def decode(self, uri): for scheme in self.schemes: try: # If this passes, it is the correct scheme return scheme.decode(uri) except scheme_error, se: log.debug("Decode throws an error: '%s'" % se)
def waitForBackend(self, devid): frontpath = self.frontendPath(devid) # lookup a phantom phantomPath = xstransact.Read(frontpath, 'phantom_vbd') if phantomPath is not None: log.debug("Waiting for %s's phantom %s.", devid, phantomPath) statusPath = phantomPath + '/' + HOTPLUG_STATUS_NODE ev = Event() result = { 'status': Timeout } xswatch(statusPath, hotplugStatusCallback, ev, result) ev.wait(DEVICE_CREATE_TIMEOUT) err = xstransact.Read(statusPath, HOTPLUG_ERROR_NODE) if result['status'] != 'Connected': return (result['status'], err) backpath = xstransact.Read(frontpath, "backend") if backpath: statusPath = backpath + '/' + HOTPLUG_STATUS_NODE ev = Event() result = { 'status': Timeout } xswatch(statusPath, hotplugStatusCallback, ev, result) ev.wait(DEVICE_CREATE_TIMEOUT) err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE) return (result['status'], err) else: return (Missing, None)
def createSocket(self): from OpenSSL import SSL # make a SSL socket ctx = SSL.Context(SSL.SSLv23_METHOD) ctx.set_options(SSL.OP_NO_SSLv2) ctx.use_privatekey_file (self.ssl_key_file) ctx.use_certificate_file(self.ssl_cert_file) sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) sock.set_accept_state() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # SO_REUSEADDR does not always ensure that we do not get an address # in use error when restarted quickly # we implement a timeout to try and avoid failing unnecessarily timeout = time.time() + 30 while True: try: if not self.isValidIP(self.interface): self.interface = self.getIfAddr(self.interface) log.debug("Listening on %s:%s" % (self.interface, self.port)) sock.bind((self.interface, self.port)) return sock except socket.error, (_errno, strerrno): if _errno == errno.EADDRINUSE and time.time() < timeout: time.sleep(0.5) else: raise
def waitForDevice(self, devid): log.debug("Waiting for %s.", devid) status = self.waitForBackend(devid) if status == Timeout: self.destroyDevice(devid) raise VmError("Device %s (%s) could not be connected. " "Hotplug scripts not working." % (devid, self.deviceClass)) elif status == Error: self.destroyDevice(devid) raise VmError("Device %s (%s) could not be connected. " "Backend device not found." % (devid, self.deviceClass)) elif status == Missing: # Don't try to destroy the device; it's already gone away. raise VmError("Device %s (%s) could not be connected. " "Device not found." % (devid, self.deviceClass)) elif status == Busy: err = None frontpath = self.frontendPath(devid) backpath = xstransact.Read(frontpath, "backend") if backpath: err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE) if not err: err = "Busy." self.destroyDevice(devid) raise VmError("Device %s (%s) could not be connected.\n%s" % (devid, self.deviceClass, err))
def show_dict(self, dict=None): if self.debug == 0: return if dict == None: dict = self.udi_dict for key in dict: log.debug('udi_info %s udi_info:%s', key, dict[key])
def main(self): try: while True: try: data = self.sock.recv(BUFFER_SIZE) if data == "": break if self.protocol.dataReceived(data): break except socket.error, ex: if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): break except (SSL.WantReadError, SSL.WantWriteError, \ SSL.WantX509LookupError): # The operation did not complete; the same I/O method # should be called again. continue except SSL.ZeroReturnError: # The SSL Connection has been closed. break except SSL.SysCallError, (retval, desc): if ((retval == -1 and desc == "Unexpected EOF") or retval > 0): # The SSL Connection is lost. break log.debug("SSL SysCallError:%d:%s" % (retval, desc)) break
def op_start(self, _, req): self.acceptCommand(req) paused = False if 'paused' in req.args and req.args['paused'] == [1]: paused = True log.debug("Starting domain " + self.dom.getName() + " " + str(paused)) return self.xd.domain_start(self.dom.getName(), paused)
def __matchPCIdev( self, list ): ret = False if list == None: return False for id in list: if id.startswith(self.devid[:9]): # id's vendor and device ID match skey = id.split(':') size = len(skey) if (size == 2): # subvendor/subdevice not suplied ret = True break elif (size == 4): # check subvendor/subdevice # check subvendor subven = '%04x' % self.subvendor if ((skey[2] != 'FFFF') and (skey[2] != 'ffff') and (skey[2] != subven)): continue # check subdevice subdev = '%04x' % self.subdevice if ((skey[3] != 'FFFF') and (skey[3] != 'ffff') and (skey[3] != subdev)): continue ret = True break else: log.debug("WARNING: invalid configuration entry: %s" % id) ret = False break return ret
def waitForDevice(self, devid): log.debug("Waiting for %s.", devid) if not self.hotplug: return (status, err) = self.waitForBackend(devid) if status == Timeout: self.destroyDevice(devid, False) raise VmError("Device %s (%s) could not be connected. " "Hotplug scripts not working." % (devid, self.deviceClass)) elif status == Error: self.destroyDevice(devid, False) if err is None: raise VmError("Device %s (%s) could not be connected. " "Backend device not found." % (devid, self.deviceClass)) else: raise VmError("Device %s (%s) could not be connected. " "%s" % (devid, self.deviceClass, err)) elif status == Missing: # Don't try to destroy the device; it's already gone away. raise VmError("Device %s (%s) could not be connected. " "Device not found." % (devid, self.deviceClass)) elif status == Busy: self.destroyDevice(devid, False) if err is None: err = "Busy." raise VmError("Device %s (%s) could not be connected.\n%s" % (devid, self.deviceClass, err))
def waitForBackend(self, devid): frontpath = self.frontendPath(devid) # lookup a phantom phantomPath = xstransact.Read(frontpath, 'phantom_vbd') if phantomPath is not None: log.debug("Waiting for %s's phantom %s.", devid, phantomPath) statusPath = phantomPath + '/' + HOTPLUG_STATUS_NODE ev = Event() result = {'status': Timeout} xswatch(statusPath, hotplugStatusCallback, ev, result) ev.wait(DEVICE_CREATE_TIMEOUT) err = xstransact.Read(statusPath, HOTPLUG_ERROR_NODE) if result['status'] != Connected: return (result['status'], err) backpath = self.readVm(devid, "backend") if backpath: statusPath = backpath + '/' + HOTPLUG_STATUS_NODE ev = Event() result = {'status': Timeout} xswatch(statusPath, hotplugStatusCallback, ev, result) ev.wait(DEVICE_CREATE_TIMEOUT) err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE) return (result['status'], err) else: return (Missing, None)
def forkHelper(cmd, fd, inputHandler, closeToChild): child = xPopen3(cmd, True, -1, [fd]) if closeToChild: child.tochild.close() thread = threading.Thread(target=slurp, args=(child.childerr, )) thread.start() try: try: while 1: line = child.fromchild.readline() if line == "": break else: line = line.rstrip() log.debug('%s', line) inputHandler(line, child.tochild) except IOError, exn: raise XendError('Error reading from child process for %s: %s' % (cmd, exn)) finally: child.fromchild.close() if not closeToChild: child.tochild.close() thread.join() child.childerr.close() status = child.wait() if status >> 8 == 127: raise XendError("%s failed: popen failed" % string.join(cmd)) elif status != 0: raise XendError("%s failed" % string.join(cmd))
def show_dict(self,dict=None): if self.debug == 0 : return if dict == None : dict = self.udi_dict for key in dict: log.debug('udi_info %s udi_info:%s',key,dict[key])
def do_FLR_for_GM45_iGFX(self): reg32 = self.pci_conf_read32(PCI_CAP_IGFX_CAP09_OFFSET) if ((reg32 >> 16) & 0x000000FF) != 0x06 or \ ((reg32 >> 24) & 0x000000F0) != 0x20: return self.pci_conf_write8(PCI_CAP_IGFX_GDRST_OFFSET, PCI_CAP_IGFX_GDRST) for i in range(0, 10): time.sleep(0.100) reg8 = self.pci_conf_read8(PCI_CAP_IGFX_GDRST_OFFSET) if (reg8 & 0x01) == 0: break if i == 10: log.debug("Intel iGFX FLR fail on GM45") return # This specific reset will hang if the command register does not have # memory space access enabled cmd = self.pci_conf_read16(PCI_COMMAND) self.pci_conf_write16(PCI_COMMAND, (cmd | 0x02)) af_pos = PCI_CAP_IGFX_CAP09_OFFSET self.do_AF_FLR(af_pos) self.pci_conf_write16(PCI_COMMAND, cmd) log.debug("Intel iGFX FLR on GM45 done")
def forkHelper(cmd, fd, inputHandler, closeToChild): child = xPopen3(cmd, True, -1, [fd]) if closeToChild: child.tochild.close() thread = threading.Thread(target = slurp, args = (child.childerr,)) thread.start() try: try: while 1: line = child.fromchild.readline() if line == "": break else: line = line.rstrip() log.debug('%s', line) inputHandler(line, child.tochild) except IOError, exn: raise XendError('Error reading from child process for %s: %s' % (cmd, exn)) finally: child.fromchild.close() if not closeToChild: child.tochild.close() thread.join() child.childerr.close() status = child.wait() if status >> 8 == 127: raise XendError("%s failed: popen failed" % string.join(cmd)) elif status != 0: raise XendError("%s failed" % string.join(cmd))
def get_host_block_device_io(self): # iostat | grep "sd*" | awk '{if (NF==6 && ($1 ~ /sd/)) print $1, $(NR-1), $NR}' usage_at = time.time() cmd = "iostat | grep \"sd*\"| awk '{if (NF==6 && ($1 ~ /sd/)) print $1, $NF-1, $NF}'" # log.debug(cmd) (rc, stdout, stderr) = doexec(cmd) out = stdout.read() result = [] if rc != 0: err = stderr.read(); stderr.close(); stdout.close(); log.debug('Failed to excute iostat!error:%s' % err) return result else: try: if out: lines = out.split('\n') for line in lines: if line.strip() and len(line.strip().split()) == 3: dev, rd_stat, wr_stat = line.strip().split() rd_stat = int(rd_stat) wr_stat = int(wr_stat) l = (usage_at, dev, rd_stat, wr_stat) result.append(l) except Exception, exn: log.debug(exn) finally:
def device_added_callback(self, udi): log.debug('UDI %s was added', udi) self.show_dict(self.udi_dict) dev_obj = self.bus.get_object('org.freedesktop.Hal', udi) dev = dbus.Interface(dev_obj, 'org.freedesktop.Hal.Device') device = dev.GetProperty('block.device') major = dev.GetProperty('block.major') minor = dev.GetProperty('block.minor') udi_info = {} udi_info['device'] = device udi_info['major'] = major udi_info['minor'] = minor udi_info['udi'] = udi already = 0 cnt = 0 for key in self.udi_dict: info = self.udi_dict[key] if info['udi'] == udi: already = 1 break cnt = cnt + 1 if already == 0: self.udi_dict[cnt] = udi_info log.debug( 'UDI %s was added, device:%s major:%s minor:%s index:%d\n', udi, device, major, minor, cnt) self.change_xenstore("add", device, major, minor)
def fd2send(sock, fd): try: while True: try: data = os.read(fd, BUFFER_SIZE) if data == "": break count = 0 while count < len(data): try: nbytes = sock.send(data[count:]) count += nbytes except socket.error, ex: if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): raise except (SSL.WantReadError, SSL.WantWriteError, \ SSL.WantX509LookupError): # The operation did not complete; the same I/O method # should be called again. continue except SSL.ZeroReturnError: # The SSL Connection has been closed. raise except SSL.SysCallError, (retval, desc): if not (retval == -1 and data == ""): # errors when writing empty strings are expected # and can be ignored log.debug("SSL SysCallError:%d:%s" % (retval, desc)) raise except SSL.Error, e: # other SSL errors log.debug("SSL Error:%s" % e) raise
def device_added_callback(self,udi): log.debug('UDI %s was added', udi) self.show_dict(self.udi_dict) dev_obj = self.bus.get_object ('org.freedesktop.Hal', udi) dev = dbus.Interface (dev_obj, 'org.freedesktop.Hal.Device') device = dev.GetProperty ('block.device') major = dev.GetProperty ('block.major') minor = dev.GetProperty ('block.minor') udi_info = {} udi_info['device'] = device udi_info['major'] = major udi_info['minor'] = minor udi_info['udi'] = udi already = 0 cnt = 0; for key in self.udi_dict: info = self.udi_dict[key] if info['udi'] == udi: already = 1 break cnt = cnt + 1 if already == 0: self.udi_dict[cnt] = udi_info; log.debug('UDI %s was added, device:%s major:%s minor:%s index:%d\n', udi, device, major, minor, cnt) self.change_xenstore( "add", device, major, minor)
def __matchPCIdev(self, list): ret = False if list == None: return False for id in list: if id.startswith( self.devid[:9]): # id's vendor and device ID match skey = id.split(':') size = len(skey) if (size == 2): # subvendor/subdevice not suplied ret = True break elif (size == 4): # check subvendor/subdevice # check subvendor subven = '%04x' % self.subvendor if ((skey[2] != 'FFFF') and (skey[2] != 'ffff') and (skey[2] != subven)): continue # check subdevice subdev = '%04x' % self.subdevice if ((skey[3] != 'FFFF') and (skey[3] != 'ffff') and (skey[3] != subdev)): continue ret = True break else: log.debug("WARNING: invalid configuration entry: %s" % id) ret = False break return ret
def recv2fd(sock, fd): try: while True: try: data = sock.recv(BUFFER_SIZE) if data == "": break count = 0 while count < len(data): try: nbytes = os.write(fd, data[count:]) count += nbytes except os.error, ex: if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): raise except socket.error, ex: if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): break except (SSL.WantReadError, SSL.WantWriteError, \ SSL.WantX509LookupError): # The operation did not complete; the same I/O method # should be called again. continue except SSL.ZeroReturnError: # The SSL Connection has been closed. break except SSL.SysCallError, (retval, desc): if ((retval == -1 and desc == "Unexpected EOF") or retval > 0): # The SSL Connection is lost. break log.debug("SSL SysCallError:%d:%s" % (retval, desc)) break
def migrate(self, deviceConfig, network, dst, step, domName): """@see DevContoller.migrate""" if network: tool = xoptions.get_external_migration_tool() if tool != '': log.info("Request to network-migrate device to %s. step=%d.", dst, step) if step == DEV_MIGRATE_TEST: """Assuming for now that everything is ok and migration with the given tool can proceed. """ return 0 else: fd = os.popen("%s -type vtpm -step %d -host %s -domname %s" % (tool, step, dst, domName), 'r') for line in fd.readlines(): mo = re.search('Error', line) if mo: raise XendError("vtpm: Fatal error in migration step %d: %s" % (step, line)) return 0 else: log.debug("External migration tool not in configuration.") return -1 return 0
def recreate_active_pools(cls): """ Read active pool config from hypervisor and create pool instances. - Query pool ids and assigned CPUs from hypervisor. - Query additional information for any pool from xenstore. If an entry for a pool id is missing in xenstore, it will be recreated with a new uuid and generic name (this is an error case) - Create an XendCPUPool instance for any pool id Function have to be called after recreation of managed pools. """ log.debug('recreate_active_pools') for pool_rec in xc.cpupool_getinfo(): pool = pool_rec['cpupool'] # read pool data from xenstore path = XS_POOLROOT + "%s/" % pool uuid = xstransact.Read(path, 'uuid') if not uuid: # xenstore entry missing / invaild; create entry with new uuid uuid = genuuid.createString() name = "Pool-%s" % pool try: inst = XendCPUPool({'name_label': name}, uuid, False) inst.update_XS(pool) except PoolError, ex: # log error and skip domain log.error('cannot recreate pool %s; skipping (reason: %s)' \ % (name, ex)) else: (name, descr) = xstransact.Read(path, 'name', 'description') other_config = {} for key in xstransact.List(path + 'other_config'): other_config[key] = xstransact.Read(path + 'other_config/%s' % key) # check existance of pool instance inst = XendAPIStore.get(uuid, cls.getClass()) if inst: # update attributes of existing instance inst.name_label = name inst.name_description = descr inst.other_config = other_config else: # recreate instance try: inst = XendCPUPool( { 'name_label': name, 'name_description': descr, 'other_config': other_config, 'proposed_CPUs': pool_rec['cpulist'], 'ncpu': len(pool_rec['cpulist']), }, uuid, False) except PoolError, ex: # log error and skip domain log.error( 'cannot recreate pool %s; skipping (reason: %s)' \ % (name, ex))
def waitForDevice_reconfigure(self, devid): log.debug("Waiting for %s - reconfigureDevice.", devid) (status, err) = self.waitForBackend_reconfigure(devid) if status == Timeout: raise VmError("Device %s (%s) could not be reconfigured. " % (devid, self.deviceClass))
def run(self): log.debug("%s", "In new run") try: self.mainloop = gobject.MainLoop() self.mainloop.run() except KeyboardInterrupt, ex: log.debug('Keyboard exception handler: %s', ex) self.mainloop.quit()
def run(self): log.debug( "%s", "In new run" ); try: self.mainloop = gobject.MainLoop() self.mainloop.run() except KeyboardInterrupt, ex: log.debug('Keyboard exception handler: %s', ex ) self.mainloop.quit()
def recreate_active_pools(cls): """ Read active pool config from hypervisor and create pool instances. - Query pool ids and assigned CPUs from hypervisor. - Query additional information for any pool from xenstore. If an entry for a pool id is missing in xenstore, it will be recreated with a new uuid and generic name (this is an error case) - Create an XendCPUPool instance for any pool id Function have to be called after recreation of managed pools. """ log.debug('recreate_active_pools') for pool_rec in xc.cpupool_getinfo(): pool = pool_rec['cpupool'] # read pool data from xenstore path = XS_POOLROOT + "%s/" % pool uuid = xstransact.Read(path, 'uuid') if not uuid: # xenstore entry missing / invaild; create entry with new uuid uuid = genuuid.createString() name = "Pool-%s" % pool try: inst = XendCPUPool( { 'name_label' : name }, uuid, False ) inst.update_XS(pool) except PoolError, ex: # log error and skip domain log.error('cannot recreate pool %s; skipping (reason: %s)' \ % (name, ex)) else: (name, descr) = xstransact.Read(path, 'name', 'description') other_config = {} for key in xstransact.List(path + 'other_config'): other_config[key] = xstransact.Read( path + 'other_config/%s' % key) # check existance of pool instance inst = XendAPIStore.get(uuid, cls.getClass()) if inst: # update attributes of existing instance inst.name_label = name inst.name_description = descr inst.other_config = other_config else: # recreate instance try: inst = XendCPUPool( { 'name_label' : name, 'name_description' : descr, 'other_config' : other_config, 'proposed_CPUs' : pool_rec['cpulist'], 'ncpu' : len(pool_rec['cpulist']), }, uuid, False ) except PoolError, ex: # log error and skip domain log.error( 'cannot recreate pool %s; skipping (reason: %s)' \ % (name, ex))
def __sendQuirks(self): for quirk in self.quirks: log.debug("Quirk Info: %04x:%02x:%02x.%1x-%s" % (self.domain, self.bus, self.slot, self.func, quirk)) try: f = file(QUIRK_SYSFS_NODE, "w") f.write("%04x:%02x:%02x.%1x-%s" % (self.domain, self.bus, self.slot, self.func, quirk)) f.close() except Exception, e: raise VmError("pci: failed to open/write/close quirks " + "sysfs node - " + str(e))
def __sendPermDevs(self): if self.__devIsUnconstrained(): log.debug("Unconstrained device: %04x:%02x:%02x.%1x" % (self.domain, self.bus, self.slot, self.func)) try: f = file(PERMISSIVE_SYSFS_NODE, "w") f.write("%04x:%02x:%02x.%1x" % (self.domain, self.bus, self.slot, self.func)) f.close() except Exception, e: raise VmError("pci: failed to open/write/close permissive " + "sysfs node: " + str(e))
def _handleAerStateWatch(self, _): log.debug('XendDomainInfo.handleAerStateWatch') if self.getDomid() == 0: raise XendError('Domain 0 cannot be shutdown') readPath = '/local/domain/0/backend/pci/%u/0/aerState' % (self.getDomid()) action = xstransact.Read(readPath) if action and action=='aerfail': log.debug('shutdown domain because of aer handle error') self.vm.shutdown('poweroff') return True
def device_removed_callback(self, udi): log.debug('UDI %s was removed', udi) self.show_dict(self.udi_dict) for key in self.udi_dict: udi_info = self.udi_dict[key] if udi_info['udi'] == udi: device = udi_info['device'] major = udi_info['major'] minor = udi_info['minor'] self.change_xenstore("remove", device, major, minor)
def setupDevice(self, config): """Setup devices from config """ pci_dev_list = config.get('devs', []) for d in pci_dev_list: self.setupOneDevice(d) wPath = '/local/domain/0/backend/pci/%u/0/aerState' % (self.getDomid()) self.aerStateWatch = xswatch(wPath, self._handleAerStateWatch) log.debug('pci: register aer watch %s', wPath) return
def device_removed_callback(self,udi): log.debug('UDI %s was removed',udi) self.show_dict(self.udi_dict) for key in self.udi_dict: udi_info = self.udi_dict[key] if udi_info['udi'] == udi: device = udi_info['device'] major = udi_info['major'] minor = udi_info['minor'] self.change_xenstore( "remove", device, major, minor)
def unregister_shutdown_watch(self): """Remove the watch on the control/shutdown, if any. Nothrow guarantee.""" try: if self.shutdownWatch: self.shutdownWatch.unwatch() except: log.exception("Unwatching hvm shutdown watch failed.") self.shutdownWatch = None log.debug("hvm shutdown watch unregistered")
def shutdown(self): """Shutdown the HalDaemon process """ log.debug("%s pid:%d", "Hald.shutdown()", self.pid) self.running = False self.ready = False if self.pid != -1: try: os.kill(self.pid, signal.SIGINT) except: print_exc()
def waitForDevice_destroy(self, devid, backpath): log.debug("Waiting for %s - destroyDevice.", devid) if not self.hotplug: return status = self.waitForBackend_destroy(backpath) if status == Timeout: raise VmError("Device %s (%s) could not be disconnected. " % (devid, self.deviceClass))
def dom0_setup(self): """Expects to be protected by the domains_lock.""" dom0 = self.domains[PRIV_DOMAIN] # get max number of vcpus to use for dom0 from config target = int(xroot.get_dom0_vcpus()) log.debug("number of vcpus to use is %d", target) # target == 0 means use all processors if target > 0: dom0.setVCpuCount(target)
def blkdev_name_to_number(name): """Take the given textual block-device name (e.g., '/dev/sda1', 'hda') and return the device number used by the OS. """ n = expand_dev_name(name) try: return os.stat(n).st_rdev except Exception, ex: log.debug("exception looking up device number for %s: %s", name, ex) pass
def run(self): """Starts the HalDaemon process """ self.ready = True try: myfile = self.find("xen/xend/server/HalDaemon.py") args = (["python", myfile]) self.pid = self.daemonize("python", args) #log.debug( "%s %s pid:%d", "Hald.py starting ", args, self.pid ) except: self.pid = -1 log.debug("Unable to start HalDaemon process")
def _readFirmwareFile(self, filename): # Sanity check if filename is None or filename.strip() == "": size = struct.pack('i', int(0)) return size + "" log.debug("Reading firmware file %s", filename) # Open try: fd = os.open(filename, os.O_RDONLY) except Exception, e: raise VmError('Unable to open firmware file %s' % filename)
def run(self): """Starts the HalDaemon process """ self.ready = True try: myfile = self.find("xen/xend/server/HalDaemon.py") args = (["python", myfile ]) self.pid = self.daemonize("python", args ) #log.debug( "%s %s pid:%d", "Hald.py starting ", args, self.pid ) except: self.pid = -1 log.debug("Unable to start HalDaemon process")
def signalDeviceModel(self, cmd, ret, par = None, timeout = True): if self.device_model is None: return # Signal the device model to for action if cmd is '' or ret is '': raise VmError('need valid command and result when signal device model') count = 0 while True: orig_state = xstransact.Read("/local/domain/0/device-model/%i/state" % self.vm.getDomid()) # This can occur right after start-up if orig_state != None: break log.debug('signalDeviceModel: orig_state is None, retrying') time.sleep(0.1) count += 1 if count < 100: continue raise VmError('Device model isn\'t ready for commands') if par is not None: xstransact.Store("/local/domain/0/device-model/%i" % self.vm.getDomid(), ('parameter', par)) xstransact.Store("/local/domain/0/device-model/%i" % self.vm.getDomid(), ('command', cmd)) # Wait for confirmation. Could do this with a watch but we'd # still end up spinning here waiting for the watch to fire. state = '' count = 0 while state != ret: state = xstransact.Read("/local/domain/0/device-model/%i/state" % self.vm.getDomid()) if state == 'error': msg = ("The device model returned an error: %s" % xstransact.Read("/local/domain/0/device-model/%i/error" % self.vm.getDomid())) raise VmError(msg) time.sleep(0.1) if timeout: count += 1 if count > 100: raise VmError('Timed out waiting for device model action') #resotre orig state xstransact.Store("/local/domain/0/device-model/%i" % self.vm.getDomid(), ('state', orig_state)) log.info("signalDeviceModel:restore dm state to %s", orig_state)