direct-io.hg

changeset 7480:a90d670c98b9

Change the semantics of GetDomainPath so that it always succeeds, regardless of
whether a domain has been introduced to the store. Added a separate message
XS_IS_DOMAIN_INTRODUCED and API for that (xs_is_domain_introduced) to determine
whether the domain has really been introduced. This change means that the
tools can determine the correct domain path earlier in the domain creation
process, which is particularly a factor with live migration, as it allows us
to create the devices earlier in the process, and unpause the new domain before
performing the introduce. Until recently we already had these features, but
the simplification of the interface between xend and xenstored caused breakage.

No longer clear out the domain path when a domain is introduced -- this was a
hack to work around the recent problematic semantics of GetDomainPath.

Do not write the contents of the info block to the store. All the configuration
info is written to the /vm path, and anything else in the info block is either
dealt with explicitly or is ephemeral and has no place in the store.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Sun Oct 23 22:45:15 2005 +0100 (2005-10-23)
parents 5a728a884242
children 1c62a4149b11
files tools/console/daemon/io.c tools/python/xen/lowlevel/xs/xs.c tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomainInfo.py tools/xenstore/xenstored_core.c tools/xenstore/xenstored_core.h tools/xenstore/xenstored_domain.c tools/xenstore/xenstored_domain.h tools/xenstore/xs.c tools/xenstore/xs.h xen/include/public/io/xs_wire.h
line diff
     1.1 --- a/tools/console/daemon/io.c	Sun Oct 23 22:34:13 2005 +0100
     1.2 +++ b/tools/console/daemon/io.c	Sun Oct 23 22:45:15 2005 +0100
     1.3 @@ -301,10 +301,7 @@ static struct domain *create_domain(int 
     1.4  	}
     1.5  
     1.6  	dom->domid = domid;
     1.7 -
     1.8  	dom->conspath = xs_get_domain_path(xs, dom->domid);
     1.9 -	if (dom->conspath == NULL)
    1.10 -		goto out;
    1.11  	s = realloc(dom->conspath, strlen(dom->conspath) +
    1.12  		    strlen("/console") + 1);
    1.13  	if (s == NULL)
     2.1 --- a/tools/python/xen/lowlevel/xs/xs.c	Sun Oct 23 22:34:13 2005 +0100
     2.2 +++ b/tools/python/xen/lowlevel/xs/xs.c	Sun Oct 23 22:45:15 2005 +0100
     2.3 @@ -795,11 +795,10 @@ static PyObject *xspy_close(PyObject *se
     2.4  }
     2.5  
     2.6  #define xspy_get_domain_path_doc "\n"			\
     2.7 -	"Return store path of domain.\n"		\
     2.8 +	"Return store path of domain, whether or not the domain exists.\n" \
     2.9  	" domid [int]: domain id\n"			\
    2.10  	"\n"						\
    2.11  	"Returns: [string] domain store path.\n"	\
    2.12 -	"         None if domid doesn't exist.\n"	\
    2.13  	"Raises RuntimeError on error.\n"		\
    2.14  	"\n"
    2.15  
     3.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Sun Oct 23 22:34:13 2005 +0100
     3.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Sun Oct 23 22:45:15 2005 +0100
     3.3 @@ -144,6 +144,8 @@ def restore(xd, fd):
     3.4          if handler.store_mfn is None or handler.console_mfn is None:
     3.5              raise XendError('Could not read store/console MFN')
     3.6  
     3.7 +        dominfo.unpause()
     3.8 +
     3.9          dominfo.completeRestore(handler.store_mfn, handler.console_mfn)
    3.10  
    3.11          return dominfo
     4.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Sun Oct 23 22:34:13 2005 +0100
     4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Sun Oct 23 22:45:15 2005 +0100
     4.3 @@ -198,7 +198,7 @@ def recreate(xeninfo, priv):
     4.4          vm = XendDomainInfo(xeninfo, domid, dompath, True)
     4.5  
     4.6      except Exception, exn:
     4.7 -        if True:
     4.8 +        if priv:
     4.9              log.warn(str(exn))
    4.10  
    4.11          vm = XendDomainInfo(xeninfo, domid, dompath, True)
    4.12 @@ -223,7 +223,9 @@ def restore(config):
    4.13      try:
    4.14          vm.construct()
    4.15          vm.storeVmDetails()
    4.16 +        vm.createDevices()
    4.17          vm.createChannels()
    4.18 +        vm.storeDomDetails()
    4.19          return vm
    4.20      except:
    4.21          vm.destroy()
    4.22 @@ -337,9 +339,9 @@ def dom_get(dom):
    4.23          log.debug("domain_getinfo(%d) failed, ignoring: %s", dom, str(err))
    4.24      return None
    4.25  
    4.26 +
    4.27  class XendDomainInfo:
    4.28  
    4.29 -
    4.30      def __init__(self, info, domid = None, dompath = None, augment = False):
    4.31  
    4.32          self.info = info
    4.33 @@ -558,13 +560,13 @@ class XendDomainInfo:
    4.34  
    4.35      def completeRestore(self, store_mfn, console_mfn):
    4.36  
    4.37 +        log.debug("XendDomainInfo.completeRestore")
    4.38 +
    4.39          self.store_mfn = store_mfn
    4.40          self.console_mfn = console_mfn
    4.41  
    4.42          self.introduceDomain()
    4.43 -        self.create_devices()
    4.44          self.storeDomDetails()
    4.45 -        self.unpause()
    4.46          self.refreshShutdown()
    4.47  
    4.48  
    4.49 @@ -597,10 +599,6 @@ class XendDomainInfo:
    4.50              'memory/target':      str(self.info['memory_KiB'])
    4.51              }
    4.52  
    4.53 -        for (k, v) in self.info.items():
    4.54 -            if v:
    4.55 -                to_store[k] = str(v)
    4.56 -
    4.57          def f(n, v):
    4.58              if v is not None:
    4.59                  to_store[n] = str(v)
    4.60 @@ -1055,6 +1053,10 @@ class XendDomainInfo:
    4.61              raise VmError('Creating domain failed: name=%s' %
    4.62                            self.info['name'])
    4.63  
    4.64 +        self.dompath = GetDomainPath(self.domid)
    4.65 +
    4.66 +        self.removeDom()
    4.67 +
    4.68          # Set maximum number of vcpus in domain
    4.69          xc.domain_max_vcpus(self.domid, int(self.info['vcpus']))
    4.70  
    4.71 @@ -1065,8 +1067,6 @@ class XendDomainInfo:
    4.72          assert self.store_port is not None
    4.73          
    4.74          IntroduceDomain(self.domid, self.store_mfn, self.store_port)
    4.75 -        self.dompath = GetDomainPath(self.domid)
    4.76 -        assert self.dompath
    4.77  
    4.78  
    4.79      def initDomain(self):
    4.80 @@ -1105,7 +1105,7 @@ class XendDomainInfo:
    4.81  
    4.82          self.introduceDomain()
    4.83  
    4.84 -        self.create_devices()
    4.85 +        self.createDevices()
    4.86  
    4.87          self.info['start_time'] = time.time()
    4.88  
    4.89 @@ -1209,23 +1209,21 @@ class XendDomainInfo:
    4.90              raise
    4.91  
    4.92  
    4.93 -    def create_configured_devices(self):
    4.94 -        for (n, c) in self.info['device']:
    4.95 -            self.createDevice(n, c)
    4.96 +    ## public:
    4.97  
    4.98 -
    4.99 -    def create_devices(self):
   4.100 +    def createDevices(self):
   4.101          """Create the devices for a vm.
   4.102  
   4.103          @raise: VmError for invalid devices
   4.104          """
   4.105 -        self.create_configured_devices()
   4.106 +
   4.107 +        for (n, c) in self.info['device']:
   4.108 +            self.createDevice(n, c)
   4.109 +
   4.110          if self.image:
   4.111              self.image.createDeviceModel()
   4.112  
   4.113  
   4.114 -    ## public:
   4.115 -
   4.116      def device_create(self, dev_config):
   4.117          """Create a new device.
   4.118  
     5.1 --- a/tools/xenstore/xenstored_core.c	Sun Oct 23 22:34:13 2005 +0100
     5.2 +++ b/tools/xenstore/xenstored_core.c	Sun Oct 23 22:45:15 2005 +0100
     5.3 @@ -166,6 +166,7 @@ static char *sockmsg_string(enum xsd_soc
     5.4  	case XS_SET_PERMS: return "SET_PERMS";
     5.5  	case XS_WATCH_EVENT: return "WATCH_EVENT";
     5.6  	case XS_ERROR: return "ERROR";
     5.7 +	case XS_IS_DOMAIN_INTRODUCED: return "XS_IS_DOMAIN_INTRODUCED";
     5.8  	default:
     5.9  		return "**UNKNOWN**";
    5.10  	}
    5.11 @@ -1001,16 +1002,6 @@ static void do_rm(struct connection *con
    5.12  }
    5.13  
    5.14  
    5.15 -void internal_rm(const char *name)
    5.16 -{
    5.17 -	struct node *node = read_node(NULL, name);
    5.18 -	if (!node) {
    5.19 -		return;
    5.20 -	}
    5.21 -	_rm(NULL, node, name);
    5.22 -}
    5.23 -
    5.24 -
    5.25  static void do_get_perms(struct connection *conn, const char *name)
    5.26  {
    5.27  	struct node *node;
    5.28 @@ -1153,6 +1144,10 @@ static void process_message(struct conne
    5.29  		do_introduce(conn, in);
    5.30  		break;
    5.31  
    5.32 +	case XS_IS_DOMAIN_INTRODUCED:
    5.33 +		do_is_domain_introduced(conn, onearg(in));
    5.34 +		break;
    5.35 +
    5.36  	case XS_RELEASE:
    5.37  		do_release(conn, onearg(in));
    5.38  		break;
     6.1 --- a/tools/xenstore/xenstored_core.h	Sun Oct 23 22:34:13 2005 +0100
     6.2 +++ b/tools/xenstore/xenstored_core.h	Sun Oct 23 22:45:15 2005 +0100
     6.3 @@ -155,9 +155,6 @@ void __attribute__((noreturn)) corrupt(s
     6.4  struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
     6.5  
     6.6  
     6.7 -void internal_rm(const char *name);
     6.8 -
     6.9 -
    6.10  /* Is this a valid node name? */
    6.11  bool is_valid_nodename(const char *node);
    6.12  
     7.1 --- a/tools/xenstore/xenstored_domain.c	Sun Oct 23 22:34:13 2005 +0100
     7.2 +++ b/tools/xenstore/xenstored_domain.c	Sun Oct 23 22:45:15 2005 +0100
     7.3 @@ -250,6 +250,11 @@ bool domain_can_write(struct connection 
     7.4  	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
     7.5  }
     7.6  
     7.7 +static char *talloc_domain_path(void *context, unsigned int domid)
     7.8 +{
     7.9 +	return talloc_asprintf(context, "/local/domain/%u", domid);
    7.10 +}
    7.11 +
    7.12  static struct domain *new_domain(void *context, unsigned int domid,
    7.13  				 unsigned long mfn, int port)
    7.14  {
    7.15 @@ -262,7 +267,7 @@ static struct domain *new_domain(void *c
    7.16  	domain->port = 0;
    7.17  	domain->shutdown = 0;
    7.18  	domain->domid = domid;
    7.19 -	domain->path = talloc_asprintf(domain, "/local/domain/%d", domid);
    7.20 +	domain->path = talloc_domain_path(domain, domid);
    7.21  	domain->interface = xc_map_foreign_range(
    7.22  		*xc_handle, domain->domid,
    7.23  		getpagesize(), PROT_READ|PROT_WRITE, mfn);
    7.24 @@ -272,8 +277,6 @@ static struct domain *new_domain(void *c
    7.25  	list_add(&domain->list, &domains);
    7.26  	talloc_set_destructor(domain, destroy_domain);
    7.27  
    7.28 -	internal_rm(domain->path);
    7.29 -
    7.30  	/* Tell kernel we're interested in this event. */
    7.31          bind.remote_domain = domid;
    7.32          bind.remote_port   = port;
    7.33 @@ -403,25 +406,37 @@ void do_release(struct connection *conn,
    7.34  
    7.35  void do_get_domain_path(struct connection *conn, const char *domid_str)
    7.36  {
    7.37 -	struct domain *domain;
    7.38 -	unsigned int domid;
    7.39 +	char *path;
    7.40  
    7.41  	if (!domid_str) {
    7.42  		send_error(conn, EINVAL);
    7.43  		return;
    7.44  	}
    7.45  
    7.46 +	path = talloc_domain_path(conn, atoi(domid_str));
    7.47 +
    7.48 +	send_reply(conn, XS_GET_DOMAIN_PATH, path, strlen(path) + 1);
    7.49 +
    7.50 +	talloc_free(path);
    7.51 +}
    7.52 +
    7.53 +void do_is_domain_introduced(struct connection *conn, const char *domid_str)
    7.54 +{
    7.55 +	int result;
    7.56 +	unsigned int domid;
    7.57 +
    7.58 +        if (!domid_str) {
    7.59 +                send_error(conn, EINVAL);
    7.60 +                return;
    7.61 +        }
    7.62 +
    7.63  	domid = atoi(domid_str);
    7.64  	if (domid == DOMID_SELF)
    7.65 -		domain = conn->domain;
    7.66 +		result = 1;
    7.67  	else
    7.68 -		domain = find_domain_by_domid(domid);
    7.69 +		result = (find_domain_by_domid(domid) != NULL);
    7.70  
    7.71 -	if (!domain)
    7.72 -		send_error(conn, ENOENT);
    7.73 -	else
    7.74 -		send_reply(conn, XS_GET_DOMAIN_PATH, domain->path,
    7.75 -			   strlen(domain->path) + 1);
    7.76 +	send_reply(conn, XS_IS_DOMAIN_INTRODUCED, result ? "T" : "F", 2);
    7.77  }
    7.78  
    7.79  static int close_xc_handle(void *_handle)
     8.1 --- a/tools/xenstore/xenstored_domain.h	Sun Oct 23 22:34:13 2005 +0100
     8.2 +++ b/tools/xenstore/xenstored_domain.h	Sun Oct 23 22:45:15 2005 +0100
     8.3 @@ -26,6 +26,9 @@ void handle_event(void);
     8.4  void do_introduce(struct connection *conn, struct buffered_data *in);
     8.5  
     8.6  /* domid */
     8.7 +void do_is_domain_introduced(struct connection *conn, const char *domid_str);
     8.8 +
     8.9 +/* domid */
    8.10  void do_release(struct connection *conn, const char *domid_str);
    8.11  
    8.12  /* domid */
     9.1 --- a/tools/xenstore/xs.c	Sun Oct 23 22:34:13 2005 +0100
     9.2 +++ b/tools/xenstore/xs.c	Sun Oct 23 22:45:15 2005 +0100
     9.3 @@ -696,13 +696,20 @@ bool xs_introduce_domain(struct xs_handl
     9.4  				ARRAY_SIZE(iov), NULL));
     9.5  }
     9.6  
     9.7 -bool xs_release_domain(struct xs_handle *h, unsigned int domid)
     9.8 +static void * single_with_domid(struct xs_handle *h,
     9.9 +				enum xsd_sockmsg_type type,
    9.10 +				unsigned int domid)
    9.11  {
    9.12  	char domid_str[MAX_STRLEN(domid)];
    9.13  
    9.14  	sprintf(domid_str, "%u", domid);
    9.15  
    9.16 -	return xs_bool(xs_single(h, NULL, XS_RELEASE, domid_str, NULL));
    9.17 +	return xs_single(h, NULL, type, domid_str, NULL);
    9.18 +}
    9.19 +
    9.20 +bool xs_release_domain(struct xs_handle *h, unsigned int domid)
    9.21 +{
    9.22 +	return xs_bool(single_with_domid(h, XS_RELEASE, domid));
    9.23  }
    9.24  
    9.25  char *xs_get_domain_path(struct xs_handle *h, unsigned int domid)
    9.26 @@ -714,6 +721,12 @@ char *xs_get_domain_path(struct xs_handl
    9.27  	return xs_single(h, NULL, XS_GET_DOMAIN_PATH, domid_str, NULL);
    9.28  }
    9.29  
    9.30 +bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid)
    9.31 +{
    9.32 +	return strcmp("F",
    9.33 +		      single_with_domid(h, XS_IS_DOMAIN_INTRODUCED, domid));
    9.34 +}
    9.35 +
    9.36  /* Only useful for DEBUG versions */
    9.37  char *xs_debug_command(struct xs_handle *h, const char *cmd,
    9.38  		       void *data, unsigned int len)
    10.1 --- a/tools/xenstore/xs.h	Sun Oct 23 22:34:13 2005 +0100
    10.2 +++ b/tools/xenstore/xs.h	Sun Oct 23 22:45:15 2005 +0100
    10.3 @@ -140,6 +140,10 @@ bool xs_release_domain(struct xs_handle 
    10.4   */
    10.5  char *xs_get_domain_path(struct xs_handle *h, unsigned int domid);
    10.6  
    10.7 +/* Return whether the domain specified has been introduced to xenstored.
    10.8 + */
    10.9 +bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid);
   10.10 +
   10.11  /* Only useful for DEBUG versions */
   10.12  char *xs_debug_command(struct xs_handle *h, const char *cmd,
   10.13  		       void *data, unsigned int len);
    11.1 --- a/xen/include/public/io/xs_wire.h	Sun Oct 23 22:34:13 2005 +0100
    11.2 +++ b/xen/include/public/io/xs_wire.h	Sun Oct 23 22:45:15 2005 +0100
    11.3 @@ -47,6 +47,7 @@ enum xsd_sockmsg_type
    11.4      XS_SET_PERMS,
    11.5      XS_WATCH_EVENT,
    11.6      XS_ERROR,
    11.7 +    XS_IS_DOMAIN_INTRODUCED
    11.8  };
    11.9  
   11.10  #define XS_WRITE_NONE "NONE"