diff -r 8ca89a9e54a7 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/XendConfig.py Wed Apr 25 12:52:29 2007 -0400 @@ -26,6 +26,7 @@ from xen.xend.XendDevices import XendDev from xen.xend.XendDevices import XendDevices from xen.xend.PrettyPrint import prettyprintstring from xen.xend.XendConstants import DOM_STATE_HALTED +from xen.xend.xenstore.xstransact import xstransact log = logging.getLogger("xend.XendConfig") log.setLevel(logging.WARN) @@ -884,36 +885,43 @@ class XendConfig(dict): # Marshall devices (running or from configuration) if not ignore_devices: - for cls in XendDevices.valid_devices(): - found = False + txn = xstransact() + try: + for cls in XendDevices.valid_devices(): + found = False - # figure if there is a dev controller is valid and running - if domain and domain.getDomid() != None: - try: - controller = domain.getDeviceController(cls) - configs = controller.configurations() - for config in configs: - if sxp.name(config) in ('vbd', 'tap'): - # The bootable flag is never written to the - # store as part of the device config. - dev_uuid = sxp.child_value(config, 'uuid') - dev_type, dev_cfg = self['devices'][dev_uuid] - is_bootable = dev_cfg.get('bootable', 0) - config.append(['bootable', int(is_bootable)]) - - sxpr.append(['device', config]) - - found = True - except: - log.exception("dumping sxp from device controllers") - pass + # figure if there is a dev controller is valid and running + if domain and domain.getDomid() != None: + try: + controller = domain.getDeviceController(cls) + configs = controller.configurations(txn) + for config in configs: + if sxp.name(config) in ('vbd', 'tap'): + # The bootable flag is never written to the + # store as part of the device config. + dev_uuid = sxp.child_value(config, 'uuid') + dev_type, dev_cfg = self['devices'][dev_uuid] + is_bootable = dev_cfg.get('bootable', 0) + config.append(['bootable', int(is_bootable)]) + + sxpr.append(['device', config]) + + found = True + except: + log.exception("dumping sxp from device controllers") + pass - # if we didn't find that device, check the existing config - # for a device in the same class - if not found: - for dev_type, dev_info in self.all_devices_sxpr(): - if dev_type == cls: - sxpr.append(['device', dev_info]) + # if we didn't find that device, check the existing config + # for a device in the same class + if not found: + for dev_type, dev_info in self.all_devices_sxpr(): + if dev_type == cls: + sxpr.append(['device', dev_info]) + + txn.commit() + except: + txn.abort() + raise return sxpr diff -r 8ca89a9e54a7 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/XendDomain.py Wed Apr 25 12:53:38 2007 -0400 @@ -391,13 +391,22 @@ class XendDomain: @rtype: None """ + txn = xstransact() + try: + self._refreshTxn(txn, refresh_shutdown) + txn.commit() + except: + txn.abort() + raise + + def _refreshTxn(self, transaction, refresh_shutdown): running = self._running_domains() # Add domains that are not already tracked but running in Xen, # and update domain state for those that are running and tracked. for dom in running: domid = dom['domid'] if domid in self.domains: - self.domains[domid].update(dom, refresh_shutdown) + self.domains[domid].update(dom, refresh_shutdown, transaction) elif domid not in self.domains and dom['dying'] != 1: try: new_dom = XendDomainInfo.recreate(dom, False) diff -r 8ca89a9e54a7 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Apr 25 12:55:05 2007 -0400 @@ -704,12 +704,15 @@ class XendDomainInfo: self._update_consoles() - def _update_consoles(self): + def _update_consoles(self, transaction = None): if self.domid == None or self.domid == 0: return # Update VT100 port if it exists - self.console_port = self.readDom('console/port') + if transaction is None: + self.console_port = self.readDom('console/port') + else: + self.console_port = self.readDomTxn(transaction, 'console/port') if self.console_port is not None: serial_consoles = self.info.console_get_all('vt100') if not serial_consoles: @@ -722,7 +725,10 @@ class XendDomainInfo: # Update VNC port if it exists and write to xenstore - vnc_port = self.readDom('console/vnc-port') + if transaction is None: + vnc_port = self.readDom('console/vnc-port') + else: + vnc_port = self.readDomTxn(transaction, 'console/vnc-port') if vnc_port is not None: for dev_uuid, (dev_type, dev_info) in self.info['devices'].items(): if dev_type == 'vfb': @@ -757,6 +763,27 @@ class XendDomainInfo: def storeVm(self, *args): return xstransact.Store(self.vmpath, *args) + + def _readVmTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.read(*paths) + + def _writeVmTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.write(*paths) + + def _removeVmTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.remove(*paths) + + def _gatherVmTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.gather(paths) + + def storeVmTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.store(*paths) + # # Function to update xenstore /dom/* # @@ -775,6 +802,28 @@ class XendDomainInfo: def storeDom(self, *args): return xstransact.Store(self.dompath, *args) + + + def readDomTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.read(*paths) + + def gatherDomTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.gather(*paths) + + def _writeDomTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.write(*paths) + + def _removeDomTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.remove(*paths) + + def storeDomTxn(self, transaction, *args): + paths = map(lambda x: self.vmpath + "/" + x, args) + return transaction.store(*paths) + def _recreateDom(self): complete(self.dompath, lambda t: self._recreateDomFunc(t)) @@ -2062,7 +2111,7 @@ class XendDomainInfo: (" as domain %s" % str(dom.domid)) or "")) - def update(self, info = None, refresh = True): + def update(self, info = None, refresh = True, transaction = None): """Update with info from xc.domain_getinfo(). """ log.trace("XendDomainInfo.update(%s) on domain %s", info, @@ -2094,7 +2143,7 @@ class XendDomainInfo: # TODO: we should eventually get rid of old_dom_states self.info.update_config(info) - self._update_consoles() + self._update_consoles(transaction) if refresh: self.refreshShutdown(info) diff -r 8ca89a9e54a7 tools/python/xen/xend/server/ConsoleController.py --- a/tools/python/xen/xend/server/ConsoleController.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/server/ConsoleController.py Wed Apr 25 12:57:05 2007 -0400 @@ -19,9 +19,12 @@ class ConsoleController(DevController): return (self.allocateDeviceID(), back, {}) - def getDeviceConfiguration(self, devid): - result = DevController.getDeviceConfiguration(self, devid) - devinfo = self.readBackend(devid, *self.valid_cfg) + def getDeviceConfiguration(self, devid, transaction = None): + result = DevController.getDeviceConfiguration(self, devid, transaction) + if transaction is None: + devinfo = self.readBackend(devid, *self.valid_cfg) + else: + devinfo = self.readBackendTxn(transaction, devid, *self.valid_cfg) config = dict(zip(self.valid_cfg, devinfo)) config = dict([(key, val) for key, val in config.items() if val != None]) diff -r 8ca89a9e54a7 tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/server/DevController.py Wed Apr 25 12:57:05 2007 -0400 @@ -225,15 +225,15 @@ class DevController: self.vm._removeVm("device/%s/%d" % (self.deviceClass, devid)) - def configurations(self): - return map(self.configuration, self.deviceIDs()) - - - def configuration(self, devid): + def configurations(self, transaction = None): + return map(lambda x: self.configuration(x, transaction), self.deviceIDs(transaction)) + + + def configuration(self, devid, transaction = None): """@return an s-expression giving the current configuration of the specified device. This would be suitable for giving to {@link #createDevice} in order to recreate that device.""" - configDict = self.getDeviceConfiguration(devid) + configDict = self.getDeviceConfiguration(devid, transaction) sxpr = [self.deviceClass] for key, val in configDict.items(): if isinstance(val, (types.ListType, types.TupleType)): @@ -259,13 +259,16 @@ class DevController: 'id', devid]] - def getDeviceConfiguration(self, devid): + def getDeviceConfiguration(self, devid, transaction = None): """Returns the configuration of a device. @note: Similar to L{configuration} except it returns a dict. @return: dict """ - backdomid = xstransact.Read(self.frontendPath(devid), "backend-id") + if transaction is None: + backdomid = xstransact.Read(self.frontendPath(devid), "backend-id") + else: + backdomid = transaction.read(self.frontendPath(devid) + "/backend-id") if backdomid is None: raise VmError("Device %s not connected" % devid) @@ -393,14 +396,28 @@ class DevController: else: raise VmError("Device %s not connected" % devid) + def readBackendTxn(self, transaction, devid, *args): + frontpath = self.frontendPath(devid) + backpath = transaction.read(frontpath + "/backend") + if backpath: + paths = map(lambda x: backpath + "/" + x, args) + return transaction.read(*paths) + else: + raise VmError("Device %s not connected" % devid) + def readFrontend(self, devid, *args): return xstransact.Read(self.frontendPath(devid), *args) + + def readFrontendTxn(self, transaction, devid, *args): + paths = map(lambda x: self.frontendPath(devid) + "/" + x, args) + return transaction.read(*paths) def deviceIDs(self, transaction = None): """@return The IDs of each of the devices currently configured for this instance's deviceClass. """ fe = self.backendRoot() + if transaction: return map(lambda x: int(x.split('/')[-1]), transaction.list(fe)) else: diff -r 8ca89a9e54a7 tools/python/xen/xend/server/blkif.py --- a/tools/python/xen/xend/server/blkif.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/server/blkif.py Wed Apr 25 12:57:05 2007 -0400 @@ -107,19 +107,26 @@ class BlkifController(DevController): (self.deviceClass, devid, config)) - def getDeviceConfiguration(self, devid): + def getDeviceConfiguration(self, devid, transaction = None): """Returns the configuration of a device. @note: Similar to L{configuration} except it returns a dict. @return: dict """ - config = DevController.getDeviceConfiguration(self, devid) - devinfo = self.readBackend(devid, 'dev', 'type', 'params', 'mode', - 'uuid') + config = DevController.getDeviceConfiguration(self, devid, transaction) + if transaction is None: + devinfo = self.readBackend(devid, 'dev', 'type', 'params', 'mode', + 'uuid') + else: + devinfo = self.readBackendTxn(transaction, devid, + 'dev', 'type', 'params', 'mode', 'uuid') dev, typ, params, mode, uuid = devinfo if dev: - dev_type = self.readFrontend(devid, 'device-type') + if transaction is None: + dev_type = self.readFrontend(devid, 'device-type') + else: + dev_type = self.readFrontendTxn(transaction, devid, 'device-type') if dev_type: dev += ':' + dev_type config['dev'] = dev diff -r 8ca89a9e54a7 tools/python/xen/xend/server/netif.py --- a/tools/python/xen/xend/server/netif.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/server/netif.py Wed Apr 25 12:57:05 2007 -0400 @@ -149,16 +149,19 @@ class NetifController(DevController): return (devid, back, front) - def getDeviceConfiguration(self, devid): + def getDeviceConfiguration(self, devid, transaction = None): """@see DevController.configuration""" - result = DevController.getDeviceConfiguration(self, devid) + result = DevController.getDeviceConfiguration(self, devid, transaction) config_path = "device/%s/%d/" % (self.deviceClass, devid) devinfo = () for x in ( 'script', 'ip', 'bridge', 'mac', 'type', 'vifname', 'rate', 'uuid', 'model' ): - y = self.vm._readVm(config_path + x) + if transaction is None: + y = self.vm._readVm(config_path + x) + else: + y = self.vm._readVmTxn(transaction, config_path + x) devinfo += (y,) (script, ip, bridge, mac, typ, vifname, rate, uuid, model) = devinfo diff -r 8ca89a9e54a7 tools/python/xen/xend/server/pciif.py --- a/tools/python/xen/xend/server/pciif.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/server/pciif.py Wed Apr 25 12:57:05 2007 -0400 @@ -78,8 +78,8 @@ class PciController(DevController): back['uuid'] = config.get('uuid','') return (0, back, {}) - def getDeviceConfiguration(self, devid): - result = DevController.getDeviceConfiguration(self, devid) + def getDeviceConfiguration(self, devid, transaction = None): + result = DevController.getDeviceConfiguration(self, devid, transaction) num_devs = self.readBackend(devid, 'num_devs') pci_devs = [] diff -r 8ca89a9e54a7 tools/python/xen/xend/server/tpmif.py --- a/tools/python/xen/xend/server/tpmif.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/server/tpmif.py Wed Apr 25 12:57:05 2007 -0400 @@ -67,9 +67,9 @@ class TPMifController(DevController): return (devid, back, front) - def getDeviceConfiguration(self, devid): + def getDeviceConfiguration(self, devid, transaction = None): """Returns the configuration of a device""" - result = DevController.getDeviceConfiguration(self, devid) + result = DevController.getDeviceConfiguration(self, devid, transaction) (instance, uuid, type) = \ self.readBackend(devid, 'instance', diff -r 8ca89a9e54a7 tools/python/xen/xend/server/vfbif.py --- a/tools/python/xen/xend/server/vfbif.py Wed Apr 25 09:44:20 2007 +0100 +++ b/tools/python/xen/xend/server/vfbif.py Wed Apr 25 12:57:05 2007 -0400 @@ -35,10 +35,13 @@ class VfbifController(DevController): return (devid, back, {}) - def getDeviceConfiguration(self, devid): - result = DevController.getDeviceConfiguration(self, devid) + def getDeviceConfiguration(self, devid, transaction = None): + result = DevController.getDeviceConfiguration(self, devid, transaction) - devinfo = self.readBackend(devid, *CONFIG_ENTRIES) + if transaction is None: + devinfo = self.readBackend(devid, *CONFIG_ENTRIES) + else: + devinfo = self.readBackendTxn(transaction, devid, *CONFIG_ENTRIES) return dict([(CONFIG_ENTRIES[i], devinfo[i]) for i in range(len(CONFIG_ENTRIES)) if devinfo[i] is not None])