From: Pascal Bouchareine <pascal@gandi.net>
To: xen-devel@lists.xensource.com
Subject: [PATCH] [Xend] Move some backend configuration
Date: Tue, 30 Sep 2008 16:24:43 +0200 [thread overview]
Message-ID: <20080930142443.GA89025@bar.gandi.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 630 bytes --]
This patch moves some dom0 variables and backend device
configuration from frontend directories to
/local/domain/<backdomid>/backend or /vm.
Also,
- the first console is created as a xend device and moves
from console/0 to device/console/0
- /vm_path/<domid> is introduced, referencing the /vm path
- /vm_path/device/backend holds the backend device location,
rather than storing it in the frontend directory
- a few helpers are added to xs.c to deal with this
Signed-off-by: Pascal Bouchareine <pascal@gandi.net>
--
\o/ Pascal Bouchareine - Gandi
g 0170393757 15, place de la Nation - 75011 Paris
[-- Attachment #2: 00_devices_in_backend.patch --]
[-- Type: text/plain, Size: 35167 bytes --]
diff -r 6a8faf6d98b2 tools/console/client/main.c
--- a/tools/console/client/main.c Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/console/client/main.c Tue Sep 30 13:17:19 2008 +0200
@@ -221,7 +221,7 @@ int main(int argc, char **argv)
{ 0 },
};
- char *path;
+ char *path, *s;
int spty, xsfd;
struct xs_handle *xs;
char *end;
@@ -257,13 +257,18 @@ int main(int argc, char **argv)
signal(SIGTERM, sighandler);
- path = xs_get_domain_path(xs, domid);
- if (path == NULL)
- err(errno, "xs_get_domain_path()");
- path = realloc(path, strlen(path) + strlen("/console/tty") + 1);
- if (path == NULL)
+ path = xs_get_backend_dev(xs, domid, "console", 0);
+ if (path == NULL) {
+ err(errno, "Could not get backend path to tty");
+ }
+
+ s = realloc(path, strlen(path) + 5);
+ if (s == NULL) {
+ free(path);
err(ENOMEM, "realloc");
- strcat(path, "/console/tty");
+ }
+ path = s;
+ strcat(path, "/tty");
/* FIXME consoled currently does not assume domain-0 doesn't have a
console which is good when we break domain-0 up. To keep us
diff -r 6a8faf6d98b2 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/console/daemon/io.c Tue Sep 30 12:15:51 2008 +0200
@@ -87,8 +87,10 @@ struct domain {
bool is_dead;
struct buffer buffer;
struct domain *next;
- char *conspath;
- char *serialpath;
+ char *consfront;
+ char *consback;
+ char *serialfront;
+ char *serialback;
int use_consolepath;
int ring_ref;
evtchn_port_or_error_t local_port;
@@ -415,7 +417,7 @@ static int domain_create_tty(struct doma
}
if (dom->use_consolepath) {
- success = asprintf(&path, "%s/limit", dom->conspath) !=
+ success = asprintf(&path, "%s/limit", dom->consback) !=
-1;
if (!success)
goto out;
@@ -427,7 +429,7 @@ static int domain_create_tty(struct doma
free(path);
}
- success = asprintf(&path, "%s/limit", dom->serialpath) != -1;
+ success = asprintf(&path, "%s/limit", dom->serialback) != -1;
if (!success)
goto out;
data = xs_read(xs, XBT_NULL, path, &len);
@@ -437,7 +439,7 @@ static int domain_create_tty(struct doma
}
free(path);
- success = asprintf(&path, "%s/tty", dom->serialpath) != -1;
+ success = asprintf(&path, "%s/tty", dom->serialback) != -1;
if (!success)
goto out;
success = xs_write(xs, XBT_NULL, path, slave, strlen(slave));
@@ -446,7 +448,7 @@ static int domain_create_tty(struct doma
goto out;
if (dom->use_consolepath) {
- success = (asprintf(&path, "%s/tty", dom->conspath) != -1);
+ success = (asprintf(&path, "%s/tty", dom->consback) != -1);
if (!success)
goto out;
success = xs_write(xs, XBT_NULL, path, slave, strlen(slave));
@@ -504,12 +506,12 @@ static int domain_create_ring(struct dom
int err, remote_port, ring_ref, rc;
char *type, path[PATH_MAX];
- err = xs_gather(xs, dom->serialpath,
+ err = xs_gather(xs, dom->serialfront,
"ring-ref", "%u", &ring_ref,
"port", "%i", &remote_port,
NULL);
if (err) {
- err = xs_gather(xs, dom->conspath,
+ err = xs_gather(xs, dom->consfront,
"ring-ref", "%u", &ring_ref,
"port", "%i", &remote_port,
NULL);
@@ -519,7 +521,7 @@ static int domain_create_ring(struct dom
} else
dom->use_consolepath = 0;
- sprintf(path, "%s/type", dom->use_consolepath ? dom->conspath: dom->serialpath);
+ sprintf(path, "%s/type", dom->use_consolepath ? dom->consfront: dom->serialfront);
type = xs_read(xs, XBT_NULL, path, NULL);
if (type && strcmp(type, "xenconsoled") != 0) {
free(type);
@@ -594,17 +596,17 @@ static bool watch_domain(struct domain *
snprintf(domid_str, sizeof(domid_str), "dom%u", dom->domid);
if (watch) {
- success = xs_watch(xs, dom->serialpath, domid_str);
+ success = xs_watch(xs, dom->serialfront, domid_str);
if (success) {
- success = xs_watch(xs, dom->conspath, domid_str);
+ success = xs_watch(xs, dom->consfront, domid_str);
if (success)
domain_create_ring(dom);
else
- xs_unwatch(xs, dom->serialpath, domid_str);
+ xs_unwatch(xs, dom->serialfront, domid_str);
}
} else {
- success = xs_unwatch(xs, dom->serialpath, domid_str);
- success = xs_unwatch(xs, dom->conspath, domid_str);
+ success = xs_unwatch(xs, dom->serialfront, domid_str);
+ success = xs_unwatch(xs, dom->consfront, domid_str);
}
return success;
@@ -614,7 +616,6 @@ static struct domain *create_domain(int
static struct domain *create_domain(int domid)
{
struct domain *dom;
- char *s;
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) {
@@ -632,21 +633,20 @@ static struct domain *create_domain(int
dom->domid = domid;
- dom->serialpath = xs_get_domain_path(xs, dom->domid);
- s = realloc(dom->serialpath, strlen(dom->serialpath) +
- strlen("/serial/0") + 1);
- if (s == NULL)
+ if (asprintf(&dom->serialback, "backend/serial/%d/0", domid) == -1) {
+ dolog(LOG_ERR, "Out of memory %s:%s():L%d",
+ __FILE__, __FUNCTION__, __LINE__);
goto out;
- dom->serialpath = s;
- strcat(dom->serialpath, "/serial/0");
-
- dom->conspath = xs_get_domain_path(xs, dom->domid);
- s = realloc(dom->conspath, strlen(dom->conspath) +
- strlen("/console") + 1);
- if (s == NULL)
+ }
+
+ if (asprintf(&dom->consback, "backend/console/%d/0", domid) == -1) {
+ dolog(LOG_ERR, "Out of memory %s:%s():L%d",
+ __FILE__, __FUNCTION__, __LINE__);
goto out;
- dom->conspath = s;
- strcat(dom->conspath, "/console");
+ }
+
+ dom->serialfront = xs_get_frontend_dev(xs, domid, "serial", 0);
+ dom->consfront = xs_get_frontend_dev(xs, domid, "console", 0);
dom->master_fd = -1;
dom->slave_fd = -1;
@@ -678,8 +678,10 @@ static struct domain *create_domain(int
return dom;
out:
- free(dom->serialpath);
- free(dom->conspath);
+ free(dom->serialback);
+ free(dom->consback);
+ free(dom->serialfront);
+ free(dom->consfront);
free(dom);
return NULL;
}
@@ -716,11 +718,17 @@ static void cleanup_domain(struct domain
free(d->buffer.data);
d->buffer.data = NULL;
- free(d->serialpath);
- d->serialpath = NULL;
-
- free(d->conspath);
- d->conspath = NULL;
+ free(d->serialback);
+ d->serialback = NULL;
+
+ free(d->consback);
+ d->consback = NULL;
+
+ free(d->serialfront);
+ d->serialfront = NULL;
+
+ free(d->consfront);
+ d->consfront = NULL;
remove_domain(d);
}
diff -r 6a8faf6d98b2 tools/console/daemon/utils.c
--- a/tools/console/daemon/utils.c Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/console/daemon/utils.c Tue Sep 30 12:01:37 2008 +0200
@@ -109,7 +109,7 @@ bool xen_setup(void)
bool xen_setup(void)
{
- xs = xs_daemon_open();
+ xs = xs_domain_open();
if (xs == NULL) {
dolog(LOG_ERR,
"Failed to contact xenstore (%m). Is it running?");
@@ -136,7 +136,7 @@ bool xen_setup(void)
out:
if (xs)
- xs_daemon_close(xs);
+ xs_domain_close(xs);
if (xc != -1)
xc_interface_close(xc);
return false;
diff -r 6a8faf6d98b2 tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/python/xen/xend/XendBootloader.py Mon Sep 29 16:21:31 2008 +0200
@@ -72,7 +72,9 @@ def bootloader(blexec, disk, dom, quiet
fcntl.fcntl(m1, fcntl.F_SETFL, os.O_NDELAY);
os.close(s1)
slavename = ptsname.ptsname(m1)
- dom.storeDom("console/tty", slavename)
+
+ dev = dom.getDeviceController('console')
+ dev.writeBackend(0, 'tty', slavename)
# Release the domain lock here, because we definitely don't want
# a stuck bootloader to deny service to other xend clients.
diff -r 6a8faf6d98b2 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon Sep 29 16:21:31 2008 +0200
@@ -113,6 +113,25 @@ def create_from_dict(config_dict):
raise
return vm
+def _tryVmPathRecover(uuid):
+ id = 0
+ vm_path = None
+ while True:
+ path = '/vm/%s' % (uuid,)
+ if id:
+ path = '%s-%d' % (path, id,)
+ try:
+ uuid = xstransact.Read('%s/uuid' % path)
+ if uuid:
+ vm_path = path
+ else:
+ return vm_path
+ except:
+ # return the last good vm_path, or none
+ # if we never found one
+ return vm_path
+ id += 1
+
def recreate(info, priv):
"""Create the VM object for an existing domain. The domain must not
be dying, as the paths in the store should already have been removed,
@@ -157,26 +176,17 @@ def recreate(info, priv):
# entry disappears (eg. xenstore-rm /)
#
try:
- vmpath = xstransact.Read(dompath, "vm")
+ # Do not trust /local/domain/%d/vm as the domU might touch
+ # No need to recheck to vm uuid then.
+ vmpath = xstransact.Read("/vm_path", str(domid))
if not vmpath:
if not priv:
- log.warn('/local/domain/%d/vm is missing. recreate is '
+ log.warn('/vm_path/%d is missing. recreate is '
'confused, trying our best to recover' % domid)
- needs_reinitialising = True
- raise XendError('reinit')
-
- uuid2_str = xstransact.Read(vmpath, "uuid")
- if not uuid2_str:
- log.warn('%s/uuid/ is missing. recreate is confused, '
- 'trying our best to recover' % vmpath)
- needs_reinitialising = True
- raise XendError('reinit')
-
- uuid2 = uuid.fromString(uuid2_str)
- if uuid1 != uuid2:
- log.warn('UUID in /vm does not match the UUID in /dom/%d.'
- 'Trying out best to recover' % domid)
- needs_reinitialising = True
+ vmpath = _tryVmPathRecover(uuid1)
+ if not vmpath:
+ needs_reinitialising = True
+ raise XendError('reinit')
except XendError:
pass # our best shot at 'goto' in python :)
@@ -365,7 +375,7 @@ class XendDomainInfo:
if i != 0:
self.vmpath = self.vmpath + '-' + str(i)
try:
- if self._readVm("uuid"):
+ if self.readVm("uuid"):
self.vmpath = None
i = i + 1
except:
@@ -450,8 +460,8 @@ class XendDomainInfo:
try:
self._constructDomain()
self._storeVmDetails()
+ self._createChannels()
self._createDevices()
- self._createChannels()
self._storeDomDetails()
self._endRestore()
except:
@@ -809,7 +819,7 @@ class XendDomainInfo:
self.info['vcpu_avail'] = (1 << xeninfo['online_vcpus']) - 1
# read image value
- image_sxp = self._readVm('image')
+ image_sxp = self.readVm('image')
if image_sxp:
self.info.update_with_image_sxp(sxp.from_string(image_sxp))
@@ -830,27 +840,15 @@ class XendDomainInfo:
if self.domid == None or self.domid == 0:
return
- # Update VT100 port if it exists
- if transaction is None:
- self.console_port = self.readDom('console/port')
- else:
- self.console_port = self.readDomTxn(transaction, 'console/port')
- if self.console_port is not None:
- serial_consoles = self.info.console_get_all('vt100')
- if not serial_consoles:
- cfg = self.info.console_add('vt100', self.console_port)
- self._createDevice('console', cfg)
- else:
- console_uuid = serial_consoles[0].get('uuid')
- self.info.console_update(console_uuid, 'location',
- self.console_port)
-
-
# Update VNC port if it exists and write to xenstore
if transaction is None:
+ # XXX todo maybe ?
+ # vnc_port = self.readDom('device/console/0/vnc-port')
vnc_port = self.readDom('console/vnc-port')
else:
+ # vnc_port = self.readDomTxn(transaction, 'device/console/0/vnc-port')
vnc_port = self.readDomTxn(transaction, 'console/vnc-port')
+
if vnc_port is not None:
for dev_uuid, (dev_type, dev_info) in self.info['devices'].items():
if dev_type == 'vfb':
@@ -870,23 +868,23 @@ class XendDomainInfo:
# Function to update xenstore /vm/*
#
- def _readVm(self, *args):
+ def readVm(self, *args):
return xstransact.Read(self.vmpath, *args)
def _writeVm(self, *args):
return xstransact.Write(self.vmpath, *args)
def _removeVm(self, *args):
+ self._removeVmPath()
return xstransact.Remove(self.vmpath, *args)
- def _gatherVm(self, *args):
+ def gatherVm(self, *args):
return xstransact.Gather(self.vmpath, *args)
def storeVm(self, *args):
return xstransact.Store(self.vmpath, *args)
-
- def _readVmTxn(self, transaction, *args):
+ def readVmTxn(self, transaction, *args):
paths = map(lambda x: self.vmpath + "/" + x, args)
return transaction.read(*paths)
@@ -923,8 +921,8 @@ class XendDomainInfo:
return xstransact.Remove(self.dompath, *args)
def storeDom(self, *args):
+ """Stores an information that we share with the domU"""
return xstransact.Store(self.dompath, *args)
-
def readDomTxn(self, transaction, *args):
paths = map(lambda x: self.dompath + "/" + x, args)
@@ -956,12 +954,20 @@ class XendDomainInfo:
t.set_permissions({'dom' : self.domid})
t.write('vm', self.vmpath)
+ def get_console_type(self):
+ # Figure out if we need to tell xenconsoled to ignore this guest's
+ # console - device model will handle console if it is running
+ constype = "ioemu"
+ if 'device_model' not in self.info['platform']:
+ constype = "xenconsoled"
+
+ return constype
+
def _storeDomDetails(self):
to_store = {
'domid': str(self.domid),
'vm': self.vmpath,
'name': self.info['name_label'],
- 'console/limit': str(xoptions.get_console_limit() * 1024),
'memory/target': str(self.info['memory_dynamic_max'] / 1024),
}
@@ -972,17 +978,11 @@ class XendDomainInfo:
else:
to_store[n] = str(v)
- # Figure out if we need to tell xenconsoled to ignore this guest's
- # console - device model will handle console if it is running
- constype = "ioemu"
- if 'device_model' not in self.info['platform']:
- constype = "xenconsoled"
-
- f('console/port', self.console_port)
- f('console/ring-ref', self.console_mfn)
- f('console/type', constype)
f('store/port', self.store_port)
f('store/ring-ref', self.store_mfn)
+
+ f('device/console/0/port', self.console_port)
+ f('device/console/0/ring-ref', self.console_mfn)
if arch.type == "x86":
f('control/platform-feature-multiprocessor-suspend', True)
@@ -1071,7 +1071,7 @@ class XendDomainInfo:
changed = True
# Check whether image definition has been updated
- image_sxp = self._readVm('image')
+ image_sxp = self.readVm('image')
if image_sxp and image_sxp != sxp.to_string(self.info.image_sxpr()):
self.info.update_with_image_sxp(sxp.from_string(image_sxp))
changed = True
@@ -1207,7 +1207,7 @@ class XendDomainInfo:
self.info['vcpus_params']['weight'] = cpu_weight
def getRestartCount(self):
- return self._readVm('xend/restart_count')
+ return self.readVm('xend/restart_count')
def refreshShutdown(self, xeninfo = None):
""" Checks the domain for whether a shutdown is required.
@@ -1366,7 +1366,7 @@ class XendDomainInfo:
"""
from xen.xend import XendDomain
- if self._readVm(RESTART_IN_PROGRESS):
+ if self.readVm(RESTART_IN_PROGRESS):
log.error('Xend failed during restart of domain %s. '
'Refusing to restart to avoid loops.',
str(self.domid))
@@ -1377,7 +1377,7 @@ class XendDomainInfo:
self._writeVm(RESTART_IN_PROGRESS, 'True')
now = time.time()
- rst = self._readVm('xend/previous_restart_time')
+ rst = self.readVm('xend/previous_restart_time')
if rst:
rst = float(rst)
timeout = now - rst
@@ -1397,6 +1397,7 @@ class XendDomainInfo:
else:
self._unwatchVm()
self.destroyDomain()
+ self._removeVm()
# new_dom's VM will be the same as this domain's VM, except where
# the rename flag has instructed us to call preserveForRestart.
@@ -1410,7 +1411,7 @@ class XendDomainInfo:
self.info)
new_dom.waitForDevices()
new_dom.unpause()
- rst_cnt = self._readVm('xend/restart_count')
+ rst_cnt = self.readVm('xend/restart_count')
rst_cnt = int(rst_cnt) + 1
self._writeVm('xend/restart_count', str(rst_cnt))
new_dom._removeVm(RESTART_IN_PROGRESS)
@@ -1502,6 +1503,16 @@ class XendDomainInfo:
return self.getDeviceController(deviceClass).reconfigureDevice(
devid, devconfig)
+ def _createConsole(self):
+ """Setups the first console for this domain"""
+ log.debug('Creating initial console ring-ref %s' % self.console_mfn)
+ devid = self._createDevice('console', {
+ 'ring-ref': self.console_mfn,
+ 'port': self.console_port,
+ 'type': self.get_console_type()
+ }
+ )
+
def _createDevices(self):
"""Create the devices for a vm.
@@ -1764,6 +1775,7 @@ class XendDomainInfo:
self._introduceDomain()
+ self._createConsole()
self._createDevices()
self.image.cleanupBootloading()
@@ -1898,11 +1910,11 @@ class XendDomainInfo:
paths = self._prepare_phantom_paths()
- self._cleanupVm()
if self.dompath is not None:
self.destroyDomain()
self._cleanup_phantom_devs(paths)
+ self._cleanupVm()
if "transient" in self.info["other_config"] \
and bool(self.info["other_config"]["transient"]):
@@ -2096,7 +2108,7 @@ class XendDomainInfo:
"""Read the specified parameters from the store.
"""
try:
- return self._gatherVm(*params)
+ return self.gatherVm(*params)
except ValueError:
# One of the int/float entries in params has a corresponding store
# entry that is invalid. We recover, because older versions of
@@ -2183,6 +2195,15 @@ class XendDomainInfo:
log.info("Dev still active but hit max loop timeout")
break
+ def _storeVmPath(self):
+ log.info("storeVmPath(%s) => %s", self.domid, self.vmpath)
+ if self.domid is not None:
+ xstransact.Write('/vm_path', str(self.domid), self.vmpath)
+
+ def _removeVmPath(self):
+ if self.domid is not None:
+ xstransact.Remove('/vm_path/%s' % str(self.domid))
+
def _storeVmDetails(self):
to_store = {}
@@ -2200,14 +2221,14 @@ class XendDomainInfo:
if image_sxpr:
to_store['image'] = sxp.to_string(image_sxpr)
- if not self._readVm('xend/restart_count'):
+ if not self.readVm('xend/restart_count'):
to_store['xend/restart_count'] = str(0)
log.debug("Storing VM details: %s", scrub_password(to_store))
self._writeVm(to_store)
self._setVmPermissions()
-
+ self._storeVmPath()
def _setVmPermissions(self):
"""Allow the guest domain to read its UUID. We don't allow it to
@@ -2227,7 +2248,7 @@ class XendDomainInfo:
log.warn("".join(traceback.format_stack()))
return self._stateGet()
else:
- raise AttributeError()
+ raise AttributeError(name)
def __setattr__(self, name, value):
if name == "state":
@@ -2338,12 +2359,6 @@ class XendDomainInfo:
ignore_devices = ignore_store,
legacy_only = legacy_only)
- #if not ignore_store and self.dompath:
- # vnc_port = self.readDom('console/vnc-port')
- # if vnc_port is not None:
- # result.append(['device',
- # ['console', ['vnc-port', str(vnc_port)]]])
-
return result
# Xen API
@@ -2608,7 +2623,7 @@ class XendDomainInfo:
if not config.has_key('device'):
devid = config.get('id')
if devid != None:
- config['device'] = 'eth%d' % devid
+ config['device'] = 'eth%s' % devid
else:
config['device'] = ''
diff -r 6a8faf6d98b2 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/python/xen/xend/image.py Mon Sep 29 16:21:31 2008 +0200
@@ -289,7 +289,7 @@ class ImageHandler:
log.info("spawning device models: %s %s", self.device_model, args)
# keep track of pid and spawned options to kill it later
self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
- self.vm.storeDom("image/device-model-pid", self.pid)
+ self.vm.storeVm("image/device-model-pid", self.pid)
log.info("device model pid: %d", self.pid)
def saveDeviceModel(self):
@@ -320,7 +320,7 @@ class ImageHandler:
def recreate(self):
if self.device_model is None:
return
- self.pid = self.vm.gatherDom(('image/device-model-pid', int))
+ self.pid = self.vm.gatherVm(('image/device-model-pid', int))
def destroyDeviceModel(self):
if self.device_model is None:
diff -r 6a8faf6d98b2 tools/python/xen/xend/server/ConsoleController.py
--- a/tools/python/xen/xend/server/ConsoleController.py Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/python/xen/xend/server/ConsoleController.py Mon Sep 29 16:21:31 2008 +0200
@@ -2,13 +2,16 @@ from xen.xend.XendLogging import log
from xen.xend.XendLogging import log
from xen.xend.XendError import VmError
+
+from xen.xend import XendOptions
+xoptions = XendOptions.instance()
class ConsoleController(DevController):
"""A dummy controller for us to represent serial and vnc
console devices with persistent UUIDs.
"""
- valid_cfg = ['location', 'uuid', 'protocol']
+ valid_cfg = ['location', 'uuid', 'protocol', 'limit']
def __init__(self, vm):
DevController.__init__(self, vm)
@@ -16,8 +19,17 @@ class ConsoleController(DevController):
def getDeviceDetails(self, config):
back = dict([(k, config[k]) for k in self.valid_cfg if k in config])
- return (self.allocateDeviceID(), back, {})
+ devid = self.allocateDeviceID()
+ front = { }
+
+ if devid == 0 and self.vm.console_mfn:
+ front.update({
+ 'type': '%s' % self.vm.get_console_type()
+ })
+
+ back['limit'] = str(xoptions.get_console_limit() * 1024)
+ return (devid, back, front)
def getDeviceConfiguration(self, devid, transaction = None):
result = DevController.getDeviceConfiguration(self, devid, transaction)
diff -r 6a8faf6d98b2 tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/python/xen/xend/server/DevController.py Mon Sep 29 16:21:31 2008 +0200
@@ -122,8 +122,11 @@ class DevController:
log.debug(
'DevController: still waiting to write device entries.')
+ devpath = self.devicePath(devid)
+
t.remove(frontpath)
t.remove(backpath)
+ t.remove(devpath)
t.mkdir(backpath)
t.set_permissions(backpath,
@@ -137,6 +140,14 @@ class DevController:
t.write2(frontpath, front)
t.write2(backpath, back)
+
+ t.mkdir(devpath)
+ t.write2(devpath, {
+ 'backend' : backpath,
+ 'backend-id' : "%i" % backdom,
+ 'frontend' : frontpath,
+ 'frontend-id' : "%i" % self.vm.getDomid()
+ })
if t.commit():
return devid
@@ -233,11 +244,12 @@ class DevController:
if force:
frontpath = self.frontendPath(dev)
- backpath = xstransact.Read(frontpath, "backend")
+ backpath = self.readVm(devid, "backend")
if backpath:
xstransact.Remove(backpath)
xstransact.Remove(frontpath)
+ # xstransact.Remove(self.devicePath()) ?? Below is the same ?
self.vm._removeVm("device/%s/%d" % (self.deviceClass, dev))
def configurations(self, transaction = None):
@@ -281,9 +293,10 @@ class DevController:
@return: dict
"""
if transaction is None:
- backdomid = xstransact.Read(self.frontendPath(devid), "backend-id")
- else:
- backdomid = transaction.read(self.frontendPath(devid) + "/backend-id")
+ backdomid = xstransact.Read(self.devicePath(devid), "backend-id")
+ else:
+ backdomid = transaction.read(self.devicePath(devid) + "/backend-id")
+
if backdomid is None:
raise VmError("Device %s not connected" % devid)
@@ -411,18 +424,22 @@ class DevController:
t.write("nextDeviceID", str(result + 1))
return result
+ def readVm(self, devid, *args):
+ devpath = self.devicePath(devid)
+ if devpath:
+ return xstransact.Read(devpath, *args)
+ else:
+ raise VmError("Device config %s not found" % devid)
def readBackend(self, devid, *args):
- frontpath = self.frontendPath(devid)
- backpath = xstransact.Read(frontpath, "backend")
+ backpath = self.readVm(devid, "backend")
if backpath:
return xstransact.Read(backpath, *args)
else:
raise VmError("Device %s not connected" % devid)
def readBackendTxn(self, transaction, devid, *args):
- frontpath = self.frontendPath(devid)
- backpath = transaction.read(frontpath + "/backend")
+ backpath = self.readVm(devid, "backend")
if backpath:
paths = map(lambda x: backpath + "/" + x, args)
return transaction.read(*paths)
@@ -440,7 +457,7 @@ class DevController:
"""@return The IDs of each of the devices currently configured for
this instance's deviceClass.
"""
- fe = self.backendRoot()
+ fe = self.deviceRoot()
if transaction:
return map(lambda x: int(x.split('/')[-1]), transaction.list(fe))
@@ -449,8 +466,7 @@ class DevController:
def writeBackend(self, devid, *args):
- frontpath = self.frontendPath(devid)
- backpath = xstransact.Read(frontpath, "backend")
+ backpath = self.readVm(devid, "backend")
if backpath:
xstransact.Write(backpath, *args)
@@ -515,9 +531,8 @@ class DevController:
def waitForBackend(self, devid):
-
frontpath = self.frontendPath(devid)
- # lookup a phantom
+ # lookup a phantom
phantomPath = xstransact.Read(frontpath, 'phantom_vbd')
if phantomPath is not None:
log.debug("Waiting for %s's phantom %s.", devid, phantomPath)
@@ -530,7 +545,7 @@ class DevController:
if result['status'] != 'Connected':
return (result['status'], err)
- backpath = xstransact.Read(frontpath, "backend")
+ backpath = self.readVm(devid, "backend")
if backpath:
@@ -579,17 +594,20 @@ class DevController:
def frontendRoot(self):
return "%s/device/%s" % (self.vm.getDomainPath(), self.deviceClass)
- def backendRoot(self):
- """Construct backend root path assuming backend is domain 0."""
- from xen.xend.XendDomain import DOM0_ID
- from xen.xend.xenstore.xsutil import GetDomainPath
- return "%s/backend/%s/%s" % (GetDomainPath(DOM0_ID),
- self.deviceClass, self.vm.getDomid())
-
def frontendMiscPath(self):
return "%s/device-misc/%s" % (self.vm.getDomainPath(),
self.deviceClass)
+ def deviceRoot(self):
+ """Return the /vm/device. Because backendRoot assumes the
+ backend domain is 0"""
+ return "%s/device/%s" % (self.vm.vmpath, self.deviceClass)
+
+ def devicePath(self, devid):
+ """Return the /device entry of the given VM. We use it to store
+ backend/frontend locations"""
+ return "%s/device/%s/%s" % (self.vm.vmpath,
+ self.deviceClass, devid)
def hotplugStatusCallback(statusPath, ev, result):
log.debug("hotplugStatusCallback %s.", statusPath)
diff -r 6a8faf6d98b2 tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/python/xen/xend/server/netif.py Mon Sep 29 16:21:31 2008 +0200
@@ -141,10 +141,6 @@ class NetifController(DevController):
if sec_lab:
back['security_label'] = sec_lab
- config_path = "device/%s/%d/" % (self.deviceClass, devid)
- for x in back:
- self.vm._writeVm(config_path + x, back[x])
-
back['handle'] = "%i" % devid
back['script'] = os.path.join(xoptions.network_script_dir, script)
if rate:
@@ -188,40 +184,14 @@ class NetifController(DevController):
result = DevController.getDeviceConfiguration(self, devid, transaction)
- config_path = "device/%s/%d/" % (self.deviceClass, devid)
- devinfo = ()
for x in ( 'script', 'ip', 'bridge', 'mac',
'type', 'vifname', 'rate', 'uuid', 'model', 'accel',
'security_label'):
if transaction is None:
- y = self.vm._readVm(config_path + x)
+ y = self.readBackend(devid, x)
else:
- y = self.vm._readVmTxn(transaction, config_path + x)
- devinfo += (y,)
- (script, ip, bridge, mac, typ, vifname, rate, uuid,
- model, accel, security_label) = devinfo
-
- if script:
- result['script'] = script
- if ip:
- result['ip'] = ip
- if bridge:
- result['bridge'] = bridge
- if mac:
- result['mac'] = mac
- if typ:
- result['type'] = typ
- if vifname:
- result['vifname'] = vifname
- if rate:
- result['rate'] = rate
- if uuid:
- result['uuid'] = uuid
- if model:
- result['model'] = model
- if accel:
- result['accel'] = accel
- if security_label:
- result['security_label'] = security_label
+ y = self.readBackendTxn(transaction, devid, x)
+ if y:
+ result[x] = y
return result
diff -r 6a8faf6d98b2 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/xenstore/xs.c Tue Sep 30 13:19:54 2008 +0200
@@ -17,6 +17,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -232,6 +233,11 @@ void xs_daemon_close(struct xs_handle *h
free(h);
}
+void xs_domain_close(struct xs_handle *h)
+{
+ xs_daemon_close(h);
+}
+
static bool read_all(int fd, void *data, unsigned int len)
{
while (len) {
@@ -739,6 +745,60 @@ char *xs_get_domain_path(struct xs_handl
return xs_single(h, XBT_NULL, XS_GET_DOMAIN_PATH, domid_str, NULL);
}
+/* read the vm path from /vm_path/<domid> */
+char *xs_get_vm_path(struct xs_handle *h, unsigned int domid)
+{
+ char vm_path[MAX_STRLEN(domid) + 9];
+ void *ret;
+ unsigned int len;
+
+ sprintf(vm_path, "/vm_path/%u", domid);
+
+ ret = xs_single(h, XBT_NULL, XS_READ, vm_path, &len);
+ if (len)
+ return ret;
+ return NULL;
+}
+
+char *xs_get_backend_dev(struct xs_handle *h, unsigned int domid,
+ const char *devclass, unsigned int devid)
+{
+ char *vm_path;
+ char *vm_dev_path;
+ char *dev_path = NULL;
+ unsigned int len;
+
+ vm_path = xs_get_vm_path(h, domid);
+ if (vm_path == NULL)
+ return NULL;
+
+ if (asprintf(&vm_dev_path, "%s/device/%s/%d/backend", vm_path,
+ devclass, devid) == -1) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ dev_path = xs_single(h, XBT_NULL, XS_READ, vm_dev_path, &len);
+ if (!dev_path) {
+ errno = ENOENT;
+ goto out;
+ }
+
+out:
+ free(vm_path);
+ free(vm_dev_path);
+ return dev_path;
+}
+
+char *xs_get_frontend_dev(struct xs_handle *h, unsigned int domid,
+ const char *devclass, unsigned int devid)
+{
+ char *path;
+ asprintf(&path, "/local/domain/%d/device/%s/%d",
+ domid, devclass, devid);
+ return path;
+}
+
bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid)
{
char *domain = single_with_domid(h, XS_IS_DOMAIN_INTRODUCED, domid);
diff -r 6a8faf6d98b2 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h Wed Sep 17 15:46:15 2008 +0100
+++ b/tools/xenstore/xs.h Mon Sep 29 16:21:31 2008 +0200
@@ -42,6 +42,7 @@ struct xs_handle *xs_daemon_open_readonl
/* Close the connection to the xs daemon. */
void xs_daemon_close(struct xs_handle *);
+void xs_domain_close(struct xs_handle *);
/* Get contents of a directory.
* Returns a malloced array: call free() on it after use.
@@ -146,6 +147,17 @@ bool xs_release_domain(struct xs_handle
*/
char *xs_get_domain_path(struct xs_handle *h, unsigned int domid);
+/* Query the vm path for a domain. Call free() after use.
+ */
+char *xs_get_vm_path(struct xs_handle *h, unsigned int domid);
+
+/* Get a device backend path from domain, devclass, devid */
+char *xs_get_backend_dev(struct xs_handle *h, unsigned int domid, const char *devclass, unsigned int devid);
+
+/* Get a device frontend path from domain, devclass, devid */
+char *xs_get_frontend_dev(struct xs_handle *h, unsigned int domid, const char *devclass, unsigned int devid);
+
+
/* Return whether the domain specified has been introduced to xenstored.
*/
bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid);
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next reply other threads:[~2008-09-30 14:24 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-30 14:24 Pascal Bouchareine [this message]
2008-09-30 14:43 ` [PATCH] [Xend] Move some backend configuration John Levon
2008-09-30 14:48 ` Keir Fraser
2008-09-30 14:58 ` John Levon
2008-09-30 15:09 ` Keir Fraser
2008-09-30 15:14 ` Ian Jackson
2008-09-30 15:30 ` Daniel P. Berrange
2008-09-30 16:09 ` Keir Fraser
2008-09-30 16:35 ` John Levon
2008-09-30 17:21 ` Pascal Bouchareine
2008-09-30 16:35 ` Daniel P. Berrange
2008-09-30 16:39 ` John Levon
2008-09-30 16:46 ` Keir Fraser
2008-09-30 17:08 ` Daniel P. Berrange
2008-09-30 17:09 ` Pascal Bouchareine
2008-10-02 9:34 ` Ian Jackson
2008-10-02 9:49 ` Keir Fraser
2008-10-02 10:16 ` Pascal Bouchareine
2008-10-02 10:20 ` Keir Fraser
2008-10-02 10:21 ` Ian Jackson
2008-10-02 10:28 ` Keir Fraser
2008-10-02 10:31 ` Ian Jackson
2008-10-02 13:45 ` John Levon
2008-10-02 14:04 ` Keir Fraser
2008-10-02 14:09 ` Keir Fraser
2008-10-02 15:09 ` John Levon
2008-10-02 15:25 ` Keir Fraser
2008-10-02 17:21 ` John Levon
2008-10-02 14:16 ` Ian Jackson
2008-09-30 15:11 ` Pascal Bouchareine
2008-09-30 15:02 ` Keir Fraser
2008-09-30 15:06 ` John Levon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080930142443.GA89025@bar.gandi.net \
--to=pascal@gandi.net \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.