From mboxrd@z Thu Jan 1 00:00:00 1970 From: Michal Novotny Subject: [PATCH] Fix restore handling checks Date: Mon, 21 Jun 2010 18:30:31 +0200 Message-ID: <4C1F93A7.9070505@redhat.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------010103090803070305040200" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: "'xen-devel@lists.xensource.com'" List-Id: xen-devel@lists.xenproject.org This is a multi-part message in MIME format. --------------010103090803070305040200 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, this is the patch to fix restore handling to implement some more checks to support more checks than for UUID and name duplicity. This patch basically disallows the migration/restore of IDE drives with the read-only flag since this is not supported according to the ATAPI/IDE specifications so we should disallow this for both domain creation and domain migration/restore. This patch implements it for both create and restore/migrate functionality. Also, the check whether the host machine does have enough memory available for the guest has been implemented which can be the real issue when you try to migrate a guest from one machine to another that is not having enough memory for this guest. The guest memory gets transferred but it fails to run so it's not running on either of those machines (i.e. domain is not on the destination nor source host machine). I did try it with restore functionality now since I've been able to make it working for save once so I'm currently using one save image for the testing but unfortunately I'm having many issues with the common migration and save functionality since I've been able to make it working once to save it correctly. Fortunately the restores for this one particular save image is working fine. I was also thinking about 2 concurrent migrations to the guest and/or save with the concurrent migration and it should be the issue (although it's not been tested because of reasons described above) since the domain gets created and it's available in the XendDomain list (i.e. xc.domain_getinfo() list) so it shouldn't be an issue here. Michal Signed-off-by: Michal Novotny -- Michal Novotny, RHCE Virtualization Team (xen userspace), Red Hat --------------010103090803070305040200 Content-Type: text/x-patch; name="xen-fix-restore-handling-for-ide-drives-and-memory.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="xen-fix-restore-handling-for-ide-drives-and-memory.patch" diff -r 31708477f0a9 tools/python/xen/xend/XendCheckpoint.py --- a/tools/python/xen/xend/XendCheckpoint.py Mon Jun 21 09:59:10 2010 +0100 +++ b/tools/python/xen/xend/XendCheckpoint.py Mon Jun 21 18:23:46 2010 +0200 @@ -64,6 +64,70 @@ list.insert (i+1, value) return +def get_avail_memory(): + """Get available memory for new guest creation (in KiB, for restore)""" + from xen.xend import XendOptions + + # First get total memory in KiB + xc = xen.lowlevel.xc.xc() + info = xc.domain_getinfo() + total_mem = xc.physinfo()['total_memory'] + del xc + + # Count memory of all running guests in KiB + mem_used = 0L + for x in info: + if x['domid'] != 0: + mem_used += x['mem_kb'] + + # Get minimal memory for dom0 and convert to KiB + min_mem = XendOptions.instance().get_dom0_min_mem() * 1024 + + return total_mem - mem_used - min_mem + +def check_for_restore_bail(msg): + raise VmError("Cannot restore: %s" % msg) + +def check_for_enough_mem(val): + mem_avail = int(get_avail_memory() / 1024) + log.debug("Available memory: %s MiB, guest requires: %s MiB" % (mem_avail, val)) + return val > mem_avail + +def check_for_restore_is_hvm(cfg): + for item in cfg: + if (type(item) == list): + if item[0] == 'image': + return type(item[1]) == list and item[1][0] == 'hvm' + +def check_for_restore_hvm_have_readonly_ide(cfg): + """Check the configuration for read-only IDE devices + Fail if such a device is found.""" + is_ide = True + if type(cfg) == list and cfg[0] in ('tap', 'vbd'): + for p in cfg: + if (type(p) != str): + if p[0] == 'dev': + is_ide = (p[1].find('hd') >= 0) + if p[0] == 'mode' and is_ide: + if p[1] == 'r': + return True + return False + +def check_for_restore(cfg): + is_hvm = check_for_restore_is_hvm(cfg) + name = None + for item in cfg: + if (type(item) == list): + if item[0] == 'name': + name = item[1] + # Check for enough memory to create the guest + if item[0] == 'memory': + if not check_for_enough_mem(item[1]): + check_for_restore_bail('Host machine doesn\'t have enough memory for %s' % name) + # We disable read-only IDE drives only for HVM guests + if item[0] == 'device' and is_hvm: + if check_for_restore_hvm_have_readonly_ide(item[1]): + check_for_restore_bail('HVM domains cannot be using read-only IDE drives') def save(fd, dominfo, network, live, dst, checkpoint=False, node=-1): from xen.xend import XendDomain @@ -220,6 +284,7 @@ othervm = xd.domain_lookup_nr(domconfig["uuid"]) if othervm is not None and othervm.domid is not None: raise VmError("Domain '%s' already exists with ID '%d'" % (domconfig["name_label"], othervm.domid)) + check_for_restore(vmconfig) if dominfo: dominfo.resume() diff -r 31708477f0a9 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jun 21 09:59:10 2010 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Jun 21 18:23:46 2010 +0200 @@ -82,6 +82,31 @@ log = logging.getLogger("xend.XendDomainInfo") #log.setLevel(logging.TRACE) +def cfg_is_hvm(cfg): + for item in cfg: + if (type(item) == list): + if item[0] == 'image': + return type(item[1]) == list and item[1][0] == 'hvm' + +def cfg_hvm_have_readonly_ide_devices(cfg): + """Check the configuration for read-only IDE devices + Fail if such a device is found.""" + if not cfg_is_hvm(cfg): + return False + + is_ide = True + for item in cfg: + if (type(item) == list): + if item[0] == 'device': + if type(item[1]) == list and item[1][0] in ('tap', 'vbd'): + for p in item[1]: + if (type(p) != str): + if p[0] == 'dev': + is_ide = (p[1].find('hd') >= 0) + if p[0] == 'mode' and is_ide: + if p[1] == 'r': + return True + return False def create(config): """Creates and start a VM using the supplied configuration. @@ -100,6 +125,10 @@ othervm = XendDomain.instance().domain_lookup_nr(domconfig["uuid"]) if othervm is not None and othervm.domid is not None: raise VmError("Domain '%s' already exists with ID '%d'" % (domconfig["name_label"], othervm.domid)) + + if cfg_hvm_have_readonly_ide_devices(config): + raise VmError("HVM domains cannot be using read-only IDE drives") + log.debug("XendDomainInfo.create(%s)", scrub_password(config)) vm = XendDomainInfo(domconfig) try: --------------010103090803070305040200 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --------------010103090803070305040200--