diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-10-14 09:09:23 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-10-14 09:09:23 +0100 |
commit | b1fd365cece2833c767ee8f96c421ee32e467af5 (patch) | |
tree | 9697a4c1ff1bb94d6d192b772daa3853149f5b1f | |
parent | 11a92ae1f0692109990da8e34e945c298afb4c6f (diff) | |
download | xen-b1fd365cece2833c767ee8f96c421ee32e467af5.tar.gz xen-b1fd365cece2833c767ee8f96c421ee32e467af5.tar.bz2 xen-b1fd365cece2833c767ee8f96c421ee32e467af5.zip |
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@jp.fujitsu.com>
-rw-r--r-- | tools/python/xen/xend/XendConfig.py | 4 | ||||
-rw-r--r-- | tools/python/xen/xend/XendDomain.py | 230 | ||||
-rw-r--r-- | tools/python/xen/xend/XendDomainInfo.py | 13 | ||||
-rw-r--r-- | tools/python/xen/xm/migrate.py | 7 |
4 files changed, 151 insertions, 103 deletions
diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 50b7afad41..b94175cd47 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -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') @@ -1158,6 +1159,9 @@ class XendConfig(dict): 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) return sxpr diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 336e5bc8b2..9c8516de27 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -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: + 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@relocate.py. 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@relocate.py. 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() + if m_dsterr: + raise XendError("%s (from %s)" % (m_dsterr.group(2), dst)) + raise + finally: 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) + 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@relocate.py. 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@relocate.py. 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 --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index fb76b47ca6..5e9f0fe6e1 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -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 --git a/tools/python/xen/xm/migrate.py b/tools/python/xen/xm/migrate.py index ee990e0b4d..220f09198a 100644 --- a/tools/python/xen/xm/migrate.py +++ b/tools/python/xen/xm/migrate.py @@ -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) |