mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
New console transport and update xenconsoled.
Add a new console interface using a seperate shared page and event channel instead of passing the console input/output over control messages. Update xenconsoled to use the new console interface. Make xenconsoled garbage collect dying domains by subscribing to the domain exception virq. Signed-off-by: Robert Read <robert@xensource.com> Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
This commit is contained in:
1 parent
750871efed
commit
14329d584a
12 files changed
+473
-187
No files matched your search
@@ -268,25 +268,33 @@ static PyObject *pyxc_linux_build(PyObject *self,
|
||||
u32 dom;
|
||||
char *image, *ramdisk = NULL, *cmdline = "";
|
||||
int flags = 0, vcpus = 1;
|
||||
int control_evtchn, store_evtchn;
|
||||
int control_evtchn, store_evtchn, console_evtchn;
|
||||
unsigned long store_mfn = 0;
|
||||
unsigned long console_mfn = 0;
|
||||
|
||||
static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
|
||||
"image", "ramdisk", "cmdline", "flags",
|
||||
"console_evtchn", "image",
|
||||
/* optional */
|
||||
"ramdisk", "cmdline", "flags",
|
||||
"vcpus", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssii", kwd_list,
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssii", kwd_list,
|
||||
&dom, &control_evtchn, &store_evtchn,
|
||||
&image, &ramdisk, &cmdline, &flags,
|
||||
&console_evtchn, &image,
|
||||
/* optional */
|
||||
&ramdisk, &cmdline, &flags,
|
||||
&vcpus) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_linux_build(xc->xc_handle, dom, image,
|
||||
ramdisk, cmdline, control_evtchn, flags, vcpus,
|
||||
store_evtchn, &store_mfn) != 0 )
|
||||
store_evtchn, &store_mfn,
|
||||
console_evtchn, &console_mfn) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
|
||||
return Py_BuildValue("{s:i,s:i}",
|
||||
"store_mfn", store_mfn,
|
||||
"console_mfn", console_mfn);
|
||||
}
|
||||
|
||||
static PyObject *pyxc_vmx_build(PyObject *self,
|
||||
|
||||
@@ -47,7 +47,7 @@ from xen.xend.XendError import XendError, VmError
|
||||
from xen.xend.XendRoot import get_component
|
||||
|
||||
from xen.xend.uuid import getUuid
|
||||
from xen.xend.xenstore import DBVar
|
||||
from xen.xend.xenstore import DBVar, XenNode, DBMap
|
||||
|
||||
"""Shutdown code for poweroff."""
|
||||
DOMAIN_POWEROFF = 0
|
||||
@@ -231,6 +231,7 @@ class XendDomainInfo:
|
||||
DBVar('start_time', ty='float'),
|
||||
DBVar('state', ty='str'),
|
||||
DBVar('store_mfn', ty='long'),
|
||||
DBVar('console_mfn', ty='long'),
|
||||
DBVar('restart_mode', ty='str'),
|
||||
DBVar('restart_state', ty='str'),
|
||||
DBVar('restart_time', ty='float'),
|
||||
@@ -260,6 +261,8 @@ class XendDomainInfo:
|
||||
self.channel = None
|
||||
self.store_channel = None
|
||||
self.store_mfn = None
|
||||
self.console_channel = None
|
||||
self.console_mfn = None
|
||||
self.controllers = {}
|
||||
|
||||
self.info = None
|
||||
@@ -297,6 +300,9 @@ class XendDomainInfo:
|
||||
if self.store_channel:
|
||||
self.store_channel.saveToDB(self.db.addChild("store_channel"),
|
||||
save=save)
|
||||
if self.console_channel:
|
||||
self.console_channel.saveToDB(self.db.addChild("console_channel"),
|
||||
save=save)
|
||||
if self.image:
|
||||
self.image.exportToDB(save=save, sync=sync)
|
||||
self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync)
|
||||
@@ -329,6 +335,9 @@ class XendDomainInfo:
|
||||
def getStoreChannel(self):
|
||||
return self.store_channel
|
||||
|
||||
def getConsoleChannel(self):
|
||||
return self.console_channel
|
||||
|
||||
def update(self, info):
|
||||
"""Update with info from xc.domain_getinfo().
|
||||
"""
|
||||
@@ -518,6 +527,14 @@ class XendDomainInfo:
|
||||
sxpr.append(self.store_channel.sxpr())
|
||||
if self.store_mfn:
|
||||
sxpr.append(['store_mfn', self.store_mfn])
|
||||
if self.console_channel:
|
||||
sxpr.append(['console_channel', self.console_channel.sxpr()])
|
||||
if self.console_mfn:
|
||||
sxpr.append(['console_mfn', self.console_mfn])
|
||||
# already in (devices)
|
||||
# console = self.getConsole()
|
||||
# if console:
|
||||
# sxpr.append(console.sxpr())
|
||||
|
||||
if self.restart_count:
|
||||
sxpr.append(['restart_count', self.restart_count])
|
||||
@@ -712,6 +729,13 @@ class XendDomainInfo:
|
||||
except Exception, ex:
|
||||
log.warning("error in domain release on xenstore: %s", ex)
|
||||
pass
|
||||
if self.console_channel:
|
||||
# notify processes using this cosole?
|
||||
try:
|
||||
self.console_channel.close()
|
||||
self.console_channel = None
|
||||
except:
|
||||
pass
|
||||
if self.image:
|
||||
try:
|
||||
self.device_model_pid = 0
|
||||
@@ -808,6 +832,7 @@ class XendDomainInfo:
|
||||
"""
|
||||
self.channel = self.openChannel("channel", 0, 1)
|
||||
self.store_channel = self.eventChannel("store_channel")
|
||||
self.console_channel = self.eventChannel("console_channel")
|
||||
|
||||
def create_configured_devices(self):
|
||||
devices = sxp.children(self.config, 'device')
|
||||
@@ -1003,6 +1028,7 @@ class XendDomainInfo:
|
||||
self.configure_fields()
|
||||
self.create_devices()
|
||||
self.create_blkif()
|
||||
self.publish_console()
|
||||
|
||||
def create_blkif(self):
|
||||
"""Create the block device interface (blkif) for the vm.
|
||||
@@ -1017,6 +1043,12 @@ class XendDomainInfo:
|
||||
backend = blkif.getBackend(0)
|
||||
backend.connect(recreate=self.recreate)
|
||||
|
||||
def publish_console(self):
|
||||
db = DBMap(db=XenNode("/console/%d" % self.id))
|
||||
db.clear()
|
||||
db['domain'] = self.db.getPath()
|
||||
db.saveDB(save=True)
|
||||
|
||||
def configure_fields(self):
|
||||
"""Process the vm configuration fields using the registered handlers.
|
||||
"""
|
||||
|
||||
@@ -238,16 +238,33 @@ class LinuxImageHandler(ImageHandler):
|
||||
store_evtchn = self.vm.store_channel.port2
|
||||
else:
|
||||
store_evtchn = 0
|
||||
if self.vm.console_channel:
|
||||
console_evtchn = self.vm.console_channel.port2
|
||||
else:
|
||||
console_evtchn = 0
|
||||
|
||||
log.debug("dom = %d", self.vm.getDomain())
|
||||
log.debug("image = %s", self.kernel)
|
||||
log.debug("control_evtchn = %s", self.vm.channel.getRemotePort())
|
||||
log.debug("store_evtchn = %d", store_evtchn)
|
||||
log.debug("console_evtchn = %d", console_evtchn)
|
||||
log.debug("cmdline = %s", self.cmdline)
|
||||
log.debug("ramdisk = %s", self.ramdisk)
|
||||
log.debug("flags = %d", self.flags)
|
||||
log.debug("vcpus = %d", self.vm.vcpus)
|
||||
|
||||
ret = xc.linux_build(dom = self.vm.getDomain(),
|
||||
image = self.kernel,
|
||||
control_evtchn = self.vm.channel.getRemotePort(),
|
||||
store_evtchn = store_evtchn,
|
||||
console_evtchn = console_evtchn,
|
||||
cmdline = self.cmdline,
|
||||
ramdisk = self.ramdisk,
|
||||
flags = self.flags,
|
||||
vcpus = self.vm.vcpus)
|
||||
if isinstance(ret, dict):
|
||||
self.vm.store_mfn = ret.get('store_mfn')
|
||||
self.vm.console_mfn = ret.get('console_mfn')
|
||||
return 0
|
||||
return ret
|
||||
|
||||
|
||||