# HG changeset patch
# User emellor@ewan
# Node ID 244f1aa98d30e72b1da9e2951371ce7ebf3b85ee
# Parent 468ad17f997033d81428edec24a1048e6ef9eda9
Add the config file parsing for the on_{poweroff,reboot,crash} options, so that
they actually take effect. Added behaviour "rename-restart" for debugging
purposes, that renames the domain out of the way, preserving it for debugging,
but starts a new domain too.
Add explicit remove of old domain paths when creating a new domain, to avoid
stale information affecting us (by shutting the domain down, for example).
Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
diff -r 468ad17f9970 -r 244f1aa98d30 tools/examples/xmexample.vmx
--- a/tools/examples/xmexample.vmx Fri Sep 30 16:05:08 2005
+++ b/tools/examples/xmexample.vmx Fri Sep 30 16:10:20 2005
@@ -50,10 +50,15 @@
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
-# may specify "destroy", meaning that the domain is cleaned up as normal,
-# "restart", meaning that a new domain is started in place of the old one, or
-# "preserve", meaning that no clean-up is done until the domain is manually
-# destroyed (using xm destroy, for example).
+# may specify:
+#
+# "destroy", meaning that the domain is cleaned up as normal;
+# "restart", meaning that a new domain is started in place of the old
+# one;
+# "preserve", meaning that no clean-up is done until the domain is
+# manually destroyed (using xm destroy, for example); or
+# "rename-restart", meaning that the old domain is not cleaned up, but is
+# renamed and a new domain started in its place.
#
# The default is
#
diff -r 468ad17f9970 -r 244f1aa98d30 tools/examples/xmexample1
--- a/tools/examples/xmexample1 Fri Sep 30 16:05:08 2005
+++ b/tools/examples/xmexample1 Fri Sep 30 16:10:20 2005
@@ -93,10 +93,15 @@
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
-# may specify "destroy", meaning that the domain is cleaned up as normal,
-# "restart", meaning that a new domain is started in place of the old one, or
-# "preserve", meaning that no clean-up is done until the domain is manually
-# destroyed (using xm destroy, for example).
+# may specify:
+#
+# "destroy", meaning that the domain is cleaned up as normal;
+# "restart", meaning that a new domain is started in place of the old
+# one;
+# "preserve", meaning that no clean-up is done until the domain is
+# manually destroyed (using xm destroy, for example); or
+# "rename-restart", meaning that the old domain is not cleaned up, but is
+# renamed and a new domain started in its place.
#
# The default is
#
diff -r 468ad17f9970 -r 244f1aa98d30 tools/examples/xmexample2
--- a/tools/examples/xmexample2 Fri Sep 30 16:05:08 2005
+++ b/tools/examples/xmexample2 Fri Sep 30 16:10:20 2005
@@ -129,10 +129,15 @@
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
-# may specify "destroy", meaning that the domain is cleaned up as normal,
-# "restart", meaning that a new domain is started in place of the old one, or
-# "preserve", meaning that no clean-up is done until the domain is manually
-# destroyed (using xm destroy, for example).
+# may specify:
+#
+# "destroy", meaning that the domain is cleaned up as normal;
+# "restart", meaning that a new domain is started in place of the old
+# one;
+# "preserve", meaning that no clean-up is done until the domain is
+# manually destroyed (using xm destroy, for example); or
+# "rename-restart", meaning that the old domain is not cleaned up, but is
+# renamed and a new domain started in its place.
#
# The default is
#
diff -r 468ad17f9970 -r 244f1aa98d30 tools/examples/xmexample3
--- a/tools/examples/xmexample3 Fri Sep 30 16:05:08 2005
+++ b/tools/examples/xmexample3 Fri Sep 30 16:10:20 2005
@@ -126,10 +126,15 @@
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
-# may specify "destroy", meaning that the domain is cleaned up as normal,
-# "restart", meaning that a new domain is started in place of the old one, or
-# "preserve", meaning that no clean-up is done until the domain is manually
-# destroyed (using xm destroy, for example).
+# may specify:
+#
+# "destroy", meaning that the domain is cleaned up as normal;
+# "restart", meaning that a new domain is started in place of the old
+# one;
+# "preserve", meaning that no clean-up is done until the domain is
+# manually destroyed (using xm destroy, for example); or
+# "rename-restart", meaning that the old domain is not cleaned up, but is
+# renamed and a new domain started in its place.
#
# The default is
#
diff -r 468ad17f9970 -r 244f1aa98d30 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Sep 30 16:05:08 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Fri Sep 30 16:10:20 2005
@@ -70,7 +70,8 @@
restart_modes = [
"restart",
"destroy",
- "preserve"
+ "preserve",
+ "rename-restart"
]
STATE_VM_OK = "ok"
@@ -653,21 +654,26 @@
restart_reason = 'crash'
elif xeninfo['shutdown']:
- reason = shutdown_reason(xeninfo['shutdown_reason'])
-
- log.info('Domain has shutdown: name=%s id=%d reason=%s.',
- self.info['name'], self.domid, reason)
-
- self.clearRestart()
-
- if reason == 'suspend':
- self.state_set(STATE_VM_SUSPENDED)
- # Don't destroy the domain. XendCheckpoint will do this
- # once it has finished.
- elif reason in ['poweroff', 'reboot']:
- restart_reason = reason
+ if self.readDom('xend/shutdown'):
+ # We've seen this shutdown already, but we are preserving
+ # the domain for debugging. Leave it alone.
+ pass
else:
- self.destroy()
+ reason = shutdown_reason(xeninfo['shutdown_reason'])
+
+ log.info('Domain has shutdown: name=%s id=%d reason=%s.',
+ self.info['name'], self.domid, reason)
+
+ self.clearRestart()
+
+ if reason == 'suspend':
+ self.state_set(STATE_VM_SUSPENDED)
+ # Don't destroy the domain. XendCheckpoint will do
+ # this once it has finished.
+ elif reason in ['poweroff', 'reboot']:
+ restart_reason = reason
+ else:
+ self.destroy()
else:
# Domain is alive. If we are shutting it down, then check
@@ -702,6 +708,8 @@
self.storeDom('xend/shutdown_start_time', time.time())
+ ## private:
+
def clearRestart(self):
self.removeDom("xend/shutdown_start_time")
@@ -709,14 +717,19 @@
def maybeRestart(self, reason):
# Dispatch to the correct method based upon the configured on_{reason}
# behaviour.
- {"destroy" : self.destroy,
- "restart" : self.restart,
- "preserve" : self.preserve}[self.info['on_' + reason]]()
+ {"destroy" : self.destroy,
+ "restart" : self.restart,
+ "preserve" : self.preserve,
+ "rename-restart" : self.renameRestart}[self.info['on_' + reason]]()
def preserve(self):
log.info("Preserving dead domain %s (%d).", self.info['name'],
self.domid)
+
+
+ def renameRestart(self):
+ self.restart(True)
def dumpCore(self):
@@ -757,6 +770,8 @@
self.closeChannel(self.console_channel, "console/port")
self.console_channel = None
+
+ ## public:
def setConsoleRef(self, ref):
self.console_mfn = ref
@@ -973,6 +988,10 @@
try:
self.dompath = DOMROOT + str(self.domid)
+ # Ensure that the domain entry is clean. This prevents a stale
+ # shutdown_start_time from killing the domain, for example.
+ self.removeDom()
+
self.initDomain()
self.construct_image()
self.configure()
@@ -1082,6 +1101,8 @@
except Exception:
log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
+
+ ## private:
def is_terminated(self):
"""Check if a domain has been terminated.
@@ -1142,7 +1163,7 @@
log.error("Recovering from above exception.")
self.storeDom(path, ret.port1)
return ret
-
+
def create_channel(self):
"""Create the channels to the domain.
"""
@@ -1162,6 +1183,9 @@
self.create_configured_devices()
if self.image:
self.image.createDeviceModel()
+
+
+ ## public:
def device_create(self, dev_config):
"""Create a new device.
@@ -1183,21 +1207,7 @@
self.configureDevice(deviceClass, devid, dev_config)
- def restart_needed(self, reason):
- """Determine if the vm needs to be restarted when shutdown
- for the given reason.
-
- @param reason: shutdown reason
- @return True if needs restart, False otherwise
- """
- if self.info['restart_mode'] == RESTART_NEVER:
- return False
- if self.info['restart_mode'] == RESTART_ALWAYS:
- return True
- if self.info['restart_mode'] == RESTART_ONREBOOT:
- return reason == 'reboot'
- return False
-
+ ## private:
def restart_check(self):
"""Check if domain restart is OK.
@@ -1216,14 +1226,16 @@
self.restart_count += 1
- def restart(self):
- """Restart the domain after it has exited. """
+ 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()
-
- self.cleanupDomain()
if self.readVm('xend/restart_in_progress'):
log.error('Xend failed during restart of domain %d. '
@@ -1235,7 +1247,12 @@
self.writeVm('xend/restart_in_progress', 'True')
try:
- self.destroy()
+ if rename:
+ self.preserveShutdownDomain()
+ else:
+ self.cleanupDomain()
+ self.destroy()
+
try:
xd = get_component('xen.xend.XendDomain')
xd.domain_unpause(xd.domain_create(config).getDomid())
@@ -1246,6 +1263,37 @@
# self.configure_bootloader()
# self.exportToDB()
+
+
+ def preserveShutdownDomain(self):
+ """Preserve a domain that has been shut down, by giving it a new UUID,
+ cloning the VM details, and giving it a new name. This allows us to
+ keep this domain for debugging, but restart a new one in its place
+ preserving the restart semantics (name and UUID preserved).
+ """
+
+ new_name = self.generateShutdownName()
+ new_uuid = getUuid()
+ log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
+ self.info['name'], self.domid, self.uuid, new_name, new_uuid)
+ self.release_devices()
+ self.info['name'] = new_name
+ self.uuid = new_uuid
+ self.vmpath = VMROOT + new_uuid
+ self.storeVmDetails()
+ self.storeDom('vm', self.vmpath)
+ self.storeDom('xend/shutdown', 'True')
+
+
+ def generateShutdownName(self):
+ n = 1
+ while True:
+ name = "%s-%d" % (self.info['name'], n)
+ try:
+ self.check_name(name)
+ return name
+ except VmError:
+ n += 1
def configure_bootloader(self):
diff -r 468ad17f9970 -r 244f1aa98d30 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Fri Sep 30 16:05:08 2005
+++ b/tools/python/xen/xm/create.py Fri Sep 30 16:10:20 2005
@@ -163,10 +163,46 @@
gopts.var('restart', val='onreboot|always|never',
fn=set_value, default=None,
- use="""Whether the domain should be restarted on exit.
+ use="""Deprecated. Use on_poweroff, on_reboot, and on_crash
+ instead.
+
+ Whether the domain should be restarted on exit.
- onreboot: restart on exit with shutdown code reboot
- always: always restart on exit, ignore exit code
- never: never restart on exit, ignore exit code""")
+
+gopts.var('on_poweroff', val='destroy|restart|preserve|rename-restart',
+ fn=set_value, default=None,
+ use="""Behaviour when a domain exits with reason 'poweroff'.
+ - destroy: the domain is cleaned up as normal;
+ - restart: a new domain is started in place of the old one;
+ - preserve: no clean-up is done until the domain is manually
+ destroyed (using xm destroy, for example);
+ - rename-restart: the old domain is not cleaned up, but is
+ renamed and a new domain started in its place.
+ """)
+
+gopts.var('on_reboot', val='destroy|restart|preserve|rename-restart',
+ fn=set_value, default=None,
+ use="""Behaviour when a domain exits with reason 'reboot'.
+ - destroy: the domain is cleaned up as normal;
+ - restart: a new domain is started in place of the old one;
+ - preserve: no clean-up is done until the domain is manually
+ destroyed (using xm destroy, for example);
+ - rename-restart: the old domain is not cleaned up, but is
+ renamed and a new domain started in its place.
+ """)
+
+gopts.var('on_crash', val='destroy|restart|preserve|rename-restart',
+ fn=set_value, default=None,
+ use="""Behaviour when a domain exits with reason 'crash'.
+ - destroy: the domain is cleaned up as normal;
+ - restart: a new domain is started in place of the old one;
+ - preserve: no clean-up is done until the domain is manually
+ destroyed (using xm destroy, for example);
+ - rename-restart: the old domain is not cleaned up, but is
+ renamed and a new domain started in its place.
+ """)
gopts.var('blkif', val='no|yes',
fn=set_bool, default=0,
@@ -536,6 +572,12 @@
config.append(['backend', ['tpmif']])
if vals.restart:
config.append(['restart', vals.restart])
+ if vals.on_poweroff:
+ config.append(['on_poweroff', vals.on_poweroff])
+ if vals.on_reboot:
+ config.append(['on_reboot', vals.on_reboot])
+ if vals.on_crash:
+ config.append(['on_crash', vals.on_crash])
if vals.bootloader:
config.append(['bootloader', vals.bootloader])
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|