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

[Xen-changelog] [xen-unstable] xm, xend: Add new option "change_home_server" to xm migrate



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1255507763 -3600
# Node ID 18758847bf313a191731278c41af7519dfa85ecf
# Parent  5e2574c2aacad2f124be9d46a45f0e34364b100d
xm,xend: Add new option "change_home_server" to xm migrate

This patch adds a new option to xm migrate command.  A concept of the
option is inspired from XenServer/XenCenter.  The concept is "Change
home server (affinity)."  The option name is "change_home_server."

Currently, a config.sxp file of a managed domain is not migrated to a
destination server even if the migration of the managed domain
succeeds.  The config.sxp file is kept in a source server.

By the patch, the config.sxp file is migrated with the managed domain.
The config.sxp file is unregistered from the source server, then the
config.sxp file is registered to the destination server.

BTW, should the config.sxp file be always migrated without the option?
If the managed domain is migrated without the option, the managed
domains exist on both the source server and the destination server.
(Of course, the managed domain on the source server is "halted" state,
and the managed domain on the destination server is "running" state.)
Is it good that the managed domains with a same UUID exist on both
servers?  (In the patch, I added the option for compatible.)

Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
---
 tools/python/xen/xend/XendConfig.py     |    4 
 tools/python/xen/xend/XendDomain.py     |  242 +++++++++++++++++---------------
 tools/python/xen/xend/XendDomainInfo.py |   13 +
 tools/python/xen/xm/migrate.py          |    7 
 4 files changed, 157 insertions(+), 109 deletions(-)

diff -r 5e2574c2aaca -r 18758847bf31 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Oct 14 09:08:16 2009 +0100
+++ b/tools/python/xen/xend/XendConfig.py       Wed Oct 14 09:09:23 2009 +0100
@@ -957,6 +957,7 @@ class XendConfig(dict):
         _set_cfg_if_exists('on_xend_stop')
         _set_cfg_if_exists('on_xend_start')
         _set_cfg_if_exists('vcpu_avail')
+        _set_cfg_if_exists('change_home_server')
         
         # Parse and store runtime configuration 
         _set_cfg_if_exists('start_time')
@@ -1157,6 +1158,9 @@ class XendConfig(dict):
             self.cpuid_to_sxp(sxpr, 'cpuid')
         if 'cpuid_check' in self:
             self.cpuid_to_sxp(sxpr, 'cpuid_check')
+
+        if self.has_key('change_home_server'):
+            sxpr.append(['change_home_server', self['change_home_server']])
 
         log.debug(sxpr)
 
diff -r 5e2574c2aaca -r 18758847bf31 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Wed Oct 14 09:08:16 2009 +0100
+++ b/tools/python/xen/xend/XendDomain.py       Wed Oct 14 09:09:23 2009 +0100
@@ -1156,7 +1156,21 @@ class XendDomain:
             self.policy_lock.acquire_reader()
 
             try:
-                return XendCheckpoint.restore(self, fd, paused=paused, 
relocating=relocating)
+                dominfo = XendCheckpoint.restore(self, fd, paused=paused, 
relocating=relocating)
+                if relocating and \
+                   dominfo.info.has_key("change_home_server"):
+                    chs = (dominfo.info["change_home_server"] == "True")
+                    dominfo.setChangeHomeServer(None)
+                    if chs:
+                        self.domains_lock.acquire()
+                        try:
+                            log.debug("Migrating new managed domain: %s: %s" %
+                                      (dominfo.getName(), dominfo.get_uuid()))
+                            self._managed_domain_register(dominfo)
+                            self.managed_config_save(dominfo)
+                        finally:
+                            self.domains_lock.release()
+                return dominfo
             except XendError, e:
                 log.exception("Restore failed")
                 raise
@@ -1298,7 +1312,8 @@ class XendDomain:
 
         return val       
 
-    def domain_migrate(self, domid, dst, live=False, port=0, node=-1, 
ssl=None):
+    def domain_migrate(self, domid, dst, live=False, port=0, node=-1, 
ssl=None,\
+                       chs=False):
         """Start domain migration.
         
         @param domid: Domain ID or Name
@@ -1313,6 +1328,8 @@ class XendDomain:
         @type node: int
         @keyword ssl: use ssl connection
         @type ssl: bool
+        @keyword chs: change home server for managed domain
+        @type chs: bool
         @rtype: None
         @raise XendError: Failed to migrate
         @raise XendInvalidDomain: Domain is not valid
@@ -1328,6 +1345,8 @@ class XendDomain:
             raise VMBadState("Domain is not running",
                              POWER_STATE_NAMES[DOM_STATE_RUNNING],
                              POWER_STATE_NAMES[dominfo._stateGet()])
+        if chs and not self.is_domain_managed(dominfo):
+            raise XendError("Domain is not a managed domain")
 
         """ The following call may raise a XendError exception """
         dominfo.testMigrateDevices(True, dst)
@@ -1339,120 +1358,131 @@ class XendDomain:
         if ssl is None:
             ssl = xoptions.get_xend_relocation_ssl()
 
-        if ssl:
-            from OpenSSL import SSL
-            from xen.web import connection
-            if port == 0:
-                port = xoptions.get_xend_relocation_ssl_port()
-            try:
-                ctx = SSL.Context(SSL.SSLv23_METHOD)
-                sock = SSL.Connection(ctx,
-                           socket.socket(socket.AF_INET, socket.SOCK_STREAM))
-                sock.set_connect_state()
-                sock.connect((dst, port))
-                sock.send("sslreceive\n")
-                sock.recv(80)
-            except SSL.Error, err:
-                raise XendError("SSL error: %s" % err)
-            except socket.error, err:
-                raise XendError("can't connect: %s" % err)
-
-            p2cread, p2cwrite = os.pipe()
-            
threading.Thread(target=connection.SSLSocketServerConnection.fd2send,
-                             args=(sock, p2cread)).start()
-
-            try:
+        try:
+            dominfo.setChangeHomeServer(chs)
+            if ssl:
+                self._domain_migrate_by_ssl(dominfo, dst, live, port, node)
+            else:
+                self._domain_migrate(dominfo, dst, live, port, node)
+        except:
+            dominfo.setChangeHomeServer(None)
+            raise
+
+    def _domain_migrate_by_ssl(self, dominfo, dst, live, port, node):
+        from OpenSSL import SSL
+        from xen.web import connection
+        if port == 0:
+            port = xoptions.get_xend_relocation_ssl_port()
+        try:
+            ctx = SSL.Context(SSL.SSLv23_METHOD)
+            sock = SSL.Connection(ctx,
+                       socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+            sock.set_connect_state()
+            sock.connect((dst, port))
+            sock.send("sslreceive\n")
+            sock.recv(80)
+        except SSL.Error, err:
+            raise XendError("SSL error: %s" % err)
+        except socket.error, err:
+            raise XendError("can't connect: %s" % err)
+
+        p2cread, p2cwrite = os.pipe()
+        threading.Thread(target=connection.SSLSocketServerConnection.fd2send,
+                         args=(sock, p2cread)).start()
+
+        try:
+            try:
+                XendCheckpoint.save(p2cwrite, dominfo, True, live, dst,
+                                    node=node)
+            except Exception, ex:
+                m_dsterr = None
                 try:
-                    XendCheckpoint.save(p2cwrite, dominfo, True, live, dst,
-                                        node=node)
-                except Exception, ex:
-                    m_dsterr = None
-                    try:
-                        sock.settimeout(3.0)
-                        dsterr = sock.recv(1024)
-                        sock.settimeout(None)
-                        if dsterr:
-                            # See send_error@xxxxxxxxxxxx If an error occurred
-                            # in a destination side, an error message with the
-                            # following form is returned from the destination
-                            # side.
-                            m_dsterr = \
-                                
re.match(r"^\(err\s\(type\s(.+)\)\s\(value\s'(.+)'\)\)", dsterr)
-                    except:
-                        # Probably socket.timeout exception occurred.
-                        # Ignore the exception because it has nothing to do 
with
-                        # an exception of XendCheckpoint.save.
-                        pass
-
-                    if m_dsterr:
-                        raise XendError("%s (from %s)" % (m_dsterr.group(2), 
dst))
-                    raise
-            finally:
-                try:
-                    sock.shutdown(2)
+                    sock.settimeout(3.0)
+                    dsterr = sock.recv(1024)
+                    sock.settimeout(None)
+                    if dsterr:
+                        # See send_error@xxxxxxxxxxxx If an error occurred
+                        # in a destination side, an error message with the
+                        # following form is returned from the destination
+                        # side.
+                        m_dsterr = \
+                            
re.match(r"^\(err\s\(type\s(.+)\)\s\(value\s'(.+)'\)\)", dsterr)
                 except:
-                    # Probably the socket is already disconnected by sock.close
-                    # in the destination side.
+                    # Probably socket.timeout exception occurred.
                     # Ignore the exception because it has nothing to do with
                     # an exception of XendCheckpoint.save.
                     pass
-                sock.close()
-
-            os.close(p2cread)
-            os.close(p2cwrite)
-        else:
-            if port == 0:
-                port = xoptions.get_xend_relocation_port()
-            try:
-                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-                # When connecting to our ssl enabled relocation server using a
-                # plain socket, send will success but recv will block. Add a
-                # 30 seconds timeout to raise a socket.timeout exception to
-                # inform the client.
-                sock.settimeout(30.0)
-                sock.connect((dst, port))
-                sock.send("receive\n")
-                sock.recv(80)
-                sock.settimeout(None)
-            except socket.error, err:
-                raise XendError("can't connect: %s" % err)
-
-            try:
+
+                if m_dsterr:
+                    raise XendError("%s (from %s)" % (m_dsterr.group(2), dst))
+                raise
+        finally:
+            try:
+                sock.shutdown(2)
+            except:
+                # Probably the socket is already disconnected by sock.close
+                # in the destination side.
+                # Ignore the exception because it has nothing to do with
+                # an exception of XendCheckpoint.save.
+                pass
+            sock.close()
+
+        os.close(p2cread)
+        os.close(p2cwrite)
+
+    def _domain_migrate(self, dominfo, dst, live, port, node):
+        if port == 0:
+            port = xoptions.get_xend_relocation_port()
+        try:
+            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            # When connecting to our ssl enabled relocation server using a
+            # plain socket, send will success but recv will block. Add a
+            # 30 seconds timeout to raise a socket.timeout exception to
+            # inform the client.
+            sock.settimeout(30.0)
+            sock.connect((dst, port))
+            sock.send("receive\n")
+            sock.recv(80)
+            sock.settimeout(None)
+        except socket.error, err:
+            raise XendError("can't connect: %s" % err)
+
+        try:
+            try:
+                XendCheckpoint.save(sock.fileno(), dominfo, True, live,
+                                    dst, node=node)
+            except Exception, ex:
+                m_dsterr = None
                 try:
-                    XendCheckpoint.save(sock.fileno(), dominfo, True, live,
-                                        dst, node=node)
-                except Exception, ex:
-                    m_dsterr = None
-                    try:
-                        sock.settimeout(3.0)
-                        dsterr = sock.recv(1024)
-                        sock.settimeout(None)
-                        if dsterr:
-                            # See send_error@xxxxxxxxxxxx If an error occurred
-                            # in a destination side, an error message with the
-                            # following form is returned from the destination
-                            # side.
-                            m_dsterr = \
-                                
re.match(r"^\(err\s\(type\s(.+)\)\s\(value\s'(.+)'\)\)", dsterr)
-                    except:
-                        # Probably socket.timeout exception occurred.
-                        # Ignore the exception because it has nothing to do 
with
-                        # an exception of XendCheckpoint.save.
-                        pass
-
-                    if m_dsterr:
-                        raise XendError("%s (from %s)" % (m_dsterr.group(2), 
dst))
-                    raise
-            finally:
-                try:
-                    sock.shutdown(2)
+                    sock.settimeout(3.0)
+                    dsterr = sock.recv(1024)
+                    sock.settimeout(None)
+                    if dsterr:
+                        # See send_error@xxxxxxxxxxxx If an error occurred
+                        # in a destination side, an error message with the
+                        # following form is returned from the destination
+                        # side.
+                        m_dsterr = \
+                            
re.match(r"^\(err\s\(type\s(.+)\)\s\(value\s'(.+)'\)\)", dsterr)
                 except:
-                    # Probably the socket is already disconnected by sock.close
-                    # in the destination side.
+                    # Probably socket.timeout exception occurred.
                     # Ignore the exception because it has nothing to do with
                     # an exception of XendCheckpoint.save.
                     pass
-                sock.close()
+
+                if m_dsterr:
+                    raise XendError("%s (from %s)" % (m_dsterr.group(2), dst))
+                raise
+        finally:
+            try:
+                sock.shutdown(2)
+            except:
+                # Probably the socket is already disconnected by sock.close
+                # in the destination side.
+                # Ignore the exception because it has nothing to do with
+                # an exception of XendCheckpoint.save.
+                pass
+            sock.close()
 
     def domain_save(self, domid, dst, checkpoint=False):
         """Start saving a domain to file.
diff -r 5e2574c2aaca -r 18758847bf31 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Oct 14 09:08:16 2009 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Oct 14 09:09:23 2009 +0100
@@ -2364,6 +2364,13 @@ class XendDomainInfo:
         return self.getDeviceController(deviceClass).recover_migrate(
                      deviceConfig, network, dst, step, domName)
 
+    def setChangeHomeServer(self, chs):
+        if chs is not None:
+            self.info['change_home_server'] = bool(chs)
+        else:
+            if self.info.has_key('change_home_server'):
+                del self.info['change_home_server']
+
 
     ## private:
 
@@ -2870,8 +2877,10 @@ class XendDomainInfo:
         self._cleanup_phantom_devs(paths)
         self._cleanupVm()
 
-        if "transient" in self.info["other_config"] \
-           and bool(self.info["other_config"]["transient"]):
+        if ("transient" in self.info["other_config"] and \
+            bool(self.info["other_config"]["transient"])) or \
+           ("change_home_server" in self.info and \
+            bool(self.info["change_home_server"])):
             XendDomain.instance().domain_delete_by_dominfo(self)
 
 
diff -r 5e2574c2aaca -r 18758847bf31 tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py    Wed Oct 14 09:08:16 2009 +0100
+++ b/tools/python/xen/xm/migrate.py    Wed Oct 14 09:09:23 2009 +0100
@@ -51,6 +51,10 @@ gopts.opt('ssl', short='s',
           fn=set_true, default=None,
           use="Use ssl connection for migration.")
 
+gopts.opt('change_home_server', short='c',
+          fn=set_true, default=0,
+          use="Change home server for managed domains.")
+
 def help():
     return str(gopts)
     
@@ -78,4 +82,5 @@ def main(argv):
         server.xend.domain.migrate(dom, dst, opts.vals.live,
                                    opts.vals.port,
                                    opts.vals.node,
-                                   opts.vals.ssl)
+                                   opts.vals.ssl,
+                                   opts.vals.change_home_server)

_______________________________________________
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®.