# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID 6a7253b1ce8ad357698219910ee6628be4a2efb9
# Parent fb265175f47c53ca193e6e264570981e228dacd0
Fix the recently-introduced failure to preserve uuid across a guest reboot.
Store the uuid in string form inside XendDomainInfo, to aid this.
Add restart-squelching logic to ensure that runaway domains to restart
indefinitely. The logic here could be cleverer, say including a backoff for
retrying, in case a network block device has gone away, but for now this will
do to stop the pathological behaviour. Fixes bug #275.
Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
diff -r fb265175f47c -r 6a7253b1ce8a tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Wed Oct 19 17:18:30 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Thu Oct 20 11:34:50 2005
@@ -87,6 +87,10 @@
ZOMBIE_PREFIX = 'Zombie-'
+"""Minimum time between domain restarts in seconds."""
+MINIMUM_RESTART_TIME = 20
+
+
xc = xen.lowlevel.xc.new()
xroot = XendRoot.instance()
@@ -102,6 +106,7 @@
# file, so those are handled separately.
ROUNDTRIPPING_CONFIG_ENTRIES = [
('name', str),
+ ('uuid', str),
('ssidref', int),
('vcpus', int),
('vcpu_avail', int),
@@ -141,7 +146,7 @@
log.debug("XendDomainInfo.create(%s)", config)
- vm = XendDomainInfo(uuid.create(), parseConfig(config))
+ vm = XendDomainInfo(parseConfig(config))
try:
vm.construct()
vm.initDomain()
@@ -166,10 +171,13 @@
domid = xeninfo['dom']
uuid1 = xeninfo['handle']
+ xeninfo['uuid'] = uuid.toString(uuid1)
dompath = GetDomainPath(domid)
if not dompath:
raise XendError(
'No domain path in store for existing domain %d' % domid)
+
+ log.info("Recreating domain %d, UUID %s.", domid, xeninfo['uuid'])
try:
vmpath = xstransact.Read(dompath, "vm")
if not vmpath:
@@ -185,19 +193,15 @@
if uuid1 != uuid2:
raise XendError(
'Uuid in store does not match uuid for existing domain %d: '
- '%s != %s' % (domid, uuid2_str, uuid.toString(uuid1)))
-
- log.info("Recreating domain %d, UUID %s.", domid, uuid2_str)
-
- vm = XendDomainInfo(uuid1, xeninfo, domid, dompath, True)
+ '%s != %s' % (domid, uuid2_str, xeninfo['uuid']))
+
+ vm = XendDomainInfo(xeninfo, domid, dompath, True)
except Exception, exn:
- log.warn(str(exn))
-
- log.info("Recreating domain %d with UUID %s.", domid,
- uuid.toString(uuid1))
-
- vm = XendDomainInfo(uuid1, xeninfo, domid, dompath, True)
+ if True:
+ log.warn(str(exn))
+
+ vm = XendDomainInfo(xeninfo, domid, dompath, True)
vm.removeDom()
vm.removeVm()
vm.storeVmDetails()
@@ -215,8 +219,7 @@
log.debug("XendDomainInfo.restore(%s)", config)
- vm = XendDomainInfo(uuid.fromString(sxp.child_value(config, 'uuid')),
- parseConfig(config))
+ vm = XendDomainInfo(parseConfig(config))
try:
vm.construct()
vm.storeVmDetails()
@@ -335,18 +338,14 @@
return None
class XendDomainInfo:
- """Virtual machine object."""
-
- """Minimum time between domain restarts in seconds.
- """
- MINIMUM_RESTART_TIME = 20
-
-
- def __init__(self, uuidbytes, info, domid = None, dompath = None,
- augment = False):
-
- self.uuidbytes = uuidbytes
+
+
+ def __init__(self, info, domid = None, dompath = None, augment = False):
+
self.info = info
+
+ if not self.infoIsSet('uuid'):
+ self.info['uuid'] = uuid.toString(uuid.create())
if domid is not None:
self.domid = domid
@@ -355,7 +354,7 @@
else:
self.domid = None
- self.vmpath = VMROOT + uuid.toString(uuidbytes)
+ self.vmpath = VMROOT + self.info['uuid']
self.dompath = dompath
if augment:
@@ -571,7 +570,7 @@
def storeVmDetails(self):
to_store = {
- 'uuid': uuid.toString(self.uuidbytes),
+ 'uuid': self.info['uuid'],
# XXX
'memory/target': str(self.info['memory_KiB'])
@@ -928,7 +927,6 @@
def sxpr(self):
sxpr = ['domain',
['domid', self.domid],
- ['uuid', uuid.toString(self.uuidbytes)],
['memory', self.info['memory_KiB'] / 1024]]
for e in ROUNDTRIPPING_CONFIG_ENTRIES:
@@ -1045,8 +1043,9 @@
self.domid,
self.info['ssidref'])
- self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'],
- handle = self.uuidbytes)
+ self.domid = xc.domain_create(
+ dom = 0, ssidref = self.info['ssidref'],
+ handle = uuid.fromString(self.info['uuid']))
if self.domid < 0:
raise VmError('Creating domain failed: name=%s' %
@@ -1253,31 +1252,12 @@
## private:
- def restart_check(self):
- """Check if domain restart is OK.
- To prevent restart loops, raise an error if it is
- less than MINIMUM_RESTART_TIME seconds since the last restart.
- """
- tnow = time.time()
- if self.restart_time is not None:
- tdelta = tnow - self.restart_time
- if tdelta < self.MINIMUM_RESTART_TIME:
- self.restart_cancel()
- msg = 'VM %s restarting too fast' % self.info['name']
- log.error(msg)
- raise VmError(msg)
- self.restart_time = tnow
- self.restart_count += 1
-
-
def restart(self, rename = False):
"""Restart the domain after it has exited.
@param rename True if the old domain is to be renamed and preserved,
False if it is to be destroyed.
"""
-
- # self.restart_check()
config = self.sxpr()
@@ -1290,11 +1270,27 @@
self.writeVm('xend/restart_in_progress', 'True')
+ now = time.time()
+ rst = self.readVm('xend/previous_restart_time')
+ log.error(rst)
+ if rst:
+ rst = float(rst)
+ timeout = now - rst
+ if timeout < MINIMUM_RESTART_TIME:
+ log.error(
+ 'VM %s restarting too fast (%f seconds since the last '
+ 'restart). Refusing to restart to avoid loops.',
+ self.info['name'], timeout)
+ self.destroy()
+ return
+
+ self.writeVm('xend/previous_restart_time', str(now))
+
try:
if rename:
self.preserveForRestart()
else:
- self.destroy()
+ self.destroyDomain()
try:
xd = get_component('xen.xend.XendDomain')
@@ -1321,15 +1317,14 @@
"""
new_name = self.generateUniqueName()
- new_uuid = uuid.create()
- new_uuid_str = uuid.toString(new_uuid)
+ new_uuid = uuid.toString(uuid.create())
log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
- self.info['name'], self.domid, uuid.toString(self.uuidbytes),
- new_name, new_uuid_str)
+ self.info['name'], self.domid, self.info['uuid'],
+ new_name, new_uuid)
self.release_devices()
self.info['name'] = new_name
- self.uuidbytes = new_uuid
- self.vmpath = VMROOT + new_uuid_str
+ self.info['uuid'] = new_uuid
+ self.vmpath = VMROOT + new_uuid
self.storeVmDetails()
self.preserve()
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|