[libvirt] [PATCH v2 10/21] conf: Store cpu pinning data in def->vcpus

Peter Krempa pkrempa at redhat.com
Fri Jan 29 16:02:05 UTC 2016


Now with the new struct the data can be stored in a much saner place.
---

Notes:
    v2:
    - clear bitmap pointer after free to avoid use after free

 src/conf/domain_conf.c   | 136 ++++++++++++++++++--------------------------
 src/conf/domain_conf.h   |   3 +-
 src/libxl/libxl_domain.c |  17 +++---
 src/libxl/libxl_driver.c |  39 ++++++-------
 src/qemu/qemu_cgroup.c   |  15 ++---
 src/qemu/qemu_driver.c   | 143 ++++++++++++++++++++++-------------------------
 src/qemu/qemu_process.c  |  36 ++++++------
 src/test/test_driver.c   |  43 ++++++--------
 8 files changed, 186 insertions(+), 246 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3dc5e00..c4b735e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1289,6 +1289,9 @@ virDomainVcpuInfoClear(virDomainVcpuInfoPtr info)
 {
     if (!info)
         return;
+
+    virBitmapFree(info->cpumask);
+    info->cpumask = NULL;
 }


@@ -1422,7 +1425,14 @@ virDomainDefGetVcpu(virDomainDefPtr def,
 static bool
 virDomainDefHasVcpuPin(const virDomainDef *def)
 {
-    return !!def->cputune.vcpupin;
+    size_t i;
+
+    for (i = 0; i < def->maxvcpus; i++) {
+        if (def->vcpus[i].cpumask)
+            return true;
+    }
+
+    return false;
 }


@@ -2593,8 +2603,6 @@ void virDomainDefFree(virDomainDefPtr def)

     virDomainIOThreadIDDefArrayFree(def->iothreadids, def->niothreadids);

-    virDomainPinDefArrayFree(def->cputune.vcpupin, def->cputune.nvcpupin);
-
     virBitmapFree(def->cputune.emulatorpin);

     for (i = 0; i < def->cputune.nvcpusched; i++)
@@ -14137,83 +14145,68 @@ virDomainIOThreadIDDefParseXML(xmlNodePtr node,
 }


-/* Check if pin with same id already exists. */
-static bool
-virDomainPinIsDuplicate(virDomainPinDefPtr *def,
-                        int npin,
-                        int id)
-{
-    size_t i;
-
-    if (!def || !npin)
-        return false;
-
-    for (i = 0; i < npin; i++) {
-        if (def[i]->id == id)
-            return true;
-    }
-
-    return false;
-}
-
 /* Parse the XML definition for a vcpupin
  *
  * vcpupin has the form of
  *   <vcpupin vcpu='0' cpuset='0'/>
  */
-static virDomainPinDefPtr
-virDomainVcpuPinDefParseXML(xmlNodePtr node,
-                            xmlXPathContextPtr ctxt)
+static int
+virDomainVcpuPinDefParseXML(virDomainDefPtr def,
+                            xmlNodePtr node)
 {
-    virDomainPinDefPtr def;
-    xmlNodePtr oldnode = ctxt->node;
+    virDomainVcpuInfoPtr vcpu;
     unsigned int vcpuid;
     char *tmp = NULL;
+    int ret = -1;

-    if (VIR_ALLOC(def) < 0)
-        return NULL;
-
-    ctxt->node = node;
-
-    if (!(tmp = virXPathString("string(./@vcpu)", ctxt))) {
-        virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("missing vcpu id in vcpupin"));
-        goto error;
+    if (!(tmp = virXMLPropString(node, "vcpu"))) {
+        virReportError(VIR_ERR_XML_ERROR, "%s", _("missing vcpu id in vcpupin"));
+        goto cleanup;
     }

     if (virStrToLong_uip(tmp, NULL, 10, &vcpuid) < 0) {
         virReportError(VIR_ERR_XML_ERROR,
                        _("invalid setting for vcpu '%s'"), tmp);
-        goto error;
+        goto cleanup;
     }
     VIR_FREE(tmp);

-    def->id = vcpuid;
+    if (!(vcpu = virDomainDefGetVcpu(def, vcpuid)) ||
+        !vcpu->online) {
+        /* To avoid the regression when daemon loading domain confs, we can't
+         * simply error out if <vcpupin> nodes greater than current vcpus.
+         * Ignore them instead. */
+        VIR_WARN("Ignoring vcpupin for missing vcpus");
+        ret = 0;
+        goto cleanup;
+    }

     if (!(tmp = virXMLPropString(node, "cpuset"))) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("missing cpuset for vcpupin"));
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("missing cpuset for vcpupin"));
+        goto cleanup;
+    }

-        goto error;
+    if (vcpu->cpumask) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("duplicate vcpupin for vcpu '%d'"), vcpuid);
+        goto cleanup;
     }

-    if (virBitmapParse(tmp, 0, &def->cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0)
-        goto error;
+    if (virBitmapParse(tmp, 0, &vcpu->cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0)
+        goto cleanup;

-    if (virBitmapIsAllClear(def->cpumask)) {
+    if (virBitmapIsAllClear(vcpu->cpumask)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Invalid value of 'cpuset': %s"), tmp);
-        goto error;
+        goto cleanup;
     }

+    ret = 0;
+
  cleanup:
     VIR_FREE(tmp);
-    ctxt->node = oldnode;
-    return def;
-
- error:
-    VIR_FREE(def);
-    goto cleanup;
+    return ret;
 }


@@ -15147,34 +15140,9 @@ virDomainDefParseXML(xmlDocPtr xml,
     if ((n = virXPathNodeSet("./cputune/vcpupin", ctxt, &nodes)) < 0)
         goto error;

-    if (n && VIR_ALLOC_N(def->cputune.vcpupin, n) < 0)
-        goto error;
-
     for (i = 0; i < n; i++) {
-        virDomainPinDefPtr vcpupin;
-        if (!(vcpupin = virDomainVcpuPinDefParseXML(nodes[i], ctxt)))
+        if (virDomainVcpuPinDefParseXML(def, nodes[i]))
             goto error;
-
-        if (virDomainPinIsDuplicate(def->cputune.vcpupin,
-                                    def->cputune.nvcpupin,
-                                    vcpupin->id)) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           "%s", _("duplicate vcpupin for same vcpu"));
-            virDomainPinDefFree(vcpupin);
-            goto error;
-        }
-
-        if (vcpupin->id >= virDomainDefGetVcpus(def)) {
-            /* To avoid the regression when daemon loading
-             * domain confs, we can't simply error out if
-             * <vcpupin> nodes greater than current vcpus,
-             * ignoring them instead.
-             */
-            VIR_WARN("Ignore vcpupin for missing vcpus");
-            virDomainPinDefFree(vcpupin);
-        } else {
-            def->cputune.vcpupin[def->cputune.nvcpupin++] = vcpupin;
-        }
     }
     VIR_FREE(nodes);

@@ -21815,15 +21783,19 @@ virDomainDefFormatInternal(virDomainDefPtr def,
                           "</emulator_quota>\n",
                           def->cputune.emulator_quota);

-    for (i = 0; i < def->cputune.nvcpupin; i++) {
+    for (i = 0; i < def->maxvcpus; i++) {
         char *cpumask;
-        virBufferAsprintf(&childrenBuf, "<vcpupin vcpu='%u' ",
-                          def->cputune.vcpupin[i]->id);
+        virDomainVcpuInfoPtr vcpu = def->vcpus + i;

-        if (!(cpumask = virBitmapFormat(def->cputune.vcpupin[i]->cpumask)))
+        if (!vcpu->cpumask)
+            continue;
+
+        if (!(cpumask = virBitmapFormat(vcpu->cpumask)))
             goto error;

-        virBufferAsprintf(&childrenBuf, "cpuset='%s'/>\n", cpumask);
+        virBufferAsprintf(&childrenBuf,
+                          "<vcpupin vcpu='%zu' cpuset='%s'/>\n", i, cpumask);
+
         VIR_FREE(cpumask);
     }

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9fdfdf2..f33c575 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2137,8 +2137,6 @@ struct _virDomainCputune {
     long long quota;
     unsigned long long emulator_period;
     long long emulator_quota;
-    size_t nvcpupin;
-    virDomainPinDefPtr *vcpupin;
     virBitmapPtr emulatorpin;

     size_t nvcpusched;
@@ -2153,6 +2151,7 @@ typedef virDomainVcpuInfo *virDomainVcpuInfoPtr;

 struct _virDomainVcpuInfo {
     bool online;
+    virBitmapPtr cpumask;
 };

 typedef struct _virDomainBlkiotune virDomainBlkiotune;
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index b098d3d..19d5657 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -821,7 +821,7 @@ int
 libxlDomainSetVcpuAffinities(libxlDriverPrivatePtr driver, virDomainObjPtr vm)
 {
     libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
-    virDomainPinDefPtr pin;
+    virDomainVcpuInfoPtr vcpu;
     libxl_bitmap map;
     virBitmapPtr cpumask = NULL;
     size_t i;
@@ -830,13 +830,12 @@ libxlDomainSetVcpuAffinities(libxlDriverPrivatePtr driver, virDomainObjPtr vm)
     libxl_bitmap_init(&map);

     for (i = 0; i < virDomainDefGetVcpus(vm->def); ++i) {
-        pin = virDomainPinFind(vm->def->cputune.vcpupin,
-                               vm->def->cputune.nvcpupin,
-                               i);
+        vcpu = virDomainDefGetVcpu(vm->def, i);

-        if (pin && pin->cpumask)
-            cpumask = pin->cpumask;
-        else
+        if (!vcpu->online)
+            continue;
+
+        if (!(cpumask = vcpu->cpumask))
             cpumask = vm->def->cpumask;

         if (!cpumask)
@@ -845,9 +844,9 @@ libxlDomainSetVcpuAffinities(libxlDriverPrivatePtr driver, virDomainObjPtr vm)
         if (virBitmapToData(cpumask, &map.map, (int *)&map.size) < 0)
             goto cleanup;

-        if (libxl_set_vcpuaffinity(cfg->ctx, vm->def->id, pin->id, &map) != 0) {
+        if (libxl_set_vcpuaffinity(cfg->ctx, vm->def->id, i, &map) != 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Failed to pin vcpu '%d' with libxenlight"), pin->id);
+                           _("Failed to pin vcpu '%zu' with libxenlight"), i);
             goto cleanup;
         }

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 6ab4f07..0b5481b 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2329,6 +2329,7 @@ libxlDomainPinVcpuFlags(virDomainPtr dom, unsigned int vcpu,
     libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
     virDomainDefPtr targetDef = NULL;
     virBitmapPtr pcpumap = NULL;
+    virDomainVcpuInfoPtr vcpuinfo;
     virDomainObjPtr vm;
     int ret = -1;

@@ -2360,10 +2361,16 @@ libxlDomainPinVcpuFlags(virDomainPtr dom, unsigned int vcpu,
     /* Make sure coverity knows targetDef is valid at this point. */
     sa_assert(targetDef);

-    pcpumap = virBitmapNewData(cpumap, maplen);
-    if (!pcpumap)
+    if (!(pcpumap = virBitmapNewData(cpumap, maplen)))
         goto endjob;

+    if (!(vcpuinfo = virDomainDefGetVcpu(targetDef, vcpu)) ||
+        !vcpuinfo->online) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("vcpu '%u' is not active"), vcpu);
+        goto endjob;
+    }
+
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
         libxl_bitmap map = { .size = maplen, .map = cpumap };
         if (libxl_set_vcpuaffinity(cfg->ctx, vm->def->id, vcpu, &map) != 0) {
@@ -2374,20 +2381,9 @@ libxlDomainPinVcpuFlags(virDomainPtr dom, unsigned int vcpu,
         }
     }

-    if (!targetDef->cputune.vcpupin) {
-        if (VIR_ALLOC(targetDef->cputune.vcpupin) < 0)
-            goto endjob;
-        targetDef->cputune.nvcpupin = 0;
-    }
-    if (virDomainPinAdd(&targetDef->cputune.vcpupin,
-                        &targetDef->cputune.nvcpupin,
-                        cpumap,
-                        maplen,
-                        vcpu) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "%s", _("failed to update or add vcpupin xml"));
-        goto endjob;
-    }
+    virBitmapFree(vcpuinfo->cpumask);
+    vcpuinfo->cpumask = pcpumap;
+    pcpumap = NULL;

     ret = 0;

@@ -2463,15 +2459,14 @@ libxlDomainGetVcpuPinInfo(virDomainPtr dom, int ncpumaps,
     memset(cpumaps, 0x00, maplen * ncpumaps);

     for (vcpu = 0; vcpu < ncpumaps; vcpu++) {
-        virDomainPinDefPtr pininfo;
+        virDomainVcpuInfoPtr vcpuinfo = virDomainDefGetVcpu(targetDef, vcpu);
         virBitmapPtr bitmap = NULL;

-        pininfo = virDomainPinFind(targetDef->cputune.vcpupin,
-                                   targetDef->cputune.nvcpupin,
-                                   vcpu);
+        if (!vcpuinfo->online)
+            continue;

-        if (pininfo && pininfo->cpumask)
-            bitmap = pininfo->cpumask;
+        if (vcpuinfo->cpumask)
+            bitmap = vcpuinfo->cpumask;
         else if (targetDef->cpumask)
             bitmap = targetDef->cpumask;
         else
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index e41f461..8dff76c 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -1007,7 +1007,7 @@ qemuSetupCgroupForVcpu(virDomainObjPtr vm)
     virCgroupPtr cgroup_vcpu = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainDefPtr def = vm->def;
-    size_t i, j;
+    size_t i;
     unsigned long long period = vm->def->cputune.period;
     long long quota = vm->def->cputune.quota;
     char *mem_mask = NULL;
@@ -1065,20 +1065,13 @@ qemuSetupCgroupForVcpu(virDomainObjPtr vm)
                 virCgroupSetCpusetMems(cgroup_vcpu, mem_mask) < 0)
                 goto cleanup;

-            /* try to use the default cpu maps */
-            if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
+            if (vcpu->cpumask)
+                cpumap = vcpu->cpumask;
+            else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
                 cpumap = priv->autoCpuset;
             else
                 cpumap = vm->def->cpumask;

-            /* lookup a more specific pinning info */
-            for (j = 0; j < def->cputune.nvcpupin; j++) {
-                if (def->cputune.vcpupin[j]->id == i) {
-                    cpumap = def->cputune.vcpupin[j]->cpumask;
-                    break;
-                }
-            }
-
             if (cpumap && qemuSetupCgroupCpusetCpus(cgroup_vcpu, cpumap) < 0)
                 goto cleanup;
         }
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c9d6d00..54600dc 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4847,11 +4847,6 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,

     virDomainAuditVcpu(vm, oldvcpus, oldvcpus - 1, "update", rc >= 0);

-    /* Free vcpupin setting */
-    virDomainPinDel(&vm->def->cputune.vcpupin,
-                    &vm->def->cputune.nvcpupin,
-                    vcpu);
-
     if (rc <= 0) {
         if (rc == 0)
             ret = 0;
@@ -4863,6 +4858,9 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
                                      VIR_CGROUP_THREAD_VCPU, vcpu) < 0)
         goto cleanup;

+    virBitmapFree(vcpuinfo->cpumask);
+    vcpuinfo->cpumask = NULL;
+
     ret = 0;

  cleanup:
@@ -5026,10 +5024,15 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
     if (persistentDef) {
         /* remove vcpupin entries for vcpus that were unplugged */
         if (nvcpus < virDomainDefGetVcpus(persistentDef)) {
-            for (i = virDomainDefGetVcpus(persistentDef) - 1; i >= nvcpus; i--)
-                virDomainPinDel(&persistentDef->cputune.vcpupin,
-                                &persistentDef->cputune.nvcpupin,
-                                i);
+            for (i = virDomainDefGetVcpus(persistentDef) - 1; i >= nvcpus; i--) {
+                virDomainVcpuInfoPtr vcpu = virDomainDefGetVcpu(persistentDef,
+                                                                i);
+
+                if (vcpu) {
+                    virBitmapFree(vcpu->cpumask);
+                    vcpu->cpumask = NULL;
+                }
+            }
         }

         if (flags & VIR_DOMAIN_VCPU_MAXIMUM) {
@@ -5088,9 +5091,11 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
     virCgroupPtr cgroup_vcpu = NULL;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
-    size_t newVcpuPinNum = 0;
-    virDomainPinDefPtr *newVcpuPin = NULL;
     virBitmapPtr pcpumap = NULL;
+    virBitmapPtr pcpumaplive = NULL;
+    virBitmapPtr pcpumappersist = NULL;
+    virDomainVcpuInfoPtr vcpuinfolive = NULL;
+    virDomainVcpuInfoPtr vcpuinfopersist = NULL;
     virQEMUDriverConfigPtr cfg = NULL;
     virObjectEventPtr event = NULL;
     char paramField[VIR_TYPED_PARAM_FIELD_LENGTH] = "";
@@ -5118,18 +5123,36 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,

     priv = vm->privateData;

-    if (def && vcpu >= virDomainDefGetVcpus(def)) {
-        virReportError(VIR_ERR_INVALID_ARG,
-                       _("vcpu %d is out of range of live cpu count %d"),
-                       vcpu, virDomainDefGetVcpus(def));
-        goto endjob;
+    if (def) {
+        if (!(vcpuinfolive = virDomainDefGetVcpu(def, vcpu))) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("vcpu %d is out of range of live cpu count %d"),
+                           vcpu, virDomainDefGetVcpus(def));
+            goto endjob;
+        }
+
+        if (!vcpuinfolive->online) {
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                           _("setting cpu pinning for inactive vcpu '%d' is not "
+                             "supported"), vcpu);
+            goto endjob;
+        }
     }

-    if (persistentDef && vcpu >= virDomainDefGetVcpus(persistentDef)) {
-        virReportError(VIR_ERR_INVALID_ARG,
-                       _("vcpu %d is out of range of persistent cpu count %d"),
-                       vcpu, virDomainDefGetVcpus(persistentDef));
-        goto endjob;
+    if (persistentDef) {
+        if (!(vcpuinfopersist = virDomainDefGetVcpu(persistentDef, vcpu))) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("vcpu %d is out of range of persistent cpu count %d"),
+                           vcpu, virDomainDefGetVcpus(persistentDef));
+            goto endjob;
+        }
+
+        if (!vcpuinfopersist->online) {
+            virReportError(VIR_ERR_OPERATION_INVALID,
+                           _("setting cpu pinning for inactive vcpu '%d' is not "
+                             "supported"), vcpu);
+            goto endjob;
+        }
     }

     if (!(pcpumap = virBitmapNewData(cpumap, maplen)))
@@ -5141,6 +5164,10 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
         goto endjob;
     }

+    if ((def && !(pcpumaplive = virBitmapNewCopy(pcpumap))) ||
+        (persistentDef && !(pcpumappersist = virBitmapNewCopy(pcpumap))))
+        goto endjob;
+
     if (def) {
         if (!qemuDomainHasVcpuPids(vm)) {
             virReportError(VIR_ERR_OPERATION_INVALID,
@@ -5148,26 +5175,6 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
             goto endjob;
         }

-        if (def->cputune.vcpupin) {
-            newVcpuPin = virDomainPinDefCopy(def->cputune.vcpupin,
-                                             def->cputune.nvcpupin);
-            if (!newVcpuPin)
-                goto endjob;
-
-            newVcpuPinNum = def->cputune.nvcpupin;
-        } else {
-            if (VIR_ALLOC(newVcpuPin) < 0)
-                goto endjob;
-            newVcpuPinNum = 0;
-        }
-
-        if (virDomainPinAdd(&newVcpuPin, &newVcpuPinNum,
-                            cpumap, maplen, vcpu) < 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("failed to update vcpupin"));
-            goto endjob;
-        }
-
         /* Configure the corresponding cpuset cgroup before set affinity. */
         if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
             if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_VCPU, vcpu,
@@ -5189,13 +5196,9 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
             }
         }

-        if (def->cputune.vcpupin)
-            virDomainPinDefArrayFree(def->cputune.vcpupin,
-                                     def->cputune.nvcpupin);
-
-        def->cputune.vcpupin = newVcpuPin;
-        def->cputune.nvcpupin = newVcpuPinNum;
-        newVcpuPin = NULL;
+        virBitmapFree(vcpuinfolive->cpumask);
+        vcpuinfolive->cpumask = pcpumaplive;
+        pcpumaplive = NULL;

         if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
             goto endjob;
@@ -5214,24 +5217,12 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
     }

     if (persistentDef) {
-        if (!persistentDef->cputune.vcpupin) {
-            if (VIR_ALLOC(persistentDef->cputune.vcpupin) < 0)
-                goto endjob;
-            persistentDef->cputune.nvcpupin = 0;
-        }
-        if (virDomainPinAdd(&persistentDef->cputune.vcpupin,
-                            &persistentDef->cputune.nvcpupin,
-                            cpumap,
-                            maplen,
-                            vcpu) < 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("failed to update or add vcpupin xml of "
-                             "a persistent domain"));
-            goto endjob;
-        }
+        virBitmapFree(vcpuinfopersist->cpumask);
+        vcpuinfopersist->cpumask = pcpumappersist;
+        pcpumappersist = NULL;

-        ret = virDomainSaveConfig(cfg->configDir, persistentDef);
-        goto endjob;
+        if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
+           goto endjob;
     }

     ret = 0;
@@ -5240,14 +5231,14 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
     qemuDomainObjEndJob(driver, vm);

  cleanup:
-    if (newVcpuPin)
-        virDomainPinDefArrayFree(newVcpuPin, newVcpuPinNum);
     if (cgroup_vcpu)
         virCgroupFree(&cgroup_vcpu);
     virDomainObjEndAPI(&vm);
     qemuDomainEventQueue(driver, event);
     VIR_FREE(str);
     virBitmapFree(pcpumap);
+    virBitmapFree(pcpumaplive);
+    virBitmapFree(pcpumappersist);
     virObjectUnref(cfg);
     return ret;
 }
@@ -5272,7 +5263,8 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom,
     virDomainObjPtr vm = NULL;
     virDomainDefPtr def;
     int ret = -1;
-    int hostcpus, vcpu;
+    int hostcpus;
+    size_t i;
     virBitmapPtr allcpumap = NULL;
     qemuDomainObjPrivatePtr priv = NULL;

@@ -5304,16 +5296,15 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom,
     if (ncpumaps < 1)
         goto cleanup;

-    for (vcpu = 0; vcpu < ncpumaps; vcpu++) {
-        virDomainPinDefPtr pininfo;
+    for (i = 0; i < ncpumaps; i++) {
+        virDomainVcpuInfoPtr vcpu = virDomainDefGetVcpu(def, i);
         virBitmapPtr bitmap = NULL;

-        pininfo = virDomainPinFind(def->cputune.vcpupin,
-                                   def->cputune.nvcpupin,
-                                   vcpu);
+        if (!vcpu->online)
+            continue;

-        if (pininfo && pininfo->cpumask)
-            bitmap = pininfo->cpumask;
+        if (vcpu->cpumask)
+            bitmap = vcpu->cpumask;
         else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO &&
                  priv->autoCpuset)
             bitmap = priv->autoCpuset;
@@ -5322,7 +5313,7 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom,
         else
             bitmap = allcpumap;

-        virBitmapToDataBuf(bitmap, VIR_GET_CPUMAP(cpumaps, maplen, vcpu), maplen);
+        virBitmapToDataBuf(bitmap, VIR_GET_CPUMAP(cpumaps, maplen, i), maplen);
     }

     ret = ncpumaps;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 5ede367..4b94a89 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2193,23 +2193,23 @@ static int
 qemuProcessSetVcpuAffinities(virDomainObjPtr vm)
 {
     virDomainDefPtr def = vm->def;
-    virDomainPinDefPtr pininfo;
-    int n;
+    virDomainVcpuInfoPtr vcpu;
+    size_t i;
     int ret = -1;
-    VIR_DEBUG("Setting affinity on CPUs nvcpupin=%zu nvcpus=%d hasVcpupids=%d",
-              def->cputune.nvcpupin, virDomainDefGetVcpus(def),
-              qemuDomainHasVcpuPids(vm));
-    if (!def->cputune.nvcpupin)
-        return 0;
+    VIR_DEBUG("Setting affinity on CPUs");

     if (!qemuDomainHasVcpuPids(vm)) {
         /* If any CPU has custom affinity that differs from the
          * VM default affinity, we must reject it
          */
-        for (n = 0; n < def->cputune.nvcpupin; n++) {
-            if (def->cputune.vcpupin[n]->cpumask &&
-                !virBitmapEqual(def->cpumask,
-                                def->cputune.vcpupin[n]->cpumask)) {
+        for (i = 0; i < virDomainDefGetVcpusMax(def); i++) {
+            vcpu = virDomainDefGetVcpu(def, i);
+
+            if (!vcpu->online)
+                continue;
+
+            if (vcpu->cpumask &&
+                !virBitmapEqual(def->cpumask, vcpu->cpumask)) {
                 virReportError(VIR_ERR_OPERATION_INVALID,
                                "%s", _("cpu affinity is not supported"));
                 return -1;
@@ -2218,19 +2218,19 @@ qemuProcessSetVcpuAffinities(virDomainObjPtr vm)
         return 0;
     }

-    for (n = 0; n < virDomainDefGetVcpus(def); n++) {
+    for (i = 0; i < virDomainDefGetVcpusMax(def); i++) {
         virBitmapPtr bitmap;
-        /* set affinity only for existing vcpus */
-        if (!(pininfo = virDomainPinFind(def->cputune.vcpupin,
-                                         def->cputune.nvcpupin,
-                                         n)))
+
+        vcpu = virDomainDefGetVcpu(def, i);
+
+        if (!vcpu->online)
             continue;

-        if (!(bitmap = pininfo->cpumask) &&
+        if (!(bitmap = vcpu->cpumask) &&
             !(bitmap = def->cpumask))
             continue;

-        if (virProcessSetAffinity(qemuDomainGetVcpuPid(vm, n), bitmap) < 0)
+        if (virProcessSetAffinity(qemuDomainGetVcpuPid(vm, i), bitmap) < 0)
             goto cleanup;
     }

diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 5986749..ed4de12 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -2455,15 +2455,14 @@ static int testDomainGetVcpus(virDomainPtr domain,
     memset(cpumaps, 0, maxinfo * maplen);

     for (i = 0; i < maxinfo; i++) {
-        virDomainPinDefPtr pininfo;
+        virDomainVcpuInfoPtr vcpu = virDomainDefGetVcpu(def, i);
         virBitmapPtr bitmap = NULL;

-        pininfo = virDomainPinFind(def->cputune.vcpupin,
-                                   def->cputune.nvcpupin,
-                                   i);
+        if (vcpu && !vcpu->online)
+            continue;

-        if (pininfo && pininfo->cpumask)
-            bitmap = pininfo->cpumask;
+        if (vcpu->cpumask)
+            bitmap = vcpu->cpumask;
         else if (def->cpumask)
             bitmap = def->cpumask;
         else
@@ -2492,6 +2491,7 @@ static int testDomainPinVcpu(virDomainPtr domain,
                              unsigned char *cpumap,
                              int maplen)
 {
+    virDomainVcpuInfoPtr vcpuinfo;
     virDomainObjPtr privdom;
     virDomainDefPtr def;
     int ret = -1;
@@ -2507,29 +2507,21 @@ static int testDomainPinVcpu(virDomainPtr domain,
         goto cleanup;
     }

-    if (vcpu > virDomainDefGetVcpus(privdom->def)) {
+    if (!(vcpuinfo = virDomainDefGetVcpu(def, vcpu)) ||
+        !vcpuinfo->online) {
         virReportError(VIR_ERR_INVALID_ARG,
                        _("requested vcpu '%d' is not present in the domain"),
                        vcpu);
         goto cleanup;
     }

-    if (!def->cputune.vcpupin) {
-        if (VIR_ALLOC(def->cputune.vcpupin) < 0)
-            goto cleanup;
-        def->cputune.nvcpupin = 0;
-    }
-    if (virDomainPinAdd(&def->cputune.vcpupin,
-                        &def->cputune.nvcpupin,
-                        cpumap,
-                        maplen,
-                        vcpu) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("failed to update or add vcpupin"));
+    virBitmapFree(vcpuinfo->cpumask);
+
+    if (!(vcpuinfo->cpumask = virBitmapNewData(cpumap, maplen)))
         goto cleanup;
-    }

     ret = 0;
+
  cleanup:
     virDomainObjEndAPI(&privdom);
     return ret;
@@ -2566,15 +2558,14 @@ testDomainGetVcpuPinInfo(virDomainPtr dom,
         ncpumaps = virDomainDefGetVcpus(def);

     for (vcpu = 0; vcpu < ncpumaps; vcpu++) {
-        virDomainPinDefPtr pininfo;
+        virDomainVcpuInfoPtr vcpuinfo = virDomainDefGetVcpu(def, vcpu);
         virBitmapPtr bitmap = NULL;

-        pininfo = virDomainPinFind(def->cputune.vcpupin,
-                                   def->cputune.nvcpupin,
-                                   vcpu);
+        if (vcpuinfo && !vcpuinfo->online)
+            continue;

-        if (pininfo && pininfo->cpumask)
-            bitmap = pininfo->cpumask;
+        if (vcpuinfo->cpumask)
+            bitmap = vcpuinfo->cpumask;
         else if (def->cpumask)
             bitmap = def->cpumask;
         else
-- 
2.6.2




More information about the libvir-list mailing list