aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-10-14 09:09:23 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-10-14 09:09:23 +0100
commitb1fd365cece2833c767ee8f96c421ee32e467af5 (patch)
tree9697a4c1ff1bb94d6d192b772daa3853149f5b1f
parent11a92ae1f0692109990da8e34e945c298afb4c6f (diff)
downloadxen-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.py4
-rw-r--r--tools/python/xen/xend/XendDomain.py230
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py13
-rw-r--r--tools/python/xen/xm/migrate.py7
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)