]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf, schema: add 'id' field for cells
authorMartin Kletzander <mkletzan@redhat.com>
Thu, 22 May 2014 07:13:05 +0000 (09:13 +0200)
committerMartin Kletzander <mkletzan@redhat.com>
Wed, 16 Jul 2014 18:15:45 +0000 (20:15 +0200)
In XML format, by definition, order of fields should not matter, so
order of parsing the elements doesn't affect the end result.  When
specifying guest NUMA cells, we depend only on the order of the 'cell'
elements.  With this patch all older domain XMLs are parsed as before,
but with the 'id' attribute they are parsed and formatted according to
that field.  This will be useful when we have tuning settings for
particular guest NUMA node.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
12 files changed:
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/cpu_conf.c
src/conf/cpu_conf.h
src/qemu/qemu_command.c
tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.xml
tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.xml
tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c
tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml [new file with mode: 0644]
tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml [new file with mode: 0644]
tests/qemuxml2xmltest.c

index 27465bb6189780ccfc96b296eefc11fdc8f3fe04..eb203670d3cce08e9f9ad14b14dddf435bc697b6 100644 (file)
   &lt;cpu&gt;
     ...
     &lt;numa&gt;
-      &lt;cell cpus='0-3' memory='512000'/&gt;
-      &lt;cell cpus='4-7' memory='512000'/&gt;
+      &lt;cell id='0' cpus='0-3' memory='512000'/&gt;
+      &lt;cell id='1' cpus='4-7' memory='512000'/&gt;
     &lt;/numa&gt;
     ...
   &lt;/cpu&gt;
 
     <p>
       Each <code>cell</code> element specifies a NUMA cell or a NUMA node.
-      <code>cpus</code> specifies the CPU or range of CPUs that are part of
-      the node. <code>memory</code> specifies the node memory in kibibytes
-      (i.e. blocks of 1024 bytes). Each cell or node is assigned cellid
-      or nodeid in the increasing order starting from 0.
+      <code>cpus</code> specifies the CPU or range of CPUs that are
+      part of the node. <code>memory</code> specifies the node memory
+      in kibibytes (i.e. blocks of 1024 bytes).
+      <span class="since">Since 1.2.7</span> all cells should
+      have <code>id</code> attribute in case referring to some cell is
+      necessary in the code, otherwise the cells are
+      assigned <code>id</code>s in the increasing order starting from
+      0.  Mixing cells with and without the <code>id</code> attribute
+      is not recommended as it may result in unwanted behaviour.
     </p>
 
     <p>
index cfd8629cd29985967a77e36e390ab88e7eccf627..1d3b4d8544049b7a1de91ef41195074380d660f5 100644 (file)
 
   <define name="numaCell">
     <element name="cell">
+      <optional>
+        <attribute name="id">
+          <ref name="unsignedInt"/>
+        </attribute>
+      </optional>
       <attribute name="cpus">
         <ref name="cpuset"/>
       </attribute>
index 811893db84059a2245b2ce9a068c640320f69b57..5003cf164cb9af9140ff0ce31be3eb2302a03636 100644 (file)
@@ -152,7 +152,6 @@ virCPUDefCopy(const virCPUDef *cpu)
         copy->ncells_max = copy->ncells = cpu->ncells;
 
         for (i = 0; i < cpu->ncells; i++) {
-            copy->cells[i].cellid = cpu->cells[i].cellid;
             copy->cells[i].mem = cpu->cells[i].mem;
 
             copy->cells[i].cpumask = virBitmapNewCopy(cpu->cells[i].cpumask);
@@ -438,17 +437,48 @@ virCPUDefParseXML(xmlNodePtr node,
         for (i = 0; i < n; i++) {
             char *cpus, *memory;
             int ret, ncpus = 0;
+            unsigned int cur_cell;
+            char *tmp = NULL;
+
+            tmp = virXMLPropString(nodes[i], "id");
+            if (!tmp) {
+                cur_cell = i;
+            } else {
+                ret  = virStrToLong_ui(tmp, NULL, 10, &cur_cell);
+                if (ret == -1) {
+                    virReportError(VIR_ERR_XML_ERROR,
+                                   _("Invalid 'id' attribute in NUMA cell: %s"),
+                                   tmp);
+                    VIR_FREE(tmp);
+                    goto error;
+                }
+                VIR_FREE(tmp);
+            }
+
+            if (cur_cell >= n) {
+                virReportError(VIR_ERR_XML_ERROR, "%s",
+                               _("Exactly one 'cell' element per guest "
+                                 "NUMA cell allowed, non-contiguous ranges or "
+                                 "ranges not starting from 0 are not allowed"));
+                goto error;
+            }
+
+            if (def->cells[cur_cell].cpustr) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("Duplicate NUMA cell info for cell id '%u'"),
+                               cur_cell);
+                goto error;
+            }
 
-            def->cells[i].cellid = i;
             cpus = virXMLPropString(nodes[i], "cpus");
             if (!cpus) {
                 virReportError(VIR_ERR_XML_ERROR, "%s",
                                _("Missing 'cpus' attribute in NUMA cell"));
                 goto error;
             }
-            def->cells[i].cpustr = cpus;
+            def->cells[cur_cell].cpustr = cpus;
 
-            ncpus = virBitmapParse(cpus, 0, &def->cells[i].cpumask,
+            ncpus = virBitmapParse(cpus, 0, &def->cells[cur_cell].cpumask,
                                    VIR_DOMAIN_CPUMASK_LEN);
             if (ncpus <= 0)
                 goto error;
@@ -461,7 +491,7 @@ virCPUDefParseXML(xmlNodePtr node,
                 goto error;
             }
 
-            ret  = virStrToLong_ui(memory, NULL, 10, &def->cells[i].mem);
+            ret  = virStrToLong_ui(memory, NULL, 10, &def->cells[cur_cell].mem);
             if (ret == -1) {
                 virReportError(VIR_ERR_XML_ERROR, "%s",
                                _("Invalid 'memory' attribute in NUMA cell"));
@@ -645,6 +675,7 @@ virCPUDefFormatBuf(virBufferPtr buf,
         virBufferAdjustIndent(buf, 2);
         for (i = 0; i < def->ncells; i++) {
             virBufferAddLit(buf, "<cell");
+            virBufferAsprintf(buf, " id='%zu'", i);
             virBufferAsprintf(buf, " cpus='%s'", def->cells[i].cpustr);
             virBufferAsprintf(buf, " memory='%d'", def->cells[i].mem);
             virBufferAddLit(buf, "/>\n");
index 8c932ceb637e8ad656479e57a4f6a4d1d87802f3..2d538db5dbb31103b3d4ec4664fd3ce135f731d1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * cpu_conf.h: CPU XML handling
  *
- * Copyright (C) 2009-2011, 2013 Red Hat, Inc.
+ * Copyright (C) 2009-2011, 2013, 2014 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -93,7 +93,6 @@ struct _virCPUFeatureDef {
 typedef struct _virCellDef virCellDef;
 typedef virCellDef *virCellDefPtr;
 struct _virCellDef {
-   int cellid;
    virBitmapPtr cpumask;       /* CPUs that are part of this node */
    char *cpustr;       /* CPUs stored in string form for dumpxml */
    unsigned int mem;   /* Node memory in kB */
index 1d23d5f241fc07ff218c15d3ec505310b7898998..63a49e305c3e4b811c774ec5423bc846a65f3cff 100644 (file)
@@ -6400,7 +6400,7 @@ qemuBuildNumaArgStr(const virDomainDef *def, virCommandPtr cmd)
         }
 
         virCommandAddArg(cmd, "-numa");
-        virBufferAsprintf(&buf, "node,nodeid=%d", def->cpu->cells[i].cellid);
+        virBufferAsprintf(&buf, "node,nodeid=%zu", i);
         virBufferAddLit(&buf, ",cpus=");
 
         /* Up through qemu 1.4, -numa does not accept a cpus
index ee402c8f7446faa83d767b9613b9517953ac7678..0543f7f79178b8d37c945938c053e71a566268f4 100644 (file)
@@ -9,10 +9,10 @@
     <boot dev='network'/>
   </os>
   <cpu>
-    <topology sockets="2" cores="4" threads="2"/>
+    <topology sockets='2' cores='4' threads='2'/>
     <numa>
-      <cell cpus="0-7" memory="109550"/>
-      <cell cpus="8-15" memory="109550"/>
+      <cell cpus='0-7' memory='109550'/>
+      <cell cpus='8-15' memory='109550'/>
     </numa>
   </cpu>
   <clock offset='utc'/>
index ee402c8f7446faa83d767b9613b9517953ac7678..0a5f9fcd13fa91136e47b5c6a8b9f2eb22b53c52 100644 (file)
@@ -9,10 +9,10 @@
     <boot dev='network'/>
   </os>
   <cpu>
-    <topology sockets="2" cores="4" threads="2"/>
+    <topology sockets='2' cores='4' threads='2'/>
     <numa>
-      <cell cpus="0-7" memory="109550"/>
-      <cell cpus="8-15" memory="109550"/>
+      <cell id='1' cpus='8-15' memory='109550'/>
+      <cell id='0' cpus='0-7' memory='109550'/>
     </numa>
   </cpu>
   <clock offset='utc'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml
new file mode 100644 (file)
index 0000000..fa3070d
--- /dev/null
@@ -0,0 +1,25 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>16</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='network'/>
+  </os>
+  <cpu>
+    <topology sockets='2' cores='4' threads='2'/>
+    <numa>
+      <cell id='1' cpus='0-7' memory='109550'/>
+      <cell id='2' cpus='8-15' memory='109550'/>
+    </numa>
+  </cpu>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+      <emulator>/usr/bin/qemu</emulator>
+  </devices>
+</domain>
index 557c87693d06c56a3e4e6e5f58d301818179c56f..8eb982f2c6a3f3e74a3e16d211a786947f4a7f0d 100644 (file)
@@ -1178,6 +1178,7 @@ mymain(void)
     DO_TEST("cpu-strict1", NONE);
     DO_TEST("cpu-numa1", NONE);
     DO_TEST("cpu-numa2", QEMU_CAPS_SMP_TOPOLOGY);
+    DO_TEST_PARSE_ERROR("cpu-numa3", NONE);
     DO_TEST("cpu-host-model", NONE);
     skipLegacyCPUs = true;
     DO_TEST("cpu-host-model-fallback", NONE);
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml
new file mode 100644 (file)
index 0000000..227bf1c
--- /dev/null
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>16</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='network'/>
+  </os>
+  <cpu>
+    <topology sockets='2' cores='4' threads='2'/>
+    <numa>
+      <cell id='0' cpus='0-7' memory='109550'/>
+      <cell id='1' cpus='8-15' memory='109550'/>
+    </numa>
+  </cpu>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <controller type='usb' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml
new file mode 100644 (file)
index 0000000..227bf1c
--- /dev/null
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>16</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='network'/>
+  </os>
+  <cpu>
+    <topology sockets='2' cores='4' threads='2'/>
+    <numa>
+      <cell id='0' cpus='0-7' memory='109550'/>
+      <cell id='1' cpus='8-15' memory='109550'/>
+    </numa>
+  </cpu>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <controller type='usb' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
index 8884b22121cef3947cd8a654a223b7755cd9a2c6..172ce2bc3d59d4857ffdddb94bec88ff1420f03b 100644 (file)
@@ -370,6 +370,9 @@ mymain(void)
 
     DO_TEST("chardev-label");
 
+    DO_TEST_DIFFERENT("cpu-numa1");
+    DO_TEST_DIFFERENT("cpu-numa2");
+
     virObjectUnref(driver.caps);
     virObjectUnref(driver.xmlopt);