[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Watch for changes in the /vm section of the store, so that we update our
# HG changeset patch # User emellor@xxxxxxxxxxxxxxxxxxxxxx # Node ID 32b574b24b18f709d3ae53661fd1dbe1ed6ce31f # Parent 3631592ad7d3acf193eb0b0ae39f81169881b14b Watch for changes in the /vm section of the store, so that we update our internal state if the store is configured by an external tool. We react properly to changes in name and on_{reboot,poweroff,crash}. Reacting correctly to vcpus, vcpu_avail, memory, and maxmem will come soon (those code aspects are already under review). cpu_weight and bootloader to be considered. Removed unused and semantically invalid method XendDomainInfo.setDomid. Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx> diff -r 3631592ad7d3 -r 32b574b24b18 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Nov 16 14:27:59 2005 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Nov 16 14:32:56 2005 @@ -45,6 +45,8 @@ from xen.xend.xenstore.xstransact import xstransact from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain +from xen.xend.xenstore.xswatch import xswatch + """Shutdown code for poweroff.""" DOMAIN_POWEROFF = 0 @@ -82,7 +84,6 @@ SHUTDOWN_TIMEOUT = 30 -DOMROOT = '/local/domain/' VMROOT = '/vm/' ZOMBIE_PREFIX = 'Zombie-' @@ -100,26 +101,52 @@ #log.setLevel(logging.TRACE) -## Configuration entries that we expect to round-trip -- be read from the +## +# All parameters of VMs that may be configured on-the-fly, or at start-up. +# +VM_CONFIG_PARAMS = [ + ('name', str), + ('on_poweroff', str), + ('on_reboot', str), + ('on_crash', str), + ] + + +## +# Configuration entries that we expect to round-trip -- be read from the # config file or xc, written to save-files (i.e. through sxpr), and reused as # config on restart or restore, all without munging. Some configuration # entries are munged for backwards compatibility reasons, or because they # don't come out of xc in the same form as they are specified in the config # file, so those are handled separately. ROUNDTRIPPING_CONFIG_ENTRIES = [ - ('name', str), - ('uuid', str), - ('ssidref', int), - ('vcpus', int), - ('vcpu_avail', int), - ('cpu_weight', float), - ('memory', int), - ('maxmem', int), - ('bootloader', str), - ('on_poweroff', str), - ('on_reboot', str), - ('on_crash', str) + ('uuid', str), + ('ssidref', int), + ('vcpus', int), + ('vcpu_avail', int), + ('cpu_weight', float), + ('memory', int), + ('maxmem', int), + ('bootloader', str), ] + +ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS + + +## +# All entries written to the store. This is VM_CONFIGURATION_PARAMS, plus +# those entries written to the store that cannot be reconfigured on-the-fly. +# +VM_STORE_ENTRIES = [ + ('uuid', str), + ('ssidref', int), + ('vcpus', int), + ('vcpu_avail', int), + ('memory', int), + ('maxmem', int), + ] + +VM_STORE_ENTRIES += VM_CONFIG_PARAMS # @@ -156,6 +183,7 @@ vm.initDomain() vm.storeVmDetails() vm.storeDomDetails() + vm.registerWatch() vm.refreshShutdown() return vm except: @@ -211,6 +239,7 @@ vm.storeVmDetails() vm.storeDomDetails() + vm.registerWatch() vm.refreshShutdown(xeninfo) return vm @@ -371,12 +400,50 @@ self.console_port = None self.console_mfn = None + self.vmWatch = None + self.state = STATE_DOM_OK self.state_updated = threading.Condition() self.refresh_shutdown_lock = threading.Condition() ## private: + + def readVMDetails(self, params): + """Read from the store all of those entries that we consider + """ + try: + return self.gatherVm(*params) + except ValueError: + # One of the int/float entries in params has a corresponding store + # entry that is invalid. We recover, because older versions of + # Xend may have put the entry there (memory/target, for example), + # but this is in general a bad situation to have reached. + log.exception( + "Store corrupted at %s! Domain %d's configuration may be " + "affected.", self.vmpath, self.domid) + return [] + + + def storeChanged(self): + log.debug("XendDomainInfo.storeChanged"); + + changed = False + + def f(x, y): + if y is not None and self.info[x[0]] != y: + self.info[x[0]] = y + changed = True + + map(f, VM_CONFIG_PARAMS, self.readVMDetails(VM_CONFIG_PARAMS)) + + if changed: + # Update the domain section of the store, as this contains some + # parameters derived from the VM configuration. + self.storeDomDetails() + + return 1 + def augmentInfo(self): """Augment self.info, as given to us through {@link #recreate}, with @@ -387,30 +454,8 @@ if not self.infoIsSet(name) and val is not None: self.info[name] = val - params = (("name", str), - ("on_poweroff", str), - ("on_reboot", str), - ("on_crash", str), - ("image", str), - ("memory", int), - ("maxmem", int), - ("vcpus", int), - ("vcpu_avail", int), - ("start_time", float)) - - try: - from_store = self.gatherVm(*params) - except ValueError, exn: - # One of the int/float entries in params has a corresponding store - # entry that is invalid. We recover, because older versions of - # Xend may have put the entry there (memory/target, for example), - # but this is in general a bad situation to have reached. - log.exception( - "Store corrupted at %s! Domain %d's configuration may be " - "affected.", self.vmpath, self.domid) - return - - map(lambda x, y: useIfNeeded(x[0], y), params, from_store) + map(lambda x, y: useIfNeeded(x[0], y), VM_STORE_ENTRIES, + self.readVMDetails(VM_STORE_ENTRIES)) device = [] for c in controllerClasses: @@ -536,23 +581,23 @@ self.introduceDomain() self.storeDomDetails() + self.registerWatch() self.refreshShutdown() log.debug("XendDomainInfo.completeRestore done") def storeVmDetails(self): - to_store = { - 'uuid': self.info['uuid'] - } + to_store = {} + + for k in VM_STORE_ENTRIES: + if self.infoIsSet(k[0]): + to_store[k[0]] = str(self.info[k[0]]) if self.infoIsSet('image'): to_store['image'] = sxp.to_string(self.info['image']) - for k in ['name', 'ssidref', 'memory', 'maxmem', 'on_poweroff', - 'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail']: - if self.infoIsSet(k): - to_store[k] = str(self.info[k]) + to_store['start_time'] = str(self.info['start_time']) log.debug("Storing VM details: %s", to_store) @@ -599,13 +644,16 @@ return result - def setDomid(self, domid): - """Set the domain id. - - @param dom: domain id - """ - self.domid = domid - self.storeDom("domid", self.domid) + ## public: + + def registerWatch(self): + """Register a watch on this VM's entries in the store, so that + when they are changed externally, we keep up to date. This should + only be called by {@link #create}, {@link #recreate}, or {@link + #restore}, once the domain's details have been written, but before the + new instance is returned.""" + self.vmWatch = xswatch(self.vmpath, self.storeChanged) + def getDomid(self): return self.domid @@ -1116,6 +1164,13 @@ """Cleanup VM resources. Idempotent. Nothrow guarantee.""" try: + try: + if self.vmWatch: + self.vmWatch.unwatch() + self.vmWatch = None + except: + log.exception("Unwatching VM path failed.") + self.removeVm() except: log.exception("Removing VM path failed.") _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |