[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Add the config file parsing for the on_{poweroff, reboot, crash} options, so that



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.