WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Fix the handling of VCPUs, specifically wrt the broken V

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix the handling of VCPUs, specifically wrt the broken VCPU hotplugging, bug
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 05 Oct 2005 17:16:11 +0000
Delivery-date: Wed, 05 Oct 2005 17:13:45 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User emellor@ewan
# Node ID 6f71824a45c19e860a3655dd8e76a83e047c84d2
# Parent  6e5463aec499333e9d4f91f612981aeb1f576445
Fix the handling of VCPUs, specifically wrt the broken VCPU hotplugging, bug
#280.  The cpu/<id>/availability paths had moved into /vm, but that is not
easily accessible by the hotplugging driver, so I have created a /vm entry
called vcpu_avail, so that the setting migrates along with the domain, and
moved the cpu/<id> ones back to /local/domain.

Don't try and destroy the domain twice if it fails within construct.  This
wasn't harming anything, but there's no need.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r 6e5463aec499 -r 6f71824a45c1 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Oct  5 16:48:36 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Oct  5 17:06:42 2005
@@ -111,6 +111,8 @@
 ROUNDTRIPPING_CONFIG_ENTRIES = [
         ('name',         str),
         ('ssidref',      int),
+        ('vcpus',        int),
+        ('vcpu_avail',   int),
         ('cpu_weight',   float),
         ('bootloader',   str),
         ('on_poweroff',  str),
@@ -119,6 +121,27 @@
     ]
 
 
+#
+# There are a number of CPU-related fields:
+#
+#   vcpus:       the number of virtual CPUs this domain is configured to use.
+#   vcpu_avail:  a bitmap telling the guest domain whether it may use each of
+#                its VCPUs.  This is translated to
+#                <dompath>/cpu/<id>/availability = {online,offline} for use
+#                by the guest domain.
+#   vcpu_to_cpu: the current mapping between virtual CPUs and the physical
+#                CPU it is using.
+#   cpumap:      a list of bitmaps, one for each VCPU, giving the physical
+#                CPUs that that VCPU may use.
+#   cpu:         a configuration setting requesting that VCPU 0 is pinned to
+#                the specified physical CPU.
+#
+# vcpus and vcpu_avail settings persist with the VM (i.e. they are persistent
+# across save, restore, migrate, and restart).  The other settings are only
+# specific to the domain, so are lost when the VM moves.
+#
+
+
 def create(config):
     """Create a VM from a configuration.
 
@@ -134,6 +157,7 @@
         vm.refreshShutdown()
         return vm
     except:
+        log.exception('Domain construction failed')
         vm.destroy()
         raise
 
@@ -200,7 +224,7 @@
         raise VmError('Invalid ssidref in config: %s' % exn)
 
     domid = xc.domain_create(ssidref = ssidref)
-    if domid <= 0:
+    if domid < 0:
         raise VmError('Creating domain failed for restore')
     try:
         vm = XendDomainInfo(uuid, parseConfig(config), domid)
@@ -240,12 +264,12 @@
     for e in ROUNDTRIPPING_CONFIG_ENTRIES:
         result[e[0]] = get_cfg(e[0], e[1])
 
-    result['memory']       = get_cfg('memory',     int)
-    result['mem_kb']       = get_cfg('mem_kb',     int)
-    result['maxmem']       = get_cfg('maxmem',     int)
-    result['maxmem_kb']    = get_cfg('maxmem_kb',  int)
-    result['cpu']          = get_cfg('cpu',        int)
-    result['image']        = get_cfg('image')
+    result['memory']    = get_cfg('memory',    int)
+    result['mem_kb']    = get_cfg('mem_kb',    int)
+    result['maxmem']    = get_cfg('maxmem',    int)
+    result['maxmem_kb'] = get_cfg('maxmem_kb', int)
+    result['cpu']       = get_cfg('cpu',       int)
+    result['image']     = get_cfg('image')
 
     try:
         if result['image']:
@@ -338,7 +362,7 @@
         self.uuid = uuid
         self.info = info
 
-        if domid:
+        if domid is not None:
             self.domid = domid
         elif 'dom' in info:
             self.domid = int(info['dom'])
@@ -382,6 +406,8 @@
                   ("on_reboot",    str),
                   ("on_crash",     str),
                   ("image",        str),
+                  ("vcpus",        int),
+                  ("vcpu_avail",   int),
                   ("start_time", float))
 
         from_store = self.gatherVm(*params)
@@ -393,13 +419,13 @@
             devconfig = self.getDeviceConfigurations(c)
             if devconfig:
                 device.extend(map(lambda x: (c, x), devconfig))
-
         useIfNeeded('device', device)
 
 
     def validateInfo(self):
         """Validate and normalise the info block.  This has either been parsed
-        by parseConfig, or received from xc through recreate.
+        by parseConfig, or received from xc through recreate and augmented by
+        the current store contents.
         """
         def defaultInfo(name, val):
             if not self.infoIsSet(name):
@@ -413,6 +439,8 @@
             defaultInfo('on_crash',     lambda: "restart")
             defaultInfo('cpu',          lambda: None)
             defaultInfo('cpu_weight',   lambda: 1.0)
+            defaultInfo('vcpus',        lambda: 1)
+            defaultInfo('vcpu_avail',   lambda: (1 << self.info['vcpus']) - 1)
             defaultInfo('bootloader',   lambda: None)
             defaultInfo('backend',      lambda: [])
             defaultInfo('device',       lambda: [])
@@ -499,12 +527,6 @@
                     raise VmError('invalid restart event: %s = %s' %
                                   (event, str(self.info[event])))
 
-            if 'cpumap' not in self.info:
-                if [self.info['vcpus'] == 1]:
-                    self.info['cpumap'] = [1];
-                else:
-                    raise VmError('Cannot create CPU map')
-
         except KeyError, exn:
             log.exception(exn)
             raise VmError('Unspecified domain detail: %s' % str(exn))
@@ -552,7 +574,8 @@
         if self.infoIsSet('image'):
             to_store['image'] = sxp.to_string(self.info['image'])
 
-        for k in ['name', 'ssidref', 'on_poweroff', 'on_reboot', 'on_crash']:
+        for k in ['name', 'ssidref', 'on_poweroff', 'on_reboot', 'on_crash',
+                  'vcpus', 'vcpu_avail']:
             if self.infoIsSet(k):
                 to_store[k] = str(self.info[k])
 
@@ -572,6 +595,15 @@
         for (k, v) in self.info.items():
             if v:
                 to_store[k] = str(v)
+
+        def availability(n):
+            if self.info['vcpu_avail'] & (1 << n):
+                return 'online'
+            else:
+                return 'offline'
+
+        for v in range(0, self.info['vcpus']):
+            to_store["cpu/%d/availability" % v] = availability(v)
 
         log.debug("Storing domain details: %s" % str(to_store))
 
@@ -916,7 +948,8 @@
         if self.infoIsSet('cpu_time'):
             sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
         sxpr.append(['vcpus', self.info['vcpus']])
-        sxpr.append(['cpumap', self.info['cpumap']])
+        if self.infoIsSet('cpumap'):
+            sxpr.append(['cpumap', self.info['cpumap']])
         if self.infoIsSet('vcpu_to_cpu'):
             sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
             sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()])
@@ -986,27 +1019,21 @@
 
         self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'])
 
-        if self.domid <= 0:
+        if self.domid < 0:
             raise VmError('Creating domain failed: name=%s' %
                           self.info['name'])
 
-        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()
-            self.storeVmDetails()
-            self.storeDomDetails()
-        except:
-            log.exception('Domain construction failed')
-            self.destroy()
-            raise VmError('Creating domain failed: name=%s' %
-                          self.info['name'])
+        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()
+        self.storeVmDetails()
+        self.storeDomDetails()
 
 
     def initDomain(self):
@@ -1041,13 +1068,6 @@
                   self.domid, self.info['name'], self.info['memory_KiB'])
 
 
-    def configure_vcpus(self):
-        d = {}
-        for v in range(0, self.info['vcpus']):
-            d["cpu/%d/availability" % v] = "online"
-        self.writeVm(d)
-
-
     def construct_image(self):
         """Construct the boot image for the domain.
         """
@@ -1055,7 +1075,6 @@
         self.image.createImage()
         IntroduceDomain(self.domid, self.store_mfn,
                         self.store_channel.port1, self.dompath)
-        self.configure_vcpus()
 
 
     ## public:
@@ -1376,10 +1395,13 @@
             log.error("Invalid VCPU %d" % vcpu)
             return
         if int(state) == 0:
+            self.info['vcpu_avail'] &= ~(1 << vcpu)
             availability = "offline"
         else:
+            self.info['vcpu_avail'] &= (1 << vcpu)
             availability = "online"
-        self.storeVm("cpu/%d/availability" % vcpu, availability)
+        self.storeVm('vcpu_avail', self.info['vcpu_avail'])
+        self.storeDom("cpu/%d/availability" % vcpu, availability)
 
     def send_sysrq(self, key=0):
         self.storeDom("control/sysrq", '%c' % key)
@@ -1397,7 +1419,6 @@
                     pass
                 else:
                     raise
-        self.configure_vcpus()
 
 
     def dom0_enforce_vcpus(self):

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Fix the handling of VCPUs, specifically wrt the broken VCPU hotplugging, bug, Xen patchbot -unstable <=