All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [Xend] Move some backend configuration
@ 2008-09-30 14:24 Pascal Bouchareine
  2008-09-30 14:43 ` John Levon
  0 siblings, 1 reply; 32+ messages in thread
From: Pascal Bouchareine @ 2008-09-30 14:24 UTC (permalink / raw)
  To: xen-devel

[-- 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

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2008-10-02 17:21 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-30 14:24 [PATCH] [Xend] Move some backend configuration Pascal Bouchareine
2008-09-30 14:43 ` 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

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.