[HVM] Control qemu's state-save via xenstore, instead of SIGUSR1

This lets us verify that qemu has indeed stopped processing before
we start saving guest memory.  Also allow qemu to continue processing
after the save has happened, instead of exiting immediately.
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
This commit is contained in:
Tim Deegan committed 2007-07-24 14:52:16 +01:00
1 parent ab3a30feef
commit f6c12fc6b6
8 files changed
+132 -50

No files matched your search

+1 -5
View File
@@ -98,10 +98,6 @@ def save(fd, dominfo, network, live, dst, checkpoint=False):
log.info("Domain %d suspended.", dominfo.getDomid())
dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP3,
domain_name)
#send signal to device model for save
if hvm:
log.info("release_devices for hvm domain")
dominfo._releaseDevices(True)
tochild.write("done\n")
tochild.flush()
log.debug('Written done')
@@ -139,7 +135,7 @@ def save(fd, dominfo, network, live, dst, checkpoint=False):
except Exception, exn:
log.exception("Save failed on domain %s (%s).", domain_name,
dominfo.getDomid())
dominfo.resumeDomain()
log.debug("XendCheckpoint.save: resumeDomain")
+5
View File
@@ -1122,6 +1122,8 @@ class XendDomainInfo:
self._clearRestart()
if reason == 'suspend':
if self._stateGet() != DOM_STATE_SUSPENDED:
self.image.saveDeviceModel()
self._stateSet(DOM_STATE_SUSPENDED)
# Don't destroy the domain. XendCheckpoint will do
# this once it has finished. However, stop watching
@@ -1764,6 +1766,9 @@ class XendDomainInfo:
ResumeDomain(self.domid)
except:
log.exception("XendDomainInfo.resume: xc.domain_resume failed on domain %s." % (str(self.domid)))
if self.is_hvm():
self.image.resumeDeviceModel()
#
# Channels for xenstore and console
+36 -6
View File
@@ -20,6 +20,7 @@
import os, string
import re
import math
import time
import signal
import xen.lowlevel.xc
@@ -27,6 +28,7 @@ from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
from xen.xend.XendError import VmError, XendError, HVMRequired
from xen.xend.XendLogging import log
from xen.xend.XendOptions import instance as xenopts
from xen.xend.xenstore.xstransact import xstransact
from xen.xend.xenstore.xswatch import xswatch
from xen.xend import arch
@@ -175,6 +177,14 @@ class ImageHandler:
"""Create device model for the domain (define in subclass if needed)."""
pass
def saveDeviceModel(self):
"""Save device model for the domain (define in subclass if needed)."""
pass
def resumeDeviceModel(self):
"""Unpause device model for the domain (define in subclass if needed)."""
pass
def destroy(self):
"""Extra cleanup on domain destroy (define in subclass if needed)."""
pass
@@ -443,17 +453,34 @@ class HVMImageHandler(ImageHandler):
self.vm.storeDom("image/device-model-pid", self.pid)
log.info("device model pid: %d", self.pid)
def saveDeviceModel(self):
# Signal the device model to pause itself and save its state
xstransact.Store("/local/domain/0/device-model/%i"
% self.vm.getDomid(), ('command', 'save'))
# 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 != 'paused':
state = xstransact.Read("/local/domain/0/device-model/%i/state"
% self.vm.getDomid())
time.sleep(0.1)
count += 1
if count > 100:
raise VmError('Timed out waiting for device model to save')
def resumeDeviceModel(self):
# Signal the device model to resume activity after pausing to save.
xstransact.Store("/local/domain/0/device-model/%i"
% self.vm.getDomid(), ('command', 'continue'))
def recreate(self):
self.pid = self.vm.gatherDom(('image/device-model-pid', int))
def destroy(self, suspend = False):
if self.pid:
if self.pid and not suspend:
try:
sig = signal.SIGKILL
if suspend:
log.info("use sigusr1 to signal qemu %d", self.pid)
sig = signal.SIGUSR1
os.kill(self.pid, sig)
os.kill(self.pid, signal.SIGKILL)
except OSError, exn:
log.exception(exn)
try:
@@ -464,6 +491,8 @@ class HVMImageHandler(ImageHandler):
# but we can't wait for it because it's not our child.
pass
self.pid = None
state = xstransact.Remove("/local/domain/0/device-model/%i"
% self.vm.getDomid())
class IA64_HVM_ImageHandler(HVMImageHandler):
@@ -507,6 +536,7 @@ class X86_HVM_ImageHandler(HVMImageHandler):
return max(4 * (256 * self.vm.getVCpuCount() + 2 * (maxmem_kb / 1024)),
shadow_mem_kb)
class X86_Linux_ImageHandler(LinuxImageHandler):
def buildDomain(self):
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.