Xen live migration begins by sending a request, or reservation, to the target specifying the resources the migrating domain will need. If the target accepts the request, the source begins the iterative precopy phase of migration. During this step, Xen copies pages of memory over a TCP connection to the destination host. While this is happening, pages that change are marked as dirty and then recopied. The machine iterates this until only very frequently changed pages remain, at which point it begins the stop and copy phase. Now Xen stops the VM and copies over any pages that change too frequently to efficiently copy during the previous phase. In practice, our testing suggests that Xen usually reaches this point after four to eight iterations. Finally the VM starts executing on the new machine.
该函数主要是对输入的命令作参数解析,然后跳转到
opts.vals.port,
opts.vals.node,
opts.vals.ssl)
if not dominfo:
raise XendInvalidDomain(str(domid))
if dominfo.getDomid() == DOM0_ID:
raise XendError("Cannot migrate privileged domain %s" % domid)
if dominfo._stateGet() != DOM_STATE_RUNNING:
raise VMBadState("Domain is not running",
POWER_STATE_NAMES[DOM_STATE_RUNNING],POWER_STATE_NAMES[dominfo._stateGet()])
If step == 0: Check whether the device is ready to be migrated
or can at all be migrated; return a '-1' if
the device is NOT ready, a '0' otherwise. If it is
not ready ( = not possible to migrate this device),
migration will not take place.
step == 1: Called immediately after step 0; migration
of the kernel has started;
step == 2: Called after the suspend has been issued
to the domain and the domain is not scheduled anymore.
Synchronize with what was started in step 1, if necessary.
Now the device should initiate its transfer to the
given target. Since there might be more than just
one device initiating a migration, this step should
put the process performing the transfer into the
background and return immediately to achieve as much
concurrency as possible.
step == 3: Synchronize with the migration of the device that
was initiated in step 2.
Make sure that the migration has finished and only
then return from the call.
def save(fd, dominfo, network, live, dst, checkpoint=False, node=-1)
log.debug("In saveInputHandler %s", line)
if line == "suspend":
log.debug("Suspending %d ...", dominfo.getDomid())
dominfo.shutdown('suspend')
dominfo.waitForSuspend()
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')
Daemon()-->run()-->relocate.listenRelocation()-->tcp.TCPListener(RelocationProtocol, port, interface = interface, hosts_allow = hosts_allow)
if self.transport:
self.send_reply(["ready", name])
try:
XendDomain.instance().domain_restore_fd(
self.transport.sock.fileno(), relocating=True)
except:
self.send_error()
self.close()
else:
log.error(name + ": no transport")
raise XendError(name + ": no transport")
def restore(xd, fd, dominfo = None, paused = False, relocating = False):
store_port, console_port, int(is_hvm), pae, apic])
if m:
self.store_mfn = int(m.group(2))
else:
m = re.match(r"^(console-mfn) (\d+)$", line)
if m:
self.console_mfn = int(m.group(2))
os.read(fd, 1) # Wait for source to close connection
dominfo.completeRestore(handler.store_mfn, handler.console_mfn):
self._introduceDomain()self.image = image.create(self, self.info)if self.image:self.image.createDeviceModel(True)self._storeDomDetails()self._registerWatches()self.refreshShutdown()
暂时还没有仔细看。