direct-io.hg

changeset 7404:75ec60b67f64

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@xensource.com>
author emellor@leeni.uk.xensource.com
date Mon Oct 17 16:22:05 2005 +0100 (2005-10-17)
parents 5e4e11d059a1
children f726c39670d9
files linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h tools/libxc/xc_misc.c tools/libxc/xenctrl.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/lowlevel/xs/xs.c tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/uuid.py tools/python/xen/xend/xenstore/xsutil.py tools/xenstore/xenstored_core.c tools/xenstore/xenstored_domain.c tools/xenstore/xs.c tools/xenstore/xs.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Mon Oct 17 14:12:20 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Mon Oct 17 16:22:05 2005 +0100
     1.3 @@ -25,8 +25,6 @@
     1.4  #include <asm/pgtable.h>
     1.5  #include <asm/uaccess.h>
     1.6  #include <asm/tlb.h>
     1.7 -#include <asm-xen/xen-public/xen.h>
     1.8 -#include <asm/hypervisor.h>
     1.9  #include <asm-xen/linux-public/privcmd.h>
    1.10  #include <asm/hypervisor.h>
    1.11  #include <asm-xen/xen-public/xen.h>
    1.12 @@ -219,41 +217,6 @@ static int privcmd_ioctl(struct inode *i
    1.13  	}
    1.14  	break;
    1.15  
    1.16 -	case IOCTL_PRIVCMD_INITDOMAIN_STORE: {
    1.17 -		extern int do_xenbus_probe(void*);
    1.18 -		unsigned long page;
    1.19 -
    1.20 -		if (xen_start_info->store_evtchn != 0) {
    1.21 -			ret = xen_start_info->store_mfn;
    1.22 -			break;
    1.23 -		}
    1.24 -
    1.25 -		/* Allocate page. */
    1.26 -		page = get_zeroed_page(GFP_KERNEL);
    1.27 -		if (!page) {
    1.28 -			ret = -ENOMEM;
    1.29 -			break;
    1.30 -		}
    1.31 -
    1.32 -		/* We don't refcnt properly, so set reserved on page.
    1.33 -		 * (this allocation is permanent) */
    1.34 -		SetPageReserved(virt_to_page(page));
    1.35 -
    1.36 -		/* Initial connect. Setup channel and page. */
    1.37 -		xen_start_info->store_evtchn = data;
    1.38 -		xen_start_info->store_mfn =
    1.39 -			pfn_to_mfn(virt_to_phys((void *)page) >>
    1.40 -				   PAGE_SHIFT);
    1.41 -		ret = xen_start_info->store_mfn;
    1.42 -
    1.43 -		/* 
    1.44 -		** Complete initialization of xenbus (viz. set up the 
    1.45 -		** connection to xenstored now that it has started). 
    1.46 -		*/
    1.47 -		kthread_run(do_xenbus_probe, NULL, "xenbus_probe");
    1.48 -	}
    1.49 -	break;
    1.50 -
    1.51  	default:
    1.52  		ret = -EINVAL;
    1.53  		break;
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Mon Oct 17 14:12:20 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Mon Oct 17 16:22:05 2005 +0100
     2.3 @@ -36,7 +36,11 @@
     2.4  #include <asm-xen/xenbus.h>
     2.5  #include "xenbus_comms.h"
     2.6  
     2.7 -static int xenbus_irq;
     2.8 +static int xenbus_irq      = 0;
     2.9 +
    2.10 +extern void xenbus_probe(void *); 
    2.11 +extern int xenstored_ready; 
    2.12 +static DECLARE_WORK(probe_work, xenbus_probe, NULL);
    2.13  
    2.14  DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
    2.15  
    2.16 @@ -47,6 +51,11 @@ static inline struct xenstore_domain_int
    2.17  
    2.18  static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
    2.19  {
    2.20 +	if(unlikely(xenstored_ready == 0)) {
    2.21 +		xenstored_ready = 1; 
    2.22 +		schedule_work(&probe_work); 
    2.23 +	} 
    2.24 +
    2.25  	wake_up(&xb_waitq);
    2.26  	return IRQ_HANDLED;
    2.27  }
    2.28 @@ -169,10 +178,6 @@ int xb_init_comms(void)
    2.29  
    2.30  	if (xenbus_irq)
    2.31  		unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq);
    2.32 -	xenbus_irq = 0;
    2.33 -
    2.34 -	if (!xen_start_info->store_evtchn)
    2.35 -		return 0;
    2.36  
    2.37  	err = bind_evtchn_to_irqhandler(
    2.38  		xen_start_info->store_evtchn, wake_waiting,
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Mon Oct 17 14:12:20 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Mon Oct 17 16:22:05 2005 +0100
     3.3 @@ -27,16 +27,25 @@
     3.4   */
     3.5  #define DEBUG
     3.6  
     3.7 -#include <asm/hypervisor.h>
     3.8 -#include <asm-xen/xenbus.h>
     3.9 -#include <asm-xen/balloon.h>
    3.10  #include <linux/kernel.h>
    3.11  #include <linux/err.h>
    3.12  #include <linux/string.h>
    3.13  #include <linux/ctype.h>
    3.14  #include <linux/fcntl.h>
    3.15 -#include <stdarg.h>
    3.16 +#include <linux/mm.h>
    3.17  #include <linux/notifier.h>
    3.18 +#include <linux/kthread.h>
    3.19 +
    3.20 +#include <asm/io.h>
    3.21 +#include <asm/page.h>
    3.22 +#include <asm/pgtable.h>
    3.23 +#include <asm/hypervisor.h>
    3.24 +#include <asm-xen/xenbus.h>
    3.25 +#include <asm-xen/xen_proc.h>
    3.26 +#include <asm-xen/balloon.h>
    3.27 +#include <asm-xen/evtchn.h>
    3.28 +#include <asm-xen/linux-public/evtchn.h>
    3.29 +
    3.30  #include "xenbus_comms.h"
    3.31  
    3.32  extern struct semaphore xenwatch_mutex;
    3.33 @@ -634,15 +643,19 @@ void xenbus_resume(void)
    3.34  	bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
    3.35  }
    3.36  
    3.37 +
    3.38 +/* A flag to determine if xenstored is 'ready' (i.e. has started) */
    3.39 +int xenstored_ready = 0; 
    3.40 +
    3.41 +
    3.42  int register_xenstore_notifier(struct notifier_block *nb)
    3.43  {
    3.44  	int ret = 0;
    3.45  
    3.46 -	if (xen_start_info->store_evtchn) {
    3.47 +        if(xenstored_ready > 0) 
    3.48  		ret = nb->notifier_call(nb, 0, NULL);
    3.49 -	} else {
    3.50 +	else 
    3.51  		notifier_chain_register(&xenstore_chain, nb);
    3.52 -	}
    3.53  
    3.54  	return ret;
    3.55  }
    3.56 @@ -654,22 +667,11 @@ void unregister_xenstore_notifier(struct
    3.57  }
    3.58  EXPORT_SYMBOL(unregister_xenstore_notifier);
    3.59  
    3.60 -/* 
    3.61 -** Called either from below xenbus_probe_init() initcall (for domUs) 
    3.62 -** or, for dom0, from a thread created in privcmd/privcmd.c (after 
    3.63 -** the user-space tools have invoked initDomainStore()) 
    3.64 -*/
    3.65 -int do_xenbus_probe(void *unused)
    3.66 +
    3.67 +
    3.68 +void xenbus_probe(void *unused)
    3.69  {
    3.70 -	int err = 0;
    3.71 -
    3.72 -	/* Initialize the interface to xenstore. */
    3.73 -	err = xs_init();
    3.74 -	if (err) {
    3.75 -		printk("XENBUS: Error initializing xenstore comms:"
    3.76 -		       " %i\n", err);
    3.77 -		return err;
    3.78 -	}
    3.79 +	BUG_ON((xenstored_ready <= 0)); 
    3.80  
    3.81  	/* Enumerate devices in xenstore. */
    3.82  	xenbus_probe_devices(&xenbus_frontend);
    3.83 @@ -682,27 +684,101 @@ int do_xenbus_probe(void *unused)
    3.84  	/* Notify others that xenstore is up */
    3.85  	notifier_call_chain(&xenstore_chain, 0, 0);
    3.86  
    3.87 -	return 0;
    3.88 +	return;
    3.89  }
    3.90  
    3.91 +
    3.92 +static struct proc_dir_entry *xsd_mfn_intf;
    3.93 +static struct proc_dir_entry *xsd_port_intf;
    3.94 +
    3.95 +
    3.96 +static int xsd_mfn_read(char *page, char **start, off_t off,
    3.97 +                        int count, int *eof, void *data)
    3.98 +{
    3.99 +	int len; 
   3.100 +	len  = sprintf(page, "%ld", xen_start_info->store_mfn); 
   3.101 +	*eof = 1; 
   3.102 +	return len; 
   3.103 +}
   3.104 +
   3.105 +static int xsd_port_read(char *page, char **start, off_t off,
   3.106 +			 int count, int *eof, void *data)
   3.107 +{
   3.108 +	int len; 
   3.109 +
   3.110 +	len  = sprintf(page, "%d", xen_start_info->store_evtchn); 
   3.111 +	*eof = 1; 
   3.112 +	return len; 
   3.113 +}
   3.114 +
   3.115 +
   3.116  static int __init xenbus_probe_init(void)
   3.117  {
   3.118 -	if (xen_init() < 0)
   3.119 +	int err = 0;
   3.120 +	/* 
   3.121 +	** Domain0 doesn't have a store_evtchn or store_mfn yet. 
   3.122 +	*/
   3.123 +	int dom0 = (xen_start_info->store_evtchn == 0);
   3.124 +
   3.125 +	printk("xenbus_probe_init\n");
   3.126 +
   3.127 +	if (xen_init() < 0) {
   3.128 +		printk("xen_init failed\n");
   3.129  		return -ENODEV;
   3.130 +	}
   3.131  
   3.132 +	/* Register ourselves with the kernel bus & device subsystems */
   3.133  	bus_register(&xenbus_frontend.bus);
   3.134  	bus_register(&xenbus_backend.bus);
   3.135  	device_register(&xenbus_frontend.dev);
   3.136  	device_register(&xenbus_backend.dev);
   3.137  
   3.138 -	/* 
   3.139 -	** Domain0 doesn't have a store_evtchn yet - this will
   3.140 -	** be set up later by xend invoking initDomainStore() 
   3.141 -	*/
   3.142 -	if (!xen_start_info->store_evtchn)
   3.143 -		return 0;
   3.144 +	if (dom0) {
   3.145 +
   3.146 +		unsigned long page;
   3.147 +		evtchn_op_t op = { 0 };
   3.148 +
   3.149 +
   3.150 +		/* Allocate page. */
   3.151 +		page = get_zeroed_page(GFP_KERNEL);
   3.152 +		if (!page) 
   3.153 +			return -ENOMEM; 
   3.154 +
   3.155 +		/* We don't refcnt properly, so set reserved on page.
   3.156 +		 * (this allocation is permanent) */
   3.157 +		SetPageReserved(virt_to_page(page));
   3.158  
   3.159 -	do_xenbus_probe(NULL);
   3.160 +		xen_start_info->store_mfn =
   3.161 +			pfn_to_mfn(virt_to_phys((void *)page) >>
   3.162 +				   PAGE_SHIFT);
   3.163 +		
   3.164 +		/* Next allocate a local port which xenstored can bind to */
   3.165 +		op.cmd = EVTCHNOP_alloc_unbound;
   3.166 +		op.u.alloc_unbound.dom        = DOMID_SELF;
   3.167 +		op.u.alloc_unbound.remote_dom = 0; 
   3.168 +
   3.169 +		BUG_ON(HYPERVISOR_event_channel_op(&op)); 
   3.170 +		xen_start_info->store_evtchn = op.u.alloc_unbound.port;
   3.171 +
   3.172 +		/* And finally publish the above info in /proc/xen */
   3.173 +		if((xsd_mfn_intf = create_xen_proc_entry("xsd_mfn", 0400)))
   3.174 +			xsd_mfn_intf->read_proc = xsd_mfn_read; 
   3.175 +		if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400)))
   3.176 +			xsd_port_intf->read_proc = xsd_port_read;
   3.177 +	}
   3.178 +
   3.179 +	/* Initialize the interface to xenstore. */
   3.180 +	err = xs_init(); 
   3.181 +	if (err) {
   3.182 +		printk("XENBUS: Error initializing xenstore comms: %i\n", err);
   3.183 +		return err; 
   3.184 +	}
   3.185 +
   3.186 +	if (!dom0) {
   3.187 +		xenstored_ready = 1;
   3.188 +		xenbus_probe(NULL);
   3.189 +	}
   3.190 +
   3.191  	return 0;
   3.192  }
   3.193  
     4.1 --- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h	Mon Oct 17 14:12:20 2005 +0100
     4.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h	Mon Oct 17 16:22:05 2005 +0100
     4.3 @@ -76,8 +76,6 @@ typedef struct privcmd_blkmsg
     4.4  	_IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
     4.5  #define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN			\
     4.6  	_IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
     4.7 -#define IOCTL_PRIVCMD_INITDOMAIN_STORE				\
     4.8 -	_IOC(_IOC_READ, 'P', 5, 0)
     4.9  
    4.10  #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
    4.11  
     5.1 --- a/tools/libxc/xc_misc.c	Mon Oct 17 14:12:20 2005 +0100
     5.2 +++ b/tools/libxc/xc_misc.c	Mon Oct 17 16:22:05 2005 +0100
     5.3 @@ -131,11 +131,6 @@ int xc_msr_write(int xc_handle, int cpu_
     5.4      return rc;
     5.5  }
     5.6  
     5.7 -long xc_init_store(int xc_handle, int remote_port)
     5.8 -{
     5.9 -    return ioctl(xc_handle, IOCTL_PRIVCMD_INITDOMAIN_STORE, remote_port);
    5.10 -}
    5.11 -
    5.12  /*
    5.13   * Local variables:
    5.14   * mode: C
     6.1 --- a/tools/libxc/xenctrl.h	Mon Oct 17 14:12:20 2005 +0100
     6.2 +++ b/tools/libxc/xenctrl.h	Mon Oct 17 16:22:05 2005 +0100
     6.3 @@ -236,12 +236,12 @@ int xc_domain_getinfolist(int xc_handle,
     6.4                            xc_domaininfo_t *info);
     6.5  
     6.6  /**
     6.7 - * This function returns information about one domain.  This information is
     6.8 - * more detailed than the information from xc_domain_getinfo().
     6.9 + * This function returns information about the execution context of a
    6.10 + * particular vcpu of a domain.
    6.11   *
    6.12   * @parm xc_handle a handle to an open hypervisor interface
    6.13   * @parm domid the domain to get information from
    6.14 - * @parm info a pointer to an xc_domaininfo_t to store the domain information
    6.15 + * @parm vcpu the vcpu number
    6.16   * @parm ctxt a pointer to a structure to store the execution context of the
    6.17   *            domain
    6.18   * @return 0 on success, -1 on failure
    6.19 @@ -489,15 +489,6 @@ int xc_dom0_op(int xc_handle, dom0_op_t 
    6.20  
    6.21  int xc_version(int xc_handle, int cmd, void *arg);
    6.22  
    6.23 -/* Initializes the store (for dom0)
    6.24 -   remote_port should be the remote end of a bound interdomain channel between
    6.25 -   the store and dom0.
    6.26 -
    6.27 -   This function returns a shared frame that should be passed to
    6.28 -   xs_introduce_domain
    6.29 - */
    6.30 -long xc_init_store(int xc_handle, int remote_port);
    6.31 -
    6.32  /*
    6.33   * MMU updates.
    6.34   */
     7.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Mon Oct 17 14:12:20 2005 +0100
     7.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Mon Oct 17 16:22:05 2005 +0100
     7.3 @@ -862,23 +862,6 @@ static PyObject *pyxc_domain_memory_incr
     7.4      return zero;
     7.5  }
     7.6  
     7.7 -static PyObject *pyxc_init_store(PyObject *self, PyObject *args,
     7.8 -				 PyObject *kwds)
     7.9 -{
    7.10 -    XcObject *xc = (XcObject *)self;
    7.11 -
    7.12 -    int remote_port;
    7.13 -
    7.14 -    static char *kwd_list[] = { "remote_port", NULL };
    7.15 -
    7.16 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, 
    7.17 -                                      &remote_port) )
    7.18 -        return NULL;
    7.19 -
    7.20 -    return PyInt_FromLong(xc_init_store(xc->xc_handle, remote_port));
    7.21 -}
    7.22 -
    7.23 -
    7.24  static PyMethodDef pyxc_methods[] = {
    7.25      { "handle",
    7.26        (PyCFunction)pyxc_handle,
    7.27 @@ -1158,13 +1141,6 @@ static PyMethodDef pyxc_methods[] = {
    7.28        " mem_kb [long]: .\n"
    7.29        "Returns: [int] 0 on success; -1 on error.\n" },
    7.30  
    7.31 -    { "init_store", 
    7.32 -      (PyCFunction)pyxc_init_store, 
    7.33 -      METH_VARARGS | METH_KEYWORDS, "\n"
    7.34 -      "Initialize the store event channel and return the store page mfn.\n"
    7.35 -      " remote_port [int]: store event channel port number.\n"
    7.36 -      "Returns: [int] mfn on success; <0 on error.\n" },
    7.37 -
    7.38      { NULL, NULL, 0, NULL }
    7.39  };
    7.40  
     8.1 --- a/tools/python/xen/lowlevel/xs/xs.c	Mon Oct 17 14:12:20 2005 +0100
     8.2 +++ b/tools/python/xen/lowlevel/xs/xs.c	Mon Oct 17 16:22:05 2005 +0100
     8.3 @@ -686,7 +686,6 @@ static PyObject *xspy_transaction_end(Py
     8.4  	" dom  [int]   : domain id\n"					\
     8.5  	" page [long]  : address of domain's xenstore page\n"		\
     8.6  	" port [int]   : port the domain is using for xenstore\n"	\
     8.7 -	" path [string]: path to the domain's data in xenstore\n"	\
     8.8  	"\n"								\
     8.9  	"Returns None on success.\n"					\
    8.10  	"Raises RuntimeError on error.\n"				\
    8.11 @@ -695,12 +694,11 @@ static PyObject *xspy_transaction_end(Py
    8.12  static PyObject *xspy_introduce_domain(PyObject *self, PyObject *args,
    8.13                                         PyObject *kwds)
    8.14  {
    8.15 -    static char *kwd_spec[] = { "dom", "page", "port", "path", NULL };
    8.16 -    static char *arg_spec = "iiis|";
    8.17 +    static char *kwd_spec[] = { "dom", "page", "port", NULL };
    8.18 +    static char *arg_spec = "iii";
    8.19      domid_t dom = 0;
    8.20      unsigned long page = 0;
    8.21      unsigned int port = 0;
    8.22 -    char *path = NULL;
    8.23  
    8.24      struct xs_handle *xh = xshandle(self);
    8.25      PyObject *val = NULL;
    8.26 @@ -709,10 +707,10 @@ static PyObject *xspy_introduce_domain(P
    8.27      if (!xh)
    8.28          goto exit;
    8.29      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
    8.30 -                                     &dom, &page, &port, &path))
    8.31 +                                     &dom, &page, &port))
    8.32          goto exit;
    8.33      Py_BEGIN_ALLOW_THREADS
    8.34 -    xsval = xs_introduce_domain(xh, dom, page, port, path);
    8.35 +    xsval = xs_introduce_domain(xh, dom, page, port);
    8.36      Py_END_ALLOW_THREADS
    8.37      if (!xsval) {
    8.38          PyErr_SetFromErrno(PyExc_RuntimeError);
     9.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Mon Oct 17 14:12:20 2005 +0100
     9.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Mon Oct 17 16:22:05 2005 +0100
     9.3 @@ -143,15 +143,13 @@ def restore(xd, fd):
     9.4              if m:
     9.5                  store_mfn = int(m.group(2))
     9.6                  dominfo.setStoreRef(store_mfn)
     9.7 -                log.debug("IntroduceDomain %d %d %d %s",
     9.8 +                log.debug("IntroduceDomain %d %d %d",
     9.9                            dominfo.getDomid(),
    9.10                            store_mfn,
    9.11 -                          dominfo.store_channel,
    9.12 -                          dominfo.getDomainPath())
    9.13 +                          dominfo.store_channel)
    9.14                  IntroduceDomain(dominfo.getDomid(),
    9.15                                  store_mfn,
    9.16 -                                dominfo.store_channel,
    9.17 -                                dominfo.getDomainPath())
    9.18 +                                dominfo.store_channel)
    9.19              else:
    9.20                  m = re.match(r"^(console-mfn) (\d+)$", line)
    9.21                  if m:
    9.22 @@ -171,6 +169,7 @@ def forkHelper(cmd, fd, inputHandler, cl
    9.23      if closeToChild:
    9.24          child.tochild.close()
    9.25  
    9.26 +    lasterr = "error unknown"
    9.27      try:
    9.28          fds = [child.fromchild.fileno(),
    9.29                 child.childerr.fileno()]
    10.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Oct 17 14:12:20 2005 +0100
    10.2 +++ b/tools/python/xen/xend/XendDomain.py	Mon Oct 17 16:22:05 2005 +0100
    10.3 @@ -21,8 +21,10 @@
    10.4   Nothing here is persistent (across reboots).
    10.5   Needs to be persistent for one uptime.
    10.6  """
    10.7 +
    10.8 +import logging
    10.9  import os
   10.10 -import logging
   10.11 +import sys
   10.12  import threading
   10.13  
   10.14  import xen.lowlevel.xc
   10.15 @@ -62,8 +64,11 @@ class XendDomain:
   10.16  
   10.17          self.domains_lock.acquire()
   10.18          try:
   10.19 +            self._add_domain(
   10.20 +                XendDomainInfo.recreate(self.xen_domains()[PRIV_DOMAIN],
   10.21 +                                        True))
   10.22 +            self.dom0_setup()
   10.23              self.refresh(True)
   10.24 -            self.dom0_setup()
   10.25          finally:
   10.26              self.domains_lock.release()
   10.27  
   10.28 @@ -178,25 +183,23 @@ class XendDomain:
   10.29                              'Cannot recreate information for dying domain %d.'
   10.30                              '  Xend will ignore this domain from now on.',
   10.31                              doms[d]['dom'])
   10.32 +                elif d == PRIV_DOMAIN:
   10.33 +                    log.fatal(
   10.34 +                        "No record of privileged domain %d!  Terminating.", d)
   10.35 +                    sys.exit(1)
   10.36                  else:
   10.37                      try:
   10.38 -                        dominfo = XendDomainInfo.recreate(doms[d])
   10.39 -                        self._add_domain(dominfo)
   10.40 +                        self._add_domain(
   10.41 +                            XendDomainInfo.recreate(doms[d], False))
   10.42                      except:
   10.43 -                        if d == PRIV_DOMAIN:
   10.44 -                            log.exception(
   10.45 -                                "Failed to recreate information for domain "
   10.46 -                                "%d.  Doing nothing except crossing my "
   10.47 -                                "fingers.", d)
   10.48 -                        else:
   10.49 -                            log.exception(
   10.50 -                                "Failed to recreate information for domain "
   10.51 -                                "%d.  Destroying it in the hope of "
   10.52 -                                "recovery.", d)
   10.53 -                            try:
   10.54 -                                xc.domain_destroy(dom = d)
   10.55 -                            except:
   10.56 -                                log.exception('Destruction of %d failed.', d)
   10.57 +                        log.exception(
   10.58 +                            "Failed to recreate information for domain "
   10.59 +                            "%d.  Destroying it in the hope of "
   10.60 +                            "recovery.", d)
   10.61 +                        try:
   10.62 +                            xc.domain_destroy(dom = d)
   10.63 +                        except:
   10.64 +                            log.exception('Destruction of %d failed.', d)
   10.65  
   10.66  
   10.67      ## public:
    11.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Oct 17 14:12:20 2005 +0100
    11.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Oct 17 16:22:05 2005 +0100
    11.3 @@ -28,7 +28,6 @@ import logging
    11.4  import string
    11.5  import time
    11.6  import threading
    11.7 -import errno
    11.8  
    11.9  import xen.lowlevel.xc
   11.10  from xen.util import asserts
   11.11 @@ -42,7 +41,7 @@ from xen.xend.XendBootloader import boot
   11.12  from xen.xend.XendError import XendError, VmError
   11.13  from xen.xend.XendRoot import get_component
   11.14  
   11.15 -from uuid import getUuid
   11.16 +import uuid
   11.17  
   11.18  from xen.xend.xenstore.xstransact import xstransact
   11.19  from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
   11.20 @@ -153,7 +152,7 @@ def create(config):
   11.21  
   11.22      log.debug("XendDomainInfo.create(%s)", config)
   11.23  
   11.24 -    vm = XendDomainInfo(getUuid(), parseConfig(config))
   11.25 +    vm = XendDomainInfo(uuid.create(), parseConfig(config))
   11.26      try:
   11.27          vm.construct()
   11.28          vm.initDomain()
   11.29 @@ -169,7 +168,7 @@ def create(config):
   11.30          raise
   11.31  
   11.32  
   11.33 -def recreate(xeninfo):
   11.34 +def recreate(xeninfo, priv):
   11.35      """Create the VM object for an existing domain.  The domain must not
   11.36      be dying, as the paths in the store should already have been removed,
   11.37      and asking us to recreate them causes problems."""
   11.38 @@ -179,39 +178,52 @@ def recreate(xeninfo):
   11.39      assert not xeninfo['dying']
   11.40  
   11.41      domid = xeninfo['dom']
   11.42 +    dompath = GetDomainPath(domid)
   11.43 +    if not dompath:
   11.44 +        raise XendError(
   11.45 +            'No domain path in store for existing domain %d' % domid)
   11.46      try:
   11.47 -        dompath = GetDomainPath(domid)
   11.48 -        if not dompath:
   11.49 -            raise XendError(
   11.50 -                'No domain path in store for existing domain %d' % domid)
   11.51          vmpath = xstransact.Read(dompath, "vm")
   11.52          if not vmpath:
   11.53              raise XendError(
   11.54                  'No vm path in store for existing domain %d' % domid)
   11.55 -        uuid = xstransact.Read(vmpath, "uuid")
   11.56 -        if not uuid:
   11.57 +        uuid1_str = xstransact.Read(vmpath, "uuid")
   11.58 +        if not uuid1_str:
   11.59              raise XendError(
   11.60                  'No vm/uuid path in store for existing domain %d' % domid)
   11.61  
   11.62 -        log.info("Recreating domain %d, UUID %s.", domid, uuid)
   11.63 +        uuid1 = uuid.fromString(uuid1_str)
   11.64 +
   11.65 +        uuid2 = xeninfo['handle']
   11.66  
   11.67 -        vm = XendDomainInfo(uuid, xeninfo, domid, True)
   11.68 +        if uuid1 != uuid2:
   11.69 +            raise XendError(
   11.70 +                'Uuid in store does not match uuid for existing domain %d: '
   11.71 +                '%s != %s' % (domid, uuid1_str, uuid.toString(uuid2)))
   11.72 +
   11.73 +        log.info("Recreating domain %d, UUID %s.", domid, uuid1_str)
   11.74 +
   11.75 +        vm = XendDomainInfo(uuid2, xeninfo, domid, dompath, True)
   11.76  
   11.77      except Exception, exn:
   11.78          log.warn(str(exn))
   11.79  
   11.80 -        uuid = getUuid()
   11.81 +        if priv:
   11.82 +            new_uuid = [0 for i in range(0, 16)]
   11.83 +        else:
   11.84 +            new_uuid = uuid.create()
   11.85  
   11.86 -        log.info("Recreating domain %d with new UUID %s.", domid, uuid)
   11.87 +        log.info("Recreating domain %d with new UUID %s.", domid,
   11.88 +                 uuid.toString(new_uuid))
   11.89  
   11.90 -        vm = XendDomainInfo(uuid, xeninfo, domid, True)
   11.91 +        vm = XendDomainInfo(new_uuid, xeninfo, domid, dompath, True)
   11.92          vm.removeDom()
   11.93          vm.storeVmDetails()
   11.94          vm.storeDomDetails()
   11.95  
   11.96 -    vm.create_channel()
   11.97 -    if domid == 0:
   11.98 -        vm.initStoreConnection()
   11.99 +    if domid != 0:
  11.100 +        # Setup store and console channels 
  11.101 +        vm.create_channels()
  11.102  
  11.103      vm.refreshShutdown(xeninfo)
  11.104      return vm
  11.105 @@ -225,12 +237,12 @@ def restore(config):
  11.106  
  11.107      log.debug("XendDomainInfo.restore(%s)", config)
  11.108  
  11.109 -    uuid = sxp.child_value(config, 'uuid')
  11.110 -    vm = XendDomainInfo(uuid, parseConfig(config))
  11.111 +    vm = XendDomainInfo(uuid.fromString(sxp.child_value(config, 'uuid')),
  11.112 +                        parseConfig(config))
  11.113      try:
  11.114          vm.construct()
  11.115          vm.configure()
  11.116 -        vm.create_channel()
  11.117 +        vm.create_channels()
  11.118          vm.storeVmDetails()
  11.119          vm.storeDomDetails()
  11.120          vm.refreshShutdown()
  11.121 @@ -355,9 +367,10 @@ class XendDomainInfo:
  11.122      MINIMUM_RESTART_TIME = 20
  11.123  
  11.124  
  11.125 -    def __init__(self, uuid, info, domid = None, augment = False):
  11.126 +    def __init__(self, uuidbytes, info, domid = None, dompath = None,
  11.127 +                 augment = False):
  11.128  
  11.129 -        self.uuid = uuid
  11.130 +        self.uuidbytes = uuidbytes
  11.131          self.info = info
  11.132  
  11.133          if domid is not None:
  11.134 @@ -367,11 +380,8 @@ class XendDomainInfo:
  11.135          else:
  11.136              self.domid = None
  11.137  
  11.138 -        self.vmpath  = VMROOT + uuid
  11.139 -        if self.domid is None:
  11.140 -            self.dompath = None
  11.141 -        else:
  11.142 -            self.dompath = DOMROOT + str(self.domid)
  11.143 +        self.vmpath  = VMROOT + uuid.toString(uuidbytes)
  11.144 +        self.dompath = dompath
  11.145  
  11.146          if augment:
  11.147              self.augmentInfo()
  11.148 @@ -440,6 +450,9 @@ class XendDomainInfo:
  11.149              defaultInfo('cpu',          lambda: None)
  11.150              defaultInfo('cpu_weight',   lambda: 1.0)
  11.151              defaultInfo('vcpus',        lambda: 1)
  11.152 +
  11.153 +            self.info['vcpus'] = int(self.info['vcpus'])
  11.154 +
  11.155              defaultInfo('vcpu_avail',   lambda: (1 << self.info['vcpus']) - 1)
  11.156              defaultInfo('bootloader',   lambda: None)
  11.157              defaultInfo('backend',      lambda: [])
  11.158 @@ -576,7 +589,7 @@ class XendDomainInfo:
  11.159  
  11.160      def storeVmDetails(self):
  11.161          to_store = {
  11.162 -            'uuid':               self.uuid,
  11.163 +            'uuid':               uuid.toString(self.uuidbytes),
  11.164  
  11.165              # XXX
  11.166              'memory/target':      str(self.info['memory_KiB'])
  11.167 @@ -651,9 +664,6 @@ class XendDomainInfo:
  11.168      def getDomainPath(self):
  11.169          return self.dompath
  11.170  
  11.171 -    def getUuid(self):
  11.172 -        return self.uuid
  11.173 -
  11.174  
  11.175      def getVCpuCount(self):
  11.176          return self.info['vcpus']
  11.177 @@ -921,7 +931,7 @@ class XendDomainInfo:
  11.178      def sxpr(self):
  11.179          sxpr = ['domain',
  11.180                  ['domid',   self.domid],
  11.181 -                ['uuid',    self.uuid],
  11.182 +                ['uuid',    uuid.toString(self.uuidbytes)],
  11.183                  ['memory',  self.info['memory_KiB'] / 1024]]
  11.184  
  11.185          for e in ROUNDTRIPPING_CONFIG_ENTRIES:
  11.186 @@ -1038,7 +1048,8 @@ class XendDomainInfo:
  11.187                    self.domid,
  11.188                    self.info['ssidref'])
  11.189  
  11.190 -        self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'])
  11.191 +        self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'],
  11.192 +                                      handle = self.uuidbytes)
  11.193  
  11.194          if self.domid < 0:
  11.195              raise VmError('Creating domain failed: name=%s' %
  11.196 @@ -1089,10 +1100,9 @@ class XendDomainInfo:
  11.197      def construct_image(self):
  11.198          """Construct the boot image for the domain.
  11.199          """
  11.200 -        self.create_channel()
  11.201 +        self.create_channels()
  11.202          self.image.createImage()
  11.203 -        IntroduceDomain(self.domid, self.store_mfn,
  11.204 -                        self.store_channel, self.dompath)
  11.205 +        IntroduceDomain(self.domid, self.store_mfn, self.store_channel)
  11.206  
  11.207  
  11.208      ## public:
  11.209 @@ -1199,7 +1209,7 @@ class XendDomainInfo:
  11.210          self.storeDom(path, port)
  11.211          return port
  11.212  
  11.213 -    def create_channel(self):
  11.214 +    def create_channels(self):
  11.215          """Create the channels to the domain.
  11.216          """
  11.217          self.store_channel = self.eventChannel("store/port")
  11.218 @@ -1312,13 +1322,15 @@ class XendDomainInfo:
  11.219          """
  11.220          
  11.221          new_name = self.generateUniqueName()
  11.222 -        new_uuid = getUuid()
  11.223 +        new_uuid = uuid.create()
  11.224 +        new_uuid_str = uuid.toString(new_uuid)
  11.225          log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
  11.226 -                 self.info['name'], self.domid, self.uuid, new_name, new_uuid)
  11.227 +                 self.info['name'], self.domid, uuid.toString(self.uuidbytes),
  11.228 +                 new_name, new_uuid_str)
  11.229          self.release_devices()
  11.230          self.info['name'] = new_name
  11.231 -        self.uuid = new_uuid
  11.232 -        self.vmpath = VMROOT + new_uuid
  11.233 +        self.uuidbytes = new_uuid
  11.234 +        self.vmpath = VMROOT + new_uuid_str
  11.235          self.storeVmDetails()
  11.236          self.preserve()
  11.237  
  11.238 @@ -1384,20 +1396,6 @@ class XendDomainInfo:
  11.239          self.storeDom("control/sysrq", '%c' % key)
  11.240  
  11.241  
  11.242 -    def initStoreConnection(self):
  11.243 -        ref = xc.init_store(self.store_channel)
  11.244 -        if ref and ref >= 0:
  11.245 -            self.setStoreRef(ref)
  11.246 -            try:
  11.247 -                IntroduceDomain(self.domid, ref, self.store_channel,
  11.248 -                                self.dompath)
  11.249 -            except RuntimeError, ex:
  11.250 -                if ex.args[0] == errno.EISCONN:
  11.251 -                    pass
  11.252 -                else:
  11.253 -                    raise
  11.254 -
  11.255 -
  11.256      def infoIsSet(self, name):
  11.257          return name in self.info and self.info[name] is not None
  11.258  
    12.1 --- a/tools/python/xen/xend/uuid.py	Mon Oct 17 14:12:20 2005 +0100
    12.2 +++ b/tools/python/xen/xend/uuid.py	Mon Oct 17 16:22:05 2005 +0100
    12.3 @@ -36,23 +36,27 @@ def getUuidUuidgen(random = True):
    12.4          cmd += " -r"
    12.5      else:
    12.6          cmd += " -t"
    12.7 -    return commands.getoutput(cmd)
    12.8 +    return fromString(commands.getoutput(cmd))
    12.9  
   12.10  
   12.11  def getUuidRandom():
   12.12      """Generate a random UUID."""
   12.13      
   12.14 -    bytes = [ random.randint(0, 255) for i in range(0, 16) ]
   12.15 -    # Encode the variant.
   12.16 -    bytes[6] = (bytes[6] & 0x0f) | 0x40
   12.17 -    bytes[8] = (bytes[8] & 0x3f) | 0x80
   12.18 -    f = "%02x"
   12.19 -    return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(bytes) )
   12.20 +    return [ random.randint(0, 255) for i in range(0, 16) ]
   12.21  
   12.22  
   12.23  #uuidFactory = getUuidUuidgen
   12.24  uuidFactory = getUuidRandom
   12.25  
   12.26  
   12.27 -def getUuid():
   12.28 +def create():
   12.29      return uuidFactory()
   12.30 +
   12.31 +
   12.32 +def toString(u):
   12.33 +    f = "%02x"
   12.34 +    return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(u) )
   12.35 +
   12.36 +def fromString(s):
   12.37 +    s = s.replace('-', '')
   12.38 +    return [ int(s[i : i + 2], 16) for i in range(0, 32, 2) ]
    13.1 --- a/tools/python/xen/xend/xenstore/xsutil.py	Mon Oct 17 14:12:20 2005 +0100
    13.2 +++ b/tools/python/xen/xend/xenstore/xsutil.py	Mon Oct 17 16:22:05 2005 +0100
    13.3 @@ -19,8 +19,8 @@ def xshandle():
    13.4          xs_lock.release()
    13.5      return xs_handle
    13.6  
    13.7 -def IntroduceDomain(domid, page, port, path):
    13.8 -    return xshandle().introduce_domain(domid, page, port, path)
    13.9 +def IntroduceDomain(domid, page, port):
   13.10 +    return xshandle().introduce_domain(domid, page, port)
   13.11  
   13.12  def GetDomainPath(domid):
   13.13      return xshandle().get_domain_path(domid)
    14.1 --- a/tools/xenstore/xenstored_core.c	Mon Oct 17 14:12:20 2005 +0100
    14.2 +++ b/tools/xenstore/xenstored_core.c	Mon Oct 17 16:22:05 2005 +0100
    14.3 @@ -51,7 +51,7 @@
    14.4  #include "xenctrl.h"
    14.5  #include "tdb.h"
    14.6  
    14.7 -int event_fd;
    14.8 +extern int eventchn_fd; /* in xenstored_domain.c */
    14.9  
   14.10  static bool verbose;
   14.11  LIST_HEAD(connections);
   14.12 @@ -319,9 +319,9 @@ static int initialize_set(fd_set *inset,
   14.13  	FD_SET(ro_sock, inset);
   14.14  	if (ro_sock > max)
   14.15  		max = ro_sock;
   14.16 -	FD_SET(event_fd, inset);
   14.17 -	if (event_fd > max)
   14.18 -		max = event_fd;
   14.19 +	FD_SET(eventchn_fd, inset);
   14.20 +	if (eventchn_fd > max)
   14.21 +		max = eventchn_fd;
   14.22  	list_for_each_entry(i, &connections, list) {
   14.23  		if (i->domain)
   14.24  			continue;
   14.25 @@ -1416,15 +1416,37 @@ static void daemonize(void)
   14.26  }
   14.27  
   14.28  
   14.29 +static void usage(void)
   14.30 +{
   14.31 +	fprintf(stderr,
   14.32 +"Usage:\n"
   14.33 +"\n"
   14.34 +"  xenstored <options>\n"
   14.35 +"\n"
   14.36 +"where options may include:\n"
   14.37 +"\n"
   14.38 +"  --no-domain-init    to state that xenstored should not initialise dom0,\n"
   14.39 +"  --pid-file <file>   giving a file for the daemon's pid to be written,\n"
   14.40 +"  --help              to output this message,\n"
   14.41 +"  --no-fork           to request that the daemon does not fork,\n"
   14.42 +"  --output-pid        to request that the pid of the daemon is output,\n"
   14.43 +"  --trace-file <file> giving the file for logging, and\n"
   14.44 +"  --verbose           to request verbose execution.\n");
   14.45 +}
   14.46 +
   14.47 +
   14.48  static struct option options[] = {
   14.49  	{ "no-domain-init", 0, NULL, 'D' },
   14.50  	{ "pid-file", 1, NULL, 'F' },
   14.51 +	{ "help", 0, NULL, 'H' },
   14.52  	{ "no-fork", 0, NULL, 'N' },
   14.53  	{ "output-pid", 0, NULL, 'P' },
   14.54  	{ "trace-file", 1, NULL, 'T' },
   14.55  	{ "verbose", 0, NULL, 'V' },
   14.56  	{ NULL, 0, NULL, 0 } };
   14.57  
   14.58 +extern void dump_conn(struct connection *conn); 
   14.59 +
   14.60  int main(int argc, char *argv[])
   14.61  {
   14.62  	int opt, *sock, *ro_sock, max;
   14.63 @@ -1435,7 +1457,7 @@ int main(int argc, char *argv[])
   14.64  	bool no_domain_init = false;
   14.65  	const char *pidfile = NULL;
   14.66  
   14.67 -	while ((opt = getopt_long(argc, argv, "DF:NPT:V", options,
   14.68 +	while ((opt = getopt_long(argc, argv, "DF:HNPT:V", options,
   14.69  				  NULL)) != -1) {
   14.70  		switch (opt) {
   14.71  		case 'D':
   14.72 @@ -1444,6 +1466,9 @@ int main(int argc, char *argv[])
   14.73  		case 'F':
   14.74  			pidfile = optarg;
   14.75  			break;
   14.76 +		case 'H':
   14.77 +			usage();
   14.78 +			return 0;
   14.79  		case 'N':
   14.80  			dofork = false;
   14.81  			break;
   14.82 @@ -1509,12 +1534,12 @@ int main(int argc, char *argv[])
   14.83  	    || listen(*ro_sock, 1) != 0)
   14.84  		barf_perror("Could not listen on sockets");
   14.85  
   14.86 -	/* If we're the first, create .perms file for root. */
   14.87 +	/* Setup the database */
   14.88  	setup_structure();
   14.89  
   14.90  	/* Listen to hypervisor. */
   14.91  	if (!no_domain_init)
   14.92 -		event_fd = domain_init();
   14.93 +		domain_init();
   14.94  
   14.95  	/* Restore existing connections. */
   14.96  	restore_existing_connections();
   14.97 @@ -1555,7 +1580,7 @@ int main(int argc, char *argv[])
   14.98  		if (FD_ISSET(*ro_sock, &inset))
   14.99  			accept_connection(*ro_sock, false);
  14.100  
  14.101 -		if (FD_ISSET(event_fd, &inset))
  14.102 +		if (FD_ISSET(eventchn_fd, &inset))
  14.103  			handle_event();
  14.104  
  14.105  		list_for_each_entry(i, &connections, list) {
    15.1 --- a/tools/xenstore/xenstored_domain.c	Mon Oct 17 14:12:20 2005 +0100
    15.2 +++ b/tools/xenstore/xenstored_domain.c	Mon Oct 17 16:22:05 2005 +0100
    15.3 @@ -40,9 +40,10 @@
    15.4  #include <xen/linux/evtchn.h>
    15.5  
    15.6  static int *xc_handle;
    15.7 -static int eventchn_fd;
    15.8  static int virq_port;
    15.9  
   15.10 +int eventchn_fd = -1; 
   15.11 +
   15.12  struct domain
   15.13  {
   15.14  	struct list_head list;
   15.15 @@ -79,9 +80,11 @@ static LIST_HEAD(domains);
   15.16  #ifndef TESTING
   15.17  static void evtchn_notify(int port)
   15.18  {
   15.19 +	int rc; 
   15.20 +
   15.21  	struct ioctl_evtchn_notify notify;
   15.22  	notify.port = port;
   15.23 -	(void)ioctl(event_fd, IOCTL_EVTCHN_NOTIFY, &notify);
   15.24 +	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
   15.25  }
   15.26  #else
   15.27  extern void evtchn_notify(int port);
   15.28 @@ -222,14 +225,14 @@ void handle_event(void)
   15.29  {
   15.30  	uint16_t port;
   15.31  
   15.32 -	if (read(event_fd, &port, sizeof(port)) != sizeof(port))
   15.33 +	if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
   15.34  		barf_perror("Failed to read from event fd");
   15.35  
   15.36  	if (port == virq_port)
   15.37  		domain_cleanup();
   15.38  
   15.39  #ifndef TESTING
   15.40 -	if (write(event_fd, &port, sizeof(port)) != sizeof(port))
   15.41 +	if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port))
   15.42  		barf_perror("Failed to write to event fd");
   15.43  #endif
   15.44  }
   15.45 @@ -247,18 +250,18 @@ bool domain_can_write(struct connection 
   15.46  }
   15.47  
   15.48  static struct domain *new_domain(void *context, unsigned int domid,
   15.49 -				 unsigned long mfn, int port,
   15.50 -				 const char *path)
   15.51 +				 unsigned long mfn, int port)
   15.52  {
   15.53  	struct domain *domain;
   15.54  	struct ioctl_evtchn_bind_interdomain bind;
   15.55  	int rc;
   15.56  
   15.57 +
   15.58  	domain = talloc(context, struct domain);
   15.59  	domain->port = 0;
   15.60  	domain->shutdown = 0;
   15.61  	domain->domid = domid;
   15.62 -	domain->path = talloc_strdup(domain, path);
   15.63 +	domain->path = talloc_asprintf(domain, "/local/domain/%d", domid);
   15.64  	domain->interface = xc_map_foreign_range(
   15.65  		*xc_handle, domain->domid,
   15.66  		getpagesize(), PROT_READ|PROT_WRITE, mfn);
   15.67 @@ -269,13 +272,13 @@ static struct domain *new_domain(void *c
   15.68  	talloc_set_destructor(domain, destroy_domain);
   15.69  
   15.70  	/* Tell kernel we're interested in this event. */
   15.71 -	bind.remote_domain = domid;
   15.72 -	bind.remote_port   = port;
   15.73 -	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
   15.74 -	if (rc == -1)
   15.75 -		return NULL;
   15.76 +        bind.remote_domain = domid;
   15.77 +        bind.remote_port   = port;
   15.78 +        rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
   15.79 +        if (rc == -1)
   15.80 +            return NULL;
   15.81 +        domain->port = rc;
   15.82  
   15.83 -	domain->port = rc;
   15.84  	domain->conn = new_connection(writechn, readchn);
   15.85  	domain->conn->domain = domain;
   15.86  
   15.87 @@ -302,11 +305,10 @@ static struct domain *find_domain_by_dom
   15.88  void do_introduce(struct connection *conn, struct buffered_data *in)
   15.89  {
   15.90  	struct domain *domain;
   15.91 -	char *vec[4];
   15.92 +	char *vec[3];
   15.93  	unsigned int domid;
   15.94  	unsigned long mfn;
   15.95  	uint16_t port;
   15.96 -	const char *path;
   15.97  
   15.98  	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
   15.99  		send_error(conn, EINVAL);
  15.100 @@ -321,10 +323,9 @@ void do_introduce(struct connection *con
  15.101  	domid = atoi(vec[0]);
  15.102  	mfn = atol(vec[1]);
  15.103  	port = atoi(vec[2]);
  15.104 -	path = vec[3];
  15.105  
  15.106  	/* Sanity check args. */
  15.107 -	if ((port <= 0) || !is_valid_nodename(path)) {
  15.108 +	if (port <= 0) { 
  15.109  		send_error(conn, EINVAL);
  15.110  		return;
  15.111  	}
  15.112 @@ -333,7 +334,7 @@ void do_introduce(struct connection *con
  15.113  
  15.114  	if (domain == NULL) {
  15.115  		/* Hang domain off "in" until we're finished. */
  15.116 -		domain = new_domain(in, domid, mfn, port, path);
  15.117 +		domain = new_domain(in, domid, mfn, port);
  15.118  		if (!domain) {
  15.119  			send_error(conn, errno);
  15.120  			return;
  15.121 @@ -348,8 +349,7 @@ void do_introduce(struct connection *con
  15.122  		/* Check that the given details match the ones we have
  15.123  		   previously recorded. */
  15.124  		if (port != domain->remote_port ||
  15.125 -		    mfn != domain->mfn ||
  15.126 -		    strcmp(path, domain->path) != 0) {
  15.127 +		    mfn != domain->mfn) {
  15.128  			send_error(conn, EINVAL);
  15.129  			return;
  15.130  		}
  15.131 @@ -440,10 +440,45 @@ void restore_existing_connections(void)
  15.132  {
  15.133  }
  15.134  
  15.135 +static int dom0_init(void) 
  15.136 +{ 
  15.137 +        int rc, fd, port; 
  15.138 +        unsigned long mfn; 
  15.139 +        char str[20]; 
  15.140 +        struct domain *dom0; 
  15.141 +        
  15.142 +        fd = open("/proc/xen/xsd_mfn", O_RDONLY); 
  15.143 +        
  15.144 +        rc = read(fd, str, sizeof(str)); 
  15.145 +        str[rc] = '\0'; 
  15.146 +        mfn = strtoul(str, NULL, 0); 
  15.147 +        
  15.148 +        close(fd); 
  15.149 +        
  15.150 +        fd = open("/proc/xen/xsd_port", O_RDONLY); 
  15.151 +        
  15.152 +        rc = read(fd, str, sizeof(str)); 
  15.153 +        str[rc] = '\0'; 
  15.154 +        port = strtoul(str, NULL, 0); 
  15.155 +        
  15.156 +        close(fd); 
  15.157 +        
  15.158 +        
  15.159 +        dom0 = new_domain(NULL, 0, mfn, port); 
  15.160 +        talloc_steal(dom0->conn, dom0); 
  15.161 +
  15.162 +        evtchn_notify(dom0->port); 
  15.163 +
  15.164 +        return 0; 
  15.165 +}
  15.166 +
  15.167 +
  15.168 +
  15.169  #define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
  15.170  #define EVTCHN_DEV_MAJOR 10
  15.171  #define EVTCHN_DEV_MINOR 201
  15.172  
  15.173 +
  15.174  /* Returns the event channel handle. */
  15.175  int domain_init(void)
  15.176  {
  15.177 @@ -484,6 +519,9 @@ int domain_init(void)
  15.178  	if (eventchn_fd < 0)
  15.179  		barf_perror("Failed to open evtchn device");
  15.180  
  15.181 +        if (dom0_init() != 0) 
  15.182 +                barf_perror("Failed to initialize dom0 state"); 
  15.183 +     
  15.184  	bind.virq = VIRQ_DOM_EXC;
  15.185  	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
  15.186  	if (rc == -1)
    16.1 --- a/tools/xenstore/xs.c	Mon Oct 17 14:12:20 2005 +0100
    16.2 +++ b/tools/xenstore/xs.c	Mon Oct 17 16:22:05 2005 +0100
    16.3 @@ -674,12 +674,12 @@ bool xs_transaction_end(struct xs_handle
    16.4   */
    16.5  bool xs_introduce_domain(struct xs_handle *h,
    16.6  			 unsigned int domid, unsigned long mfn,
    16.7 -			 unsigned int eventchn, const char *path)
    16.8 +			 unsigned int eventchn)
    16.9  {
   16.10  	char domid_str[MAX_STRLEN(domid)];
   16.11  	char mfn_str[MAX_STRLEN(mfn)];
   16.12  	char eventchn_str[MAX_STRLEN(eventchn)];
   16.13 -	struct iovec iov[4];
   16.14 +	struct iovec iov[3];
   16.15  
   16.16  	sprintf(domid_str, "%u", domid);
   16.17  	sprintf(mfn_str, "%lu", mfn);
   16.18 @@ -691,8 +691,6 @@ bool xs_introduce_domain(struct xs_handl
   16.19  	iov[1].iov_len = strlen(mfn_str) + 1;
   16.20  	iov[2].iov_base = eventchn_str;
   16.21  	iov[2].iov_len = strlen(eventchn_str) + 1;
   16.22 -	iov[3].iov_base = (char *)path;
   16.23 -	iov[3].iov_len = strlen(path) + 1;
   16.24  
   16.25  	return xs_bool(xs_talkv(h, NULL, XS_INTRODUCE, iov,
   16.26  				ARRAY_SIZE(iov), NULL));
    17.1 --- a/tools/xenstore/xs.h	Mon Oct 17 14:12:20 2005 +0100
    17.2 +++ b/tools/xenstore/xs.h	Mon Oct 17 16:22:05 2005 +0100
    17.3 @@ -130,9 +130,7 @@ bool xs_transaction_end(struct xs_handle
    17.4  bool xs_introduce_domain(struct xs_handle *h,
    17.5  			 unsigned int domid,
    17.6  			 unsigned long mfn,
    17.7 -                         unsigned int eventchn,
    17.8 -			 const char *path);
    17.9 -
   17.10 +                         unsigned int eventchn); 
   17.11  /* Release a domain.
   17.12   * Tells the store domain to release the memory page to the domain.
   17.13   */