def exportToDB(self, save=False, sync=False): to_store = { 'id': self.id, 'dbid': self.dbid, 'config': sxp.to_string(self.config) } xstransact.Write(self.dbpath, to_store)
def exportToDB(self, save=False, sync=False): to_store = { 'id' : self.id, 'dbid' : self.dbid, 'config' : sxp.to_string(self.config) } xstransact.Write(self.dbpath, to_store)
def getDeviceDetails(self, config): log.debug('vbfs config=' + sxp.to_string(config)) luns = sxp.child_value(config, 'luns') if not luns: log.debug('vbfs: luns param not set') raise VmError('luns param not set') back = {'luns': luns} # devid = self.allocateDeviceID() devid = 1 front = {'virtual-device': "%i" % devid} log.info('bfsback :%s', back) log.info('bfsfront:%s', front) return (devid, back, front)
def getDeviceDetails(self, config): log.debug("vbfs config=" + sxp.to_string(config)) luns = sxp.child_value(config, "luns") if not luns: log.debug("vbfs: luns param not set") raise VmError("luns param not set") back = {"luns": luns} # devid = self.allocateDeviceID() devid = 1 front = {"virtual-device": "%i" % devid} log.info("bfsback :%s", back) log.info("bfsfront:%s", front) return (devid, back, front)
if node > -1: insert_after(sxprep,'vcpus',['node', str(node)]) for device_sxp in sxp.children(sxprep, 'device'): backend = sxp.child(device_sxp[1], 'backend') if backend == None: continue bkdominfo = XendDomain.instance().domain_lookup_nr(backend[1]) if bkdominfo == None: raise XendError("Could not find backend: %s" % backend[1]) if bkdominfo.getDomid() == XendDomain.DOM0_ID: # Skip for compatibility of checkpoint data format continue backend[1] = bkdominfo.getName() config = sxp.to_string(sxprep) domain_name = dominfo.getName() # Rename the domain temporarily, so that we don't get a name clash if this # domain is migrating (live or non-live) to the local host. Doing such a # thing is useful for debugging. dominfo.setName('migrating-' + domain_name) try: dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP1, domain_name) write_exact(fd, pack("!i", len(config)), "could not write guest state file: config len") write_exact(fd, config, "could not write guest state file: config") image_cfg = dominfo.info.get('image', {})
def sxp2string(sexp): return sxp.to_string(sexp)
def save(fd, dominfo, network, live, dst, checkpoint=False): write_exact(fd, SIGNATURE, "could not write guest state file: signature") # CoW timing checkpointtime = [] downtime = [] buf_list = [] # Cow timing checkpointtime.append(time.time()) config = sxp.to_string(dominfo.sxpr()) domain_name = dominfo.getName() # Rename the domain temporarily, so that we don't get a name clash if this # domain is migrating (live or non-live) to the local host. Doing such a # thing is useful for debugging. dominfo.setName('migrating-' + domain_name) try: dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP1, domain_name) write_exact(fd, pack("!i", len(config)), "could not write guest state file: config len") write_exact(fd, config, "could not write guest state file: config") image_cfg = dominfo.info.get('image', {}) hvm = dominfo.info.is_hvm() # xc_save takes three customization parameters: maxit, max_f, and # flags the last controls whether or not save is 'live', while the # first two further customize behaviour when 'live' save is # enabled. Passing "0" simply uses the defaults compiled into # libxenguest; see the comments and/or code in xc_linux_save() for # more information. cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd), str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ] def saveInputHandler(line, tochild): if line == "suspend": dominfo.shutdown('suspend') # CoW timing downtime.append(time.time()) dominfo.waitForShutdown() dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2, domain_name) dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP3, domain_name) if hvm: dominfo.image.saveDeviceModel() # for CoW purposes, get qemu-dm state qemu_fd = os.open("/var/lib/xen/qemu-save.%d" % dominfo.getDomid(), os.O_RDONLY) while True: buf = os.read(qemu_fd, dm_batch) if len(buf): buf_list.append(buf) else: break os.close(qemu_fd) # Cow: snapshot VBD os.system("/etc/xen/scripts/snapshot-vbd.sh %s" % os.path.basename(dst)) log.debug('Performed VBD snapshot') tochild.write("done\n") tochild.flush() if line == "restart": global down_end log.debug("Restarting %d ...", dominfo.getDomid()) dominfo.resumeDomain(downtime) # CoW timing downtime.append(time.time()) tochild.write("done\n") tochild.flush() forkHelper(cmd, fd, saveInputHandler, False) # put qemu device model state if os.path.exists("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()): os.remove("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()) write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature") for buf in buf_list: if len(buf): write_exact(fd, buf, "could not write device model state") else: break try: dominfo.setName(domain_name) except VmError: # Ignore this. The name conflict (hopefully) arises because we # are doing localhost migration; if we are doing a suspend of a # persistent VM, we need the rename, and don't expect the # conflict. This needs more thought. pass # CoW timing checkpointtime.append(time.time()) log.debug("[downtime] %s", downtime[2] - downtime[0]) log.debug("[checkpoint_time] %s", checkpointtime[1] - checkpointtime[0]) except Exception, exn: log.exception("Save failed on domain %s (%s) - resuming.", domain_name, dominfo.getDomid()) dominfo.resumeDomain([]) try: dominfo.setName(domain_name) except: log.exception("Failed to reset the migrating domain's name") raise exn
if node > -1: insert_after(sxprep, 'vcpus', ['node', str(node)]) for device_sxp in sxp.children(sxprep, 'device'): backend = sxp.child(device_sxp[1], 'backend') if backend == None: continue bkdominfo = XendDomain.instance().domain_lookup_nr(backend[1]) if bkdominfo == None: raise XendError("Could not find backend: %s" % backend[1]) if bkdominfo.getDomid() == XendDomain.DOM0_ID: # Skip for compatibility of checkpoint data format continue backend[1] = bkdominfo.getName() config = sxp.to_string(sxprep) domain_name = dominfo.getName() # Rename the domain temporarily, so that we don't get a name clash if this # domain is migrating (live or non-live) to the local host. Doing such a # thing is useful for debugging. dominfo.setName('migrating-' + domain_name) try: dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP1, domain_name) write_exact(fd, pack("!i", len(config)), "could not write guest state file: config len") write_exact(fd, config, "could not write guest state file: config") image_cfg = dominfo.info.get('image', {})
def save(fd, dominfo, network, live, dst, checkpoint=False, node=-1): write_exact(fd, SIGNATURE, "could not write guest state file: signature") sxprep = dominfo.sxpr() if node > -1: insert_after(sxprep, 'vcpus', ['node', str(node)]) config = sxp.to_string(sxprep) domain_name = dominfo.getName() # Rename the domain temporarily, so that we don't get a name clash if this # domain is migrating (live or non-live) to the local host. Doing such a # thing is useful for debugging. dominfo.setName('migrating-' + domain_name) try: dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP1, domain_name) write_exact(fd, pack("!i", len(config)), "could not write guest state file: config len") write_exact(fd, config, "could not write guest state file: config") image_cfg = dominfo.info.get('image', {}) hvm = dominfo.info.is_hvm() # xc_save takes three customization parameters: maxit, max_f, and # flags the last controls whether or not save is 'live', while the # first two further customize behaviour when 'live' save is # enabled. Passing "0" simply uses the defaults compiled into # libxenguest; see the comments and/or code in xc_linux_save() for # more information. cmd = [ xen.util.auxbin.pathTo(XC_SAVE), str(fd), str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ] log.debug("[xc_save]: %s", string.join(cmd)) def saveInputHandler(line, tochild): log.debug("In saveInputHandler %s", line) if line == "suspend": log.debug("Suspending %d ...", dominfo.getDomid()) dominfo.shutdown('suspend') dominfo.waitForShutdown() if line in ('suspend', 'suspended'): dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2, domain_name) log.info("Domain %d suspended.", dominfo.getDomid()) dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP3, domain_name) if hvm: dominfo.image.saveDeviceModel() if line == "suspend": tochild.write("done\n") tochild.flush() log.debug('Written done') forkHelper(cmd, fd, saveInputHandler, False) # put qemu device model state if os.path.exists("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()): write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature") qemu_fd = os.open("/var/lib/xen/qemu-save.%d" % dominfo.getDomid(), os.O_RDONLY) while True: buf = os.read(qemu_fd, dm_batch) if len(buf): write_exact(fd, buf, "could not write device model state") else: break os.close(qemu_fd) os.remove("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()) if checkpoint: dominfo.resumeDomain() else: dominfo.destroy() dominfo.testDeviceComplete() try: dominfo.setName(domain_name, False) except VmError: # Ignore this. The name conflict (hopefully) arises because we # are doing localhost migration; if we are doing a suspend of a # persistent VM, we need the rename, and don't expect the # conflict. This needs more thought. pass except Exception, exn: log.exception("Save failed on domain %s (%s) - resuming.", domain_name, dominfo.getDomid()) dominfo.resumeDomain() try: dominfo.setName(domain_name) except: log.exception("Failed to reset the migrating domain's name") raise exn
def save(fd, dominfo, network, live, dst, checkpoint=False, node=-1): write_exact(fd, SIGNATURE, "could not write guest state file: signature") sxprep = dominfo.sxpr() if node > -1: insert_after(sxprep,'vcpus',['node', str(node)]) config = sxp.to_string(sxprep) domain_name = dominfo.getName() # Rename the domain temporarily, so that we don't get a name clash if this # domain is migrating (live or non-live) to the local host. Doing such a # thing is useful for debugging. dominfo.setName('migrating-' + domain_name) try: dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP1, domain_name) write_exact(fd, pack("!i", len(config)), "could not write guest state file: config len") write_exact(fd, config, "could not write guest state file: config") image_cfg = dominfo.info.get('image', {}) hvm = dominfo.info.is_hvm() # xc_save takes three customization parameters: maxit, max_f, and # flags the last controls whether or not save is 'live', while the # first two further customize behaviour when 'live' save is # enabled. Passing "0" simply uses the defaults compiled into # libxenguest; see the comments and/or code in xc_linux_save() for # more information. cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd), str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ] log.debug("[xc_save]: %s", string.join(cmd)) def saveInputHandler(line, tochild): log.debug("In saveInputHandler %s", line) if line == "suspend": log.debug("Suspending %d ...", dominfo.getDomid()) dominfo.shutdown('suspend') dominfo.waitForShutdown() if line in ('suspend', 'suspended'): dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2, domain_name) log.info("Domain %d suspended.", dominfo.getDomid()) dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP3, domain_name) if hvm: dominfo.image.saveDeviceModel() if line == "suspend": tochild.write("done\n") tochild.flush() log.debug('Written done') forkHelper(cmd, fd, saveInputHandler, False) # put qemu device model state if os.path.exists("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()): write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature") qemu_fd = os.open("/var/lib/xen/qemu-save.%d" % dominfo.getDomid(), os.O_RDONLY) while True: buf = os.read(qemu_fd, dm_batch) if len(buf): write_exact(fd, buf, "could not write device model state") else: break os.close(qemu_fd) os.remove("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()) if checkpoint: dominfo.resumeDomain() else: dominfo.destroy() dominfo.testDeviceComplete() try: dominfo.setName(domain_name, False) except VmError: # Ignore this. The name conflict (hopefully) arises because we # are doing localhost migration; if we are doing a suspend of a # persistent VM, we need the rename, and don't expect the # conflict. This needs more thought. pass except Exception, exn: log.exception("Save failed on domain %s (%s) - resuming.", domain_name, dominfo.getDomid()) dominfo.resumeDomain() try: dominfo.setName(domain_name) except: log.exception("Failed to reset the migrating domain's name") raise exn
def sxprtostr(sxpr): "convert an sxpr to string" return sxp.to_string(sxpr)
def save(fd, dominfo, network, live, dst, checkpoint=False): write_exact(fd, SIGNATURE, "could not write guest state file: signature") # CoW timing checkpointtime = [] downtime = [] buf_list = [] # Cow timing checkpointtime.append(time.time()) config = sxp.to_string(dominfo.sxpr()) domain_name = dominfo.getName() # Rename the domain temporarily, so that we don't get a name clash if this # domain is migrating (live or non-live) to the local host. Doing such a # thing is useful for debugging. dominfo.setName('migrating-' + domain_name) try: dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP1, domain_name) write_exact(fd, pack("!i", len(config)), "could not write guest state file: config len") write_exact(fd, config, "could not write guest state file: config") image_cfg = dominfo.info.get('image', {}) hvm = dominfo.info.is_hvm() # xc_save takes three customization parameters: maxit, max_f, and # flags the last controls whether or not save is 'live', while the # first two further customize behaviour when 'live' save is # enabled. Passing "0" simply uses the defaults compiled into # libxenguest; see the comments and/or code in xc_linux_save() for # more information. cmd = [ xen.util.auxbin.pathTo(XC_SAVE), str(fd), str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ] def saveInputHandler(line, tochild): if line == "suspend": dominfo.shutdown('suspend') # CoW timing downtime.append(time.time()) dominfo.waitForShutdown() dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2, domain_name) dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP3, domain_name) if hvm: dominfo.image.saveDeviceModel() # for CoW purposes, get qemu-dm state qemu_fd = os.open( "/var/lib/xen/qemu-save.%d" % dominfo.getDomid(), os.O_RDONLY) while True: buf = os.read(qemu_fd, dm_batch) if len(buf): buf_list.append(buf) else: break os.close(qemu_fd) # Cow: snapshot VBD os.system("/etc/xen/scripts/snapshot-vbd.sh %s" % os.path.basename(dst)) log.debug('Performed VBD snapshot') tochild.write("done\n") tochild.flush() if line == "restart": global down_end log.debug("Restarting %d ...", dominfo.getDomid()) dominfo.resumeDomain(downtime) # CoW timing downtime.append(time.time()) tochild.write("done\n") tochild.flush() forkHelper(cmd, fd, saveInputHandler, False) # put qemu device model state if os.path.exists("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()): os.remove("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()) write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature") for buf in buf_list: if len(buf): write_exact(fd, buf, "could not write device model state") else: break try: dominfo.setName(domain_name) except VmError: # Ignore this. The name conflict (hopefully) arises because we # are doing localhost migration; if we are doing a suspend of a # persistent VM, we need the rename, and don't expect the # conflict. This needs more thought. pass # CoW timing checkpointtime.append(time.time()) log.debug("[downtime] %s", downtime[2] - downtime[0]) log.debug("[checkpoint_time] %s", checkpointtime[1] - checkpointtime[0]) except Exception, exn: log.exception("Save failed on domain %s (%s) - resuming.", domain_name, dominfo.getDomid()) dominfo.resumeDomain([]) try: dominfo.setName(domain_name) except: log.exception("Failed to reset the migrating domain's name") raise exn