[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Have xenstored initialise its connections, meaning that xend can be out of



# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID 75ec60b67f644c6a6c629c97c4c0153e005442a0
# Parent  5e4e11d059a1d9aa42b818ad0118c163e2f66767
Have xenstored initialise its connections, meaning that xend can be out of
that loop completely -- the xc_init_store, initDomainStore calls can all go.

Have xenstored understand where the local domain information goes.  Xend no
longer has to generate a path and pass it to xenstored through
xs_introduce_domain -- we just allow xenstored to generate the path, and then
call GetDomainPath later.  There is still some work required to tidy this up.

Change the uuid module to generate uuids as lists of bytes, not in the
stringified form.  Added a unit test for that module.

Change the semantics of Xend restart, relying on these changes to the
xenstored semantics and earlier changes to add an opaque handle to the
hypervisor's domain-specific data block.  The semantics are now clearer, as
Xend can validate whether the details in the store match the current live
domain.

Added a usage statement to xenstored.

Some of this code is by Steven Hand.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r 5e4e11d059a1 -r 75ec60b67f64 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Mon Oct 17 
13:12:20 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Mon Oct 17 
15:22:05 2005
@@ -25,8 +25,6 @@
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
-#include <asm-xen/xen-public/xen.h>
-#include <asm/hypervisor.h>
 #include <asm-xen/linux-public/privcmd.h>
 #include <asm/hypervisor.h>
 #include <asm-xen/xen-public/xen.h>
@@ -219,41 +217,6 @@
        }
        break;
 
-       case IOCTL_PRIVCMD_INITDOMAIN_STORE: {
-               extern int do_xenbus_probe(void*);
-               unsigned long page;
-
-               if (xen_start_info->store_evtchn != 0) {
-                       ret = xen_start_info->store_mfn;
-                       break;
-               }
-
-               /* Allocate page. */
-               page = get_zeroed_page(GFP_KERNEL);
-               if (!page) {
-                       ret = -ENOMEM;
-                       break;
-               }
-
-               /* We don't refcnt properly, so set reserved on page.
-                * (this allocation is permanent) */
-               SetPageReserved(virt_to_page(page));
-
-               /* Initial connect. Setup channel and page. */
-               xen_start_info->store_evtchn = data;
-               xen_start_info->store_mfn =
-                       pfn_to_mfn(virt_to_phys((void *)page) >>
-                                  PAGE_SHIFT);
-               ret = xen_start_info->store_mfn;
-
-               /* 
-               ** Complete initialization of xenbus (viz. set up the 
-               ** connection to xenstored now that it has started). 
-               */
-               kthread_run(do_xenbus_probe, NULL, "xenbus_probe");
-       }
-       break;
-
        default:
                ret = -EINVAL;
                break;
diff -r 5e4e11d059a1 -r 75ec60b67f64 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Mon Oct 17 
13:12:20 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Mon Oct 17 
15:22:05 2005
@@ -36,7 +36,11 @@
 #include <asm-xen/xenbus.h>
 #include "xenbus_comms.h"
 
-static int xenbus_irq;
+static int xenbus_irq      = 0;
+
+extern void xenbus_probe(void *); 
+extern int xenstored_ready; 
+static DECLARE_WORK(probe_work, xenbus_probe, NULL);
 
 DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
 
@@ -47,6 +51,11 @@
 
 static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
 {
+       if(unlikely(xenstored_ready == 0)) {
+               xenstored_ready = 1; 
+               schedule_work(&probe_work); 
+       } 
+
        wake_up(&xb_waitq);
        return IRQ_HANDLED;
 }
@@ -169,10 +178,6 @@
 
        if (xenbus_irq)
                unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq);
-       xenbus_irq = 0;
-
-       if (!xen_start_info->store_evtchn)
-               return 0;
 
        err = bind_evtchn_to_irqhandler(
                xen_start_info->store_evtchn, wake_waiting,
diff -r 5e4e11d059a1 -r 75ec60b67f64 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Mon Oct 17 
13:12:20 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Mon Oct 17 
15:22:05 2005
@@ -27,16 +27,25 @@
  */
 #define DEBUG
 
-#include <asm/hypervisor.h>
-#include <asm-xen/xenbus.h>
-#include <asm-xen/balloon.h>
 #include <linux/kernel.h>
 #include <linux/err.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/fcntl.h>
-#include <stdarg.h>
+#include <linux/mm.h>
 #include <linux/notifier.h>
+#include <linux/kthread.h>
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/hypervisor.h>
+#include <asm-xen/xenbus.h>
+#include <asm-xen/xen_proc.h>
+#include <asm-xen/balloon.h>
+#include <asm-xen/evtchn.h>
+#include <asm-xen/linux-public/evtchn.h>
+
 #include "xenbus_comms.h"
 
 extern struct semaphore xenwatch_mutex;
@@ -634,15 +643,19 @@
        bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
 }
 
+
+/* A flag to determine if xenstored is 'ready' (i.e. has started) */
+int xenstored_ready = 0; 
+
+
 int register_xenstore_notifier(struct notifier_block *nb)
 {
        int ret = 0;
 
-       if (xen_start_info->store_evtchn) {
+        if(xenstored_ready > 0) 
                ret = nb->notifier_call(nb, 0, NULL);
-       } else {
+       else 
                notifier_chain_register(&xenstore_chain, nb);
-       }
 
        return ret;
 }
@@ -654,22 +667,11 @@
 }
 EXPORT_SYMBOL(unregister_xenstore_notifier);
 
-/* 
-** Called either from below xenbus_probe_init() initcall (for domUs) 
-** or, for dom0, from a thread created in privcmd/privcmd.c (after 
-** the user-space tools have invoked initDomainStore()) 
-*/
-int do_xenbus_probe(void *unused)
-{
-       int err = 0;
-
-       /* Initialize the interface to xenstore. */
-       err = xs_init();
-       if (err) {
-               printk("XENBUS: Error initializing xenstore comms:"
-                      " %i\n", err);
-               return err;
-       }
+
+
+void xenbus_probe(void *unused)
+{
+       BUG_ON((xenstored_ready <= 0)); 
 
        /* Enumerate devices in xenstore. */
        xenbus_probe_devices(&xenbus_frontend);
@@ -682,27 +684,101 @@
        /* Notify others that xenstore is up */
        notifier_call_chain(&xenstore_chain, 0, 0);
 
-       return 0;
-}
+       return;
+}
+
+
+static struct proc_dir_entry *xsd_mfn_intf;
+static struct proc_dir_entry *xsd_port_intf;
+
+
+static int xsd_mfn_read(char *page, char **start, off_t off,
+                        int count, int *eof, void *data)
+{
+       int len; 
+       len  = sprintf(page, "%ld", xen_start_info->store_mfn); 
+       *eof = 1; 
+       return len; 
+}
+
+static int xsd_port_read(char *page, char **start, off_t off,
+                        int count, int *eof, void *data)
+{
+       int len; 
+
+       len  = sprintf(page, "%d", xen_start_info->store_evtchn); 
+       *eof = 1; 
+       return len; 
+}
+
 
 static int __init xenbus_probe_init(void)
 {
-       if (xen_init() < 0)
+       int err = 0;
+       /* 
+       ** Domain0 doesn't have a store_evtchn or store_mfn yet. 
+       */
+       int dom0 = (xen_start_info->store_evtchn == 0);
+
+       printk("xenbus_probe_init\n");
+
+       if (xen_init() < 0) {
+               printk("xen_init failed\n");
                return -ENODEV;
-
+       }
+
+       /* Register ourselves with the kernel bus & device subsystems */
        bus_register(&xenbus_frontend.bus);
        bus_register(&xenbus_backend.bus);
        device_register(&xenbus_frontend.dev);
        device_register(&xenbus_backend.dev);
 
-       /* 
-       ** Domain0 doesn't have a store_evtchn yet - this will
-       ** be set up later by xend invoking initDomainStore() 
-       */
-       if (!xen_start_info->store_evtchn)
-               return 0;
-
-       do_xenbus_probe(NULL);
+       if (dom0) {
+
+               unsigned long page;
+               evtchn_op_t op = { 0 };
+
+
+               /* Allocate page. */
+               page = get_zeroed_page(GFP_KERNEL);
+               if (!page) 
+                       return -ENOMEM; 
+
+               /* We don't refcnt properly, so set reserved on page.
+                * (this allocation is permanent) */
+               SetPageReserved(virt_to_page(page));
+
+               xen_start_info->store_mfn =
+                       pfn_to_mfn(virt_to_phys((void *)page) >>
+                                  PAGE_SHIFT);
+               
+               /* Next allocate a local port which xenstored can bind to */
+               op.cmd = EVTCHNOP_alloc_unbound;
+               op.u.alloc_unbound.dom        = DOMID_SELF;
+               op.u.alloc_unbound.remote_dom = 0; 
+
+               BUG_ON(HYPERVISOR_event_channel_op(&op)); 
+               xen_start_info->store_evtchn = op.u.alloc_unbound.port;
+
+               /* And finally publish the above info in /proc/xen */
+               if((xsd_mfn_intf = create_xen_proc_entry("xsd_mfn", 0400)))
+                       xsd_mfn_intf->read_proc = xsd_mfn_read; 
+               if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400)))
+                       xsd_port_intf->read_proc = xsd_port_read;
+       }
+
+       /* Initialize the interface to xenstore. */
+       err = xs_init(); 
+       if (err) {
+               printk("XENBUS: Error initializing xenstore comms: %i\n", err);
+               return err; 
+       }
+
+       if (!dom0) {
+               xenstored_ready = 1;
+               xenbus_probe(NULL);
+       }
+
        return 0;
 }
 
diff -r 5e4e11d059a1 -r 75ec60b67f64 
linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h
--- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h       Mon Oct 
17 13:12:20 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h       Mon Oct 
17 15:22:05 2005
@@ -76,8 +76,6 @@
        _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
 #define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN                  \
        _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
-#define IOCTL_PRIVCMD_INITDOMAIN_STORE                         \
-       _IOC(_IOC_READ, 'P', 5, 0)
 
 #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
 
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/libxc/xc_misc.c
--- a/tools/libxc/xc_misc.c     Mon Oct 17 13:12:20 2005
+++ b/tools/libxc/xc_misc.c     Mon Oct 17 15:22:05 2005
@@ -131,11 +131,6 @@
     return rc;
 }
 
-long xc_init_store(int xc_handle, int remote_port)
-{
-    return ioctl(xc_handle, IOCTL_PRIVCMD_INITDOMAIN_STORE, remote_port);
-}
-
 /*
  * Local variables:
  * mode: C
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Mon Oct 17 13:12:20 2005
+++ b/tools/libxc/xenctrl.h     Mon Oct 17 15:22:05 2005
@@ -236,12 +236,12 @@
                           xc_domaininfo_t *info);
 
 /**
- * This function returns information about one domain.  This information is
- * more detailed than the information from xc_domain_getinfo().
+ * This function returns information about the execution context of a
+ * particular vcpu of a domain.
  *
  * @parm xc_handle a handle to an open hypervisor interface
  * @parm domid the domain to get information from
- * @parm info a pointer to an xc_domaininfo_t to store the domain information
+ * @parm vcpu the vcpu number
  * @parm ctxt a pointer to a structure to store the execution context of the
  *            domain
  * @return 0 on success, -1 on failure
@@ -488,15 +488,6 @@
 int xc_dom0_op(int xc_handle, dom0_op_t *op);
 
 int xc_version(int xc_handle, int cmd, void *arg);
-
-/* Initializes the store (for dom0)
-   remote_port should be the remote end of a bound interdomain channel between
-   the store and dom0.
-
-   This function returns a shared frame that should be passed to
-   xs_introduce_domain
- */
-long xc_init_store(int xc_handle, int remote_port);
 
 /*
  * MMU updates.
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Mon Oct 17 13:12:20 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Oct 17 15:22:05 2005
@@ -862,23 +862,6 @@
     return zero;
 }
 
-static PyObject *pyxc_init_store(PyObject *self, PyObject *args,
-                                PyObject *kwds)
-{
-    XcObject *xc = (XcObject *)self;
-
-    int remote_port;
-
-    static char *kwd_list[] = { "remote_port", NULL };
-
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, 
-                                      &remote_port) )
-        return NULL;
-
-    return PyInt_FromLong(xc_init_store(xc->xc_handle, remote_port));
-}
-
-
 static PyMethodDef pyxc_methods[] = {
     { "handle",
       (PyCFunction)pyxc_handle,
@@ -1158,13 +1141,6 @@
       " mem_kb [long]: .\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
-    { "init_store", 
-      (PyCFunction)pyxc_init_store, 
-      METH_VARARGS | METH_KEYWORDS, "\n"
-      "Initialize the store event channel and return the store page mfn.\n"
-      " remote_port [int]: store event channel port number.\n"
-      "Returns: [int] mfn on success; <0 on error.\n" },
-
     { NULL, NULL, 0, NULL }
 };
 
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Mon Oct 17 13:12:20 2005
+++ b/tools/python/xen/lowlevel/xs/xs.c Mon Oct 17 15:22:05 2005
@@ -686,7 +686,6 @@
        " dom  [int]   : domain id\n"                                   \
        " page [long]  : address of domain's xenstore page\n"           \
        " port [int]   : port the domain is using for xenstore\n"       \
-       " path [string]: path to the domain's data in xenstore\n"       \
        "\n"                                                            \
        "Returns None on success.\n"                                    \
        "Raises RuntimeError on error.\n"                               \
@@ -695,12 +694,11 @@
 static PyObject *xspy_introduce_domain(PyObject *self, PyObject *args,
                                        PyObject *kwds)
 {
-    static char *kwd_spec[] = { "dom", "page", "port", "path", NULL };
-    static char *arg_spec = "iiis|";
+    static char *kwd_spec[] = { "dom", "page", "port", NULL };
+    static char *arg_spec = "iii";
     domid_t dom = 0;
     unsigned long page = 0;
     unsigned int port = 0;
-    char *path = NULL;
 
     struct xs_handle *xh = xshandle(self);
     PyObject *val = NULL;
@@ -709,10 +707,10 @@
     if (!xh)
         goto exit;
     if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
-                                     &dom, &page, &port, &path))
-        goto exit;
-    Py_BEGIN_ALLOW_THREADS
-    xsval = xs_introduce_domain(xh, dom, page, port, path);
+                                     &dom, &page, &port))
+        goto exit;
+    Py_BEGIN_ALLOW_THREADS
+    xsval = xs_introduce_domain(xh, dom, page, port);
     Py_END_ALLOW_THREADS
     if (!xsval) {
         PyErr_SetFromErrno(PyExc_RuntimeError);
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Mon Oct 17 13:12:20 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py   Mon Oct 17 15:22:05 2005
@@ -143,15 +143,13 @@
             if m:
                 store_mfn = int(m.group(2))
                 dominfo.setStoreRef(store_mfn)
-                log.debug("IntroduceDomain %d %d %d %s",
+                log.debug("IntroduceDomain %d %d %d",
                           dominfo.getDomid(),
                           store_mfn,
-                          dominfo.store_channel,
-                          dominfo.getDomainPath())
+                          dominfo.store_channel)
                 IntroduceDomain(dominfo.getDomid(),
                                 store_mfn,
-                                dominfo.store_channel,
-                                dominfo.getDomainPath())
+                                dominfo.store_channel)
             else:
                 m = re.match(r"^(console-mfn) (\d+)$", line)
                 if m:
@@ -171,6 +169,7 @@
     if closeToChild:
         child.tochild.close()
 
+    lasterr = "error unknown"
     try:
         fds = [child.fromchild.fileno(),
                child.childerr.fileno()]
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Mon Oct 17 13:12:20 2005
+++ b/tools/python/xen/xend/XendDomain.py       Mon Oct 17 15:22:05 2005
@@ -21,8 +21,10 @@
  Nothing here is persistent (across reboots).
  Needs to be persistent for one uptime.
 """
+
+import logging
 import os
-import logging
+import sys
 import threading
 
 import xen.lowlevel.xc
@@ -62,8 +64,11 @@
 
         self.domains_lock.acquire()
         try:
+            self._add_domain(
+                XendDomainInfo.recreate(self.xen_domains()[PRIV_DOMAIN],
+                                        True))
+            self.dom0_setup()
             self.refresh(True)
-            self.dom0_setup()
         finally:
             self.domains_lock.release()
 
@@ -178,25 +183,23 @@
                             'Cannot recreate information for dying domain %d.'
                             '  Xend will ignore this domain from now on.',
                             doms[d]['dom'])
+                elif d == PRIV_DOMAIN:
+                    log.fatal(
+                        "No record of privileged domain %d!  Terminating.", d)
+                    sys.exit(1)
                 else:
                     try:
-                        dominfo = XendDomainInfo.recreate(doms[d])
-                        self._add_domain(dominfo)
+                        self._add_domain(
+                            XendDomainInfo.recreate(doms[d], False))
                     except:
-                        if d == PRIV_DOMAIN:
-                            log.exception(
-                                "Failed to recreate information for domain "
-                                "%d.  Doing nothing except crossing my "
-                                "fingers.", d)
-                        else:
-                            log.exception(
-                                "Failed to recreate information for domain "
-                                "%d.  Destroying it in the hope of "
-                                "recovery.", d)
-                            try:
-                                xc.domain_destroy(dom = d)
-                            except:
-                                log.exception('Destruction of %d failed.', d)
+                        log.exception(
+                            "Failed to recreate information for domain "
+                            "%d.  Destroying it in the hope of "
+                            "recovery.", d)
+                        try:
+                            xc.domain_destroy(dom = d)
+                        except:
+                            log.exception('Destruction of %d failed.', d)
 
 
     ## public:
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Oct 17 13:12:20 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Oct 17 15:22:05 2005
@@ -28,7 +28,6 @@
 import string
 import time
 import threading
-import errno
 
 import xen.lowlevel.xc
 from xen.util import asserts
@@ -42,7 +41,7 @@
 from xen.xend.XendError import XendError, VmError
 from xen.xend.XendRoot import get_component
 
-from uuid import getUuid
+import uuid
 
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
@@ -153,7 +152,7 @@
 
     log.debug("XendDomainInfo.create(%s)", config)
 
-    vm = XendDomainInfo(getUuid(), parseConfig(config))
+    vm = XendDomainInfo(uuid.create(), parseConfig(config))
     try:
         vm.construct()
         vm.initDomain()
@@ -169,7 +168,7 @@
         raise
 
 
-def recreate(xeninfo):
+def recreate(xeninfo, 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,
     and asking us to recreate them causes problems."""
@@ -179,39 +178,52 @@
     assert not xeninfo['dying']
 
     domid = xeninfo['dom']
+    dompath = GetDomainPath(domid)
+    if not dompath:
+        raise XendError(
+            'No domain path in store for existing domain %d' % domid)
     try:
-        dompath = GetDomainPath(domid)
-        if not dompath:
-            raise XendError(
-                'No domain path in store for existing domain %d' % domid)
         vmpath = xstransact.Read(dompath, "vm")
         if not vmpath:
             raise XendError(
                 'No vm path in store for existing domain %d' % domid)
-        uuid = xstransact.Read(vmpath, "uuid")
-        if not uuid:
+        uuid1_str = xstransact.Read(vmpath, "uuid")
+        if not uuid1_str:
             raise XendError(
                 'No vm/uuid path in store for existing domain %d' % domid)
 
-        log.info("Recreating domain %d, UUID %s.", domid, uuid)
-
-        vm = XendDomainInfo(uuid, xeninfo, domid, True)
+        uuid1 = uuid.fromString(uuid1_str)
+
+        uuid2 = xeninfo['handle']
+
+        if uuid1 != uuid2:
+            raise XendError(
+                'Uuid in store does not match uuid for existing domain %d: '
+                '%s != %s' % (domid, uuid1_str, uuid.toString(uuid2)))
+
+        log.info("Recreating domain %d, UUID %s.", domid, uuid1_str)
+
+        vm = XendDomainInfo(uuid2, xeninfo, domid, dompath, True)
 
     except Exception, exn:
         log.warn(str(exn))
 
-        uuid = getUuid()
-
-        log.info("Recreating domain %d with new UUID %s.", domid, uuid)
-
-        vm = XendDomainInfo(uuid, xeninfo, domid, True)
+        if priv:
+            new_uuid = [0 for i in range(0, 16)]
+        else:
+            new_uuid = uuid.create()
+
+        log.info("Recreating domain %d with new UUID %s.", domid,
+                 uuid.toString(new_uuid))
+
+        vm = XendDomainInfo(new_uuid, xeninfo, domid, dompath, True)
         vm.removeDom()
         vm.storeVmDetails()
         vm.storeDomDetails()
 
-    vm.create_channel()
-    if domid == 0:
-        vm.initStoreConnection()
+    if domid != 0:
+        # Setup store and console channels 
+        vm.create_channels()
 
     vm.refreshShutdown(xeninfo)
     return vm
@@ -225,12 +237,12 @@
 
     log.debug("XendDomainInfo.restore(%s)", config)
 
-    uuid = sxp.child_value(config, 'uuid')
-    vm = XendDomainInfo(uuid, parseConfig(config))
+    vm = XendDomainInfo(uuid.fromString(sxp.child_value(config, 'uuid')),
+                        parseConfig(config))
     try:
         vm.construct()
         vm.configure()
-        vm.create_channel()
+        vm.create_channels()
         vm.storeVmDetails()
         vm.storeDomDetails()
         vm.refreshShutdown()
@@ -355,9 +367,10 @@
     MINIMUM_RESTART_TIME = 20
 
 
-    def __init__(self, uuid, info, domid = None, augment = False):
-
-        self.uuid = uuid
+    def __init__(self, uuidbytes, info, domid = None, dompath = None,
+                 augment = False):
+
+        self.uuidbytes = uuidbytes
         self.info = info
 
         if domid is not None:
@@ -367,11 +380,8 @@
         else:
             self.domid = None
 
-        self.vmpath  = VMROOT + uuid
-        if self.domid is None:
-            self.dompath = None
-        else:
-            self.dompath = DOMROOT + str(self.domid)
+        self.vmpath  = VMROOT + uuid.toString(uuidbytes)
+        self.dompath = dompath
 
         if augment:
             self.augmentInfo()
@@ -440,6 +450,9 @@
             defaultInfo('cpu',          lambda: None)
             defaultInfo('cpu_weight',   lambda: 1.0)
             defaultInfo('vcpus',        lambda: 1)
+
+            self.info['vcpus'] = int(self.info['vcpus'])
+
             defaultInfo('vcpu_avail',   lambda: (1 << self.info['vcpus']) - 1)
             defaultInfo('bootloader',   lambda: None)
             defaultInfo('backend',      lambda: [])
@@ -576,7 +589,7 @@
 
     def storeVmDetails(self):
         to_store = {
-            'uuid':               self.uuid,
+            'uuid':               uuid.toString(self.uuidbytes),
 
             # XXX
             'memory/target':      str(self.info['memory_KiB'])
@@ -650,9 +663,6 @@
 
     def getDomainPath(self):
         return self.dompath
-
-    def getUuid(self):
-        return self.uuid
 
 
     def getVCpuCount(self):
@@ -921,7 +931,7 @@
     def sxpr(self):
         sxpr = ['domain',
                 ['domid',   self.domid],
-                ['uuid',    self.uuid],
+                ['uuid',    uuid.toString(self.uuidbytes)],
                 ['memory',  self.info['memory_KiB'] / 1024]]
 
         for e in ROUNDTRIPPING_CONFIG_ENTRIES:
@@ -1038,7 +1048,8 @@
                   self.domid,
                   self.info['ssidref'])
 
-        self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'])
+        self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'],
+                                      handle = self.uuidbytes)
 
         if self.domid < 0:
             raise VmError('Creating domain failed: name=%s' %
@@ -1089,10 +1100,9 @@
     def construct_image(self):
         """Construct the boot image for the domain.
         """
-        self.create_channel()
+        self.create_channels()
         self.image.createImage()
-        IntroduceDomain(self.domid, self.store_mfn,
-                        self.store_channel, self.dompath)
+        IntroduceDomain(self.domid, self.store_mfn, self.store_channel)
 
 
     ## public:
@@ -1199,7 +1209,7 @@
         self.storeDom(path, port)
         return port
 
-    def create_channel(self):
+    def create_channels(self):
         """Create the channels to the domain.
         """
         self.store_channel = self.eventChannel("store/port")
@@ -1312,13 +1322,15 @@
         """
         
         new_name = self.generateUniqueName()
-        new_uuid = getUuid()
+        new_uuid = uuid.create()
+        new_uuid_str = uuid.toString(new_uuid)
         log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
-                 self.info['name'], self.domid, self.uuid, new_name, new_uuid)
+                 self.info['name'], self.domid, uuid.toString(self.uuidbytes),
+                 new_name, new_uuid_str)
         self.release_devices()
         self.info['name'] = new_name
-        self.uuid = new_uuid
-        self.vmpath = VMROOT + new_uuid
+        self.uuidbytes = new_uuid
+        self.vmpath = VMROOT + new_uuid_str
         self.storeVmDetails()
         self.preserve()
 
@@ -1384,20 +1396,6 @@
         self.storeDom("control/sysrq", '%c' % key)
 
 
-    def initStoreConnection(self):
-        ref = xc.init_store(self.store_channel)
-        if ref and ref >= 0:
-            self.setStoreRef(ref)
-            try:
-                IntroduceDomain(self.domid, ref, self.store_channel,
-                                self.dompath)
-            except RuntimeError, ex:
-                if ex.args[0] == errno.EISCONN:
-                    pass
-                else:
-                    raise
-
-
     def infoIsSet(self, name):
         return name in self.info and self.info[name] is not None
 
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/python/xen/xend/uuid.py
--- a/tools/python/xen/xend/uuid.py     Mon Oct 17 13:12:20 2005
+++ b/tools/python/xen/xend/uuid.py     Mon Oct 17 15:22:05 2005
@@ -36,23 +36,27 @@
         cmd += " -r"
     else:
         cmd += " -t"
-    return commands.getoutput(cmd)
+    return fromString(commands.getoutput(cmd))
 
 
 def getUuidRandom():
     """Generate a random UUID."""
     
-    bytes = [ random.randint(0, 255) for i in range(0, 16) ]
-    # Encode the variant.
-    bytes[6] = (bytes[6] & 0x0f) | 0x40
-    bytes[8] = (bytes[8] & 0x3f) | 0x80
-    f = "%02x"
-    return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(bytes) )
+    return [ random.randint(0, 255) for i in range(0, 16) ]
 
 
 #uuidFactory = getUuidUuidgen
 uuidFactory = getUuidRandom
 
 
-def getUuid():
+def create():
     return uuidFactory()
+
+
+def toString(u):
+    f = "%02x"
+    return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(u) )
+
+def fromString(s):
+    s = s.replace('-', '')
+    return [ int(s[i : i + 2], 16) for i in range(0, 32, 2) ]
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/python/xen/xend/xenstore/xsutil.py
--- a/tools/python/xen/xend/xenstore/xsutil.py  Mon Oct 17 13:12:20 2005
+++ b/tools/python/xen/xend/xenstore/xsutil.py  Mon Oct 17 15:22:05 2005
@@ -19,8 +19,8 @@
         xs_lock.release()
     return xs_handle
 
-def IntroduceDomain(domid, page, port, path):
-    return xshandle().introduce_domain(domid, page, port, path)
+def IntroduceDomain(domid, page, port):
+    return xshandle().introduce_domain(domid, page, port)
 
 def GetDomainPath(domid):
     return xshandle().get_domain_path(domid)
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Mon Oct 17 13:12:20 2005
+++ b/tools/xenstore/xenstored_core.c   Mon Oct 17 15:22:05 2005
@@ -51,7 +51,7 @@
 #include "xenctrl.h"
 #include "tdb.h"
 
-int event_fd;
+extern int eventchn_fd; /* in xenstored_domain.c */
 
 static bool verbose;
 LIST_HEAD(connections);
@@ -319,9 +319,9 @@
        FD_SET(ro_sock, inset);
        if (ro_sock > max)
                max = ro_sock;
-       FD_SET(event_fd, inset);
-       if (event_fd > max)
-               max = event_fd;
+       FD_SET(eventchn_fd, inset);
+       if (eventchn_fd > max)
+               max = eventchn_fd;
        list_for_each_entry(i, &connections, list) {
                if (i->domain)
                        continue;
@@ -1416,14 +1416,36 @@
 }
 
 
+static void usage(void)
+{
+       fprintf(stderr,
+"Usage:\n"
+"\n"
+"  xenstored <options>\n"
+"\n"
+"where options may include:\n"
+"\n"
+"  --no-domain-init    to state that xenstored should not initialise dom0,\n"
+"  --pid-file <file>   giving a file for the daemon's pid to be written,\n"
+"  --help              to output this message,\n"
+"  --no-fork           to request that the daemon does not fork,\n"
+"  --output-pid        to request that the pid of the daemon is output,\n"
+"  --trace-file <file> giving the file for logging, and\n"
+"  --verbose           to request verbose execution.\n");
+}
+
+
 static struct option options[] = {
        { "no-domain-init", 0, NULL, 'D' },
        { "pid-file", 1, NULL, 'F' },
+       { "help", 0, NULL, 'H' },
        { "no-fork", 0, NULL, 'N' },
        { "output-pid", 0, NULL, 'P' },
        { "trace-file", 1, NULL, 'T' },
        { "verbose", 0, NULL, 'V' },
        { NULL, 0, NULL, 0 } };
+
+extern void dump_conn(struct connection *conn); 
 
 int main(int argc, char *argv[])
 {
@@ -1435,7 +1457,7 @@
        bool no_domain_init = false;
        const char *pidfile = NULL;
 
-       while ((opt = getopt_long(argc, argv, "DF:NPT:V", options,
+       while ((opt = getopt_long(argc, argv, "DF:HNPT:V", options,
                                  NULL)) != -1) {
                switch (opt) {
                case 'D':
@@ -1444,6 +1466,9 @@
                case 'F':
                        pidfile = optarg;
                        break;
+               case 'H':
+                       usage();
+                       return 0;
                case 'N':
                        dofork = false;
                        break;
@@ -1509,12 +1534,12 @@
            || listen(*ro_sock, 1) != 0)
                barf_perror("Could not listen on sockets");
 
-       /* If we're the first, create .perms file for root. */
+       /* Setup the database */
        setup_structure();
 
        /* Listen to hypervisor. */
        if (!no_domain_init)
-               event_fd = domain_init();
+               domain_init();
 
        /* Restore existing connections. */
        restore_existing_connections();
@@ -1555,7 +1580,7 @@
                if (FD_ISSET(*ro_sock, &inset))
                        accept_connection(*ro_sock, false);
 
-               if (FD_ISSET(event_fd, &inset))
+               if (FD_ISSET(eventchn_fd, &inset))
                        handle_event();
 
                list_for_each_entry(i, &connections, list) {
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Mon Oct 17 13:12:20 2005
+++ b/tools/xenstore/xenstored_domain.c Mon Oct 17 15:22:05 2005
@@ -40,8 +40,9 @@
 #include <xen/linux/evtchn.h>
 
 static int *xc_handle;
-static int eventchn_fd;
 static int virq_port;
+
+int eventchn_fd = -1; 
 
 struct domain
 {
@@ -79,9 +80,11 @@
 #ifndef TESTING
 static void evtchn_notify(int port)
 {
+       int rc; 
+
        struct ioctl_evtchn_notify notify;
        notify.port = port;
-       (void)ioctl(event_fd, IOCTL_EVTCHN_NOTIFY, &notify);
+       rc = ioctl(eventchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
 }
 #else
 extern void evtchn_notify(int port);
@@ -222,14 +225,14 @@
 {
        uint16_t port;
 
-       if (read(event_fd, &port, sizeof(port)) != sizeof(port))
+       if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
                barf_perror("Failed to read from event fd");
 
        if (port == virq_port)
                domain_cleanup();
 
 #ifndef TESTING
-       if (write(event_fd, &port, sizeof(port)) != sizeof(port))
+       if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port))
                barf_perror("Failed to write to event fd");
 #endif
 }
@@ -247,18 +250,18 @@
 }
 
 static struct domain *new_domain(void *context, unsigned int domid,
-                                unsigned long mfn, int port,
-                                const char *path)
+                                unsigned long mfn, int port)
 {
        struct domain *domain;
        struct ioctl_evtchn_bind_interdomain bind;
        int rc;
+
 
        domain = talloc(context, struct domain);
        domain->port = 0;
        domain->shutdown = 0;
        domain->domid = domid;
-       domain->path = talloc_strdup(domain, path);
+       domain->path = talloc_asprintf(domain, "/local/domain/%d", domid);
        domain->interface = xc_map_foreign_range(
                *xc_handle, domain->domid,
                getpagesize(), PROT_READ|PROT_WRITE, mfn);
@@ -269,13 +272,13 @@
        talloc_set_destructor(domain, destroy_domain);
 
        /* Tell kernel we're interested in this event. */
-       bind.remote_domain = domid;
-       bind.remote_port   = port;
-       rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
-       if (rc == -1)
-               return NULL;
-
-       domain->port = rc;
+        bind.remote_domain = domid;
+        bind.remote_port   = port;
+        rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+        if (rc == -1)
+            return NULL;
+        domain->port = rc;
+
        domain->conn = new_connection(writechn, readchn);
        domain->conn->domain = domain;
 
@@ -302,11 +305,10 @@
 void do_introduce(struct connection *conn, struct buffered_data *in)
 {
        struct domain *domain;
-       char *vec[4];
+       char *vec[3];
        unsigned int domid;
        unsigned long mfn;
        uint16_t port;
-       const char *path;
 
        if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
                send_error(conn, EINVAL);
@@ -321,10 +323,9 @@
        domid = atoi(vec[0]);
        mfn = atol(vec[1]);
        port = atoi(vec[2]);
-       path = vec[3];
 
        /* Sanity check args. */
-       if ((port <= 0) || !is_valid_nodename(path)) {
+       if (port <= 0) { 
                send_error(conn, EINVAL);
                return;
        }
@@ -333,7 +334,7 @@
 
        if (domain == NULL) {
                /* Hang domain off "in" until we're finished. */
-               domain = new_domain(in, domid, mfn, port, path);
+               domain = new_domain(in, domid, mfn, port);
                if (!domain) {
                        send_error(conn, errno);
                        return;
@@ -348,8 +349,7 @@
                /* Check that the given details match the ones we have
                   previously recorded. */
                if (port != domain->remote_port ||
-                   mfn != domain->mfn ||
-                   strcmp(path, domain->path) != 0) {
+                   mfn != domain->mfn) {
                        send_error(conn, EINVAL);
                        return;
                }
@@ -440,9 +440,44 @@
 {
 }
 
+static int dom0_init(void) 
+{ 
+        int rc, fd, port; 
+        unsigned long mfn; 
+        char str[20]; 
+        struct domain *dom0; 
+        
+        fd = open("/proc/xen/xsd_mfn", O_RDONLY); 
+        
+        rc = read(fd, str, sizeof(str)); 
+        str[rc] = '\0'; 
+        mfn = strtoul(str, NULL, 0); 
+        
+        close(fd); 
+        
+        fd = open("/proc/xen/xsd_port", O_RDONLY); 
+        
+        rc = read(fd, str, sizeof(str)); 
+        str[rc] = '\0'; 
+        port = strtoul(str, NULL, 0); 
+        
+        close(fd); 
+        
+        
+        dom0 = new_domain(NULL, 0, mfn, port); 
+        talloc_steal(dom0->conn, dom0); 
+
+        evtchn_notify(dom0->port); 
+
+        return 0; 
+}
+
+
+
 #define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
 #define EVTCHN_DEV_MAJOR 10
 #define EVTCHN_DEV_MINOR 201
+
 
 /* Returns the event channel handle. */
 int domain_init(void)
@@ -484,6 +519,9 @@
        if (eventchn_fd < 0)
                barf_perror("Failed to open evtchn device");
 
+        if (dom0_init() != 0) 
+                barf_perror("Failed to initialize dom0 state"); 
+     
        bind.virq = VIRQ_DOM_EXC;
        rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
        if (rc == -1)
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Mon Oct 17 13:12:20 2005
+++ b/tools/xenstore/xs.c       Mon Oct 17 15:22:05 2005
@@ -674,12 +674,12 @@
  */
 bool xs_introduce_domain(struct xs_handle *h,
                         unsigned int domid, unsigned long mfn,
-                        unsigned int eventchn, const char *path)
+                        unsigned int eventchn)
 {
        char domid_str[MAX_STRLEN(domid)];
        char mfn_str[MAX_STRLEN(mfn)];
        char eventchn_str[MAX_STRLEN(eventchn)];
-       struct iovec iov[4];
+       struct iovec iov[3];
 
        sprintf(domid_str, "%u", domid);
        sprintf(mfn_str, "%lu", mfn);
@@ -691,8 +691,6 @@
        iov[1].iov_len = strlen(mfn_str) + 1;
        iov[2].iov_base = eventchn_str;
        iov[2].iov_len = strlen(eventchn_str) + 1;
-       iov[3].iov_base = (char *)path;
-       iov[3].iov_len = strlen(path) + 1;
 
        return xs_bool(xs_talkv(h, NULL, XS_INTRODUCE, iov,
                                ARRAY_SIZE(iov), NULL));
diff -r 5e4e11d059a1 -r 75ec60b67f64 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h       Mon Oct 17 13:12:20 2005
+++ b/tools/xenstore/xs.h       Mon Oct 17 15:22:05 2005
@@ -130,9 +130,7 @@
 bool xs_introduce_domain(struct xs_handle *h,
                         unsigned int domid,
                         unsigned long mfn,
-                         unsigned int eventchn,
-                        const char *path);
-
+                         unsigned int eventchn); 
 /* Release a domain.
  * Tells the store domain to release the memory page to the domain.
  */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.