]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: Add support for parsing and formatting max memory and slot count
authorPeter Krempa <pkrempa@redhat.com>
Mon, 11 Aug 2014 15:40:32 +0000 (17:40 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 23 Mar 2015 13:25:14 +0000 (14:25 +0100)
Add a XML element that will allow to specify maximum supportable memory
and the count of memory slots to use with memory hotplug.

To avoid possible confusion and misuse of the new element this patch
also explicitly forbids the use of the maxMemory setting in individual
drivers's post parse callbacks. This limitation will be lifted when the
support is implemented.

19 files changed:
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/bhyve/bhyve_domain.c
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/libxl/libxl_domain.c
src/lxc/lxc_domain.c
src/openvz/openvz_driver.c
src/parallels/parallels_driver.c
src/phyp/phyp_driver.c
src/qemu/qemu_domain.c
src/uml/uml_driver.c
src/vbox/vbox_common.c
src/vmware/vmware_driver.c
src/vmx/vmx.c
src/xen/xen_driver.c
src/xenapi/xenapi_driver.c
tests/domainschemadata/maxMemory.xml [new file with mode: 0644]

index be35c82e7d0438244f4e7a28c8872e890b11f899..cc80efa73d01a18a9f721bffa63afd487e230790 100644 (file)
 <pre>
 &lt;domain&gt;
   ...
+  &lt;maxMemory slots='16' unit='KiB'&gt;1524288&lt;/maxMemory&gt;
   &lt;memory unit='KiB'&gt;524288&lt;/memory&gt;
   &lt;currentMemory unit='KiB'&gt;524288&lt;/currentMemory&gt;
   ...
         <span class='since'><code>unit</code> since 0.9.11</span>,
         <span class='since'><code>dumpCore</code> since 0.10.2
         (QEMU only)</span></dd>
+      <dt><code>maxMemory</code></dt>
+      <dd>The run time maximum memory allocation of the guest. The initial
+        memory specified by either the <code>&lt;memory&gt;</code> element or
+        the NUMA cell size configuration can be increased by hot-plugging of
+        memory to the limit specified by this element.
+
+        The <code>unit</code> attribute behaves the same as for
+        <code>&lt;memory&gt;</code>.
+
+        The <code>slots</code> attribute specifies the number of slots
+        available for adding memory to the guest. The bounds are hypervisor
+        specific.
+
+        Note that due to alignment of the memory chunks added via memory
+        hotplug the full size allocation specified by this element may be
+        impossible to achieve.
+        <span class='since'>Since 1.2.14</span>
+      </dd>
+
       <dt><code>currentMemory</code></dt>
       <dd>The actual allocation of memory for the guest. This value can
         be less than the maximum allocation, to allow for ballooning
index ebd9299371b68255d5a6cf9cbcdb3ae4dfd7dd9e..a0dee17123c63e9187f6c9e74f865c266cfc3d4d 100644 (file)
           </optional>
         </element>
       </optional>
+      <optional>
+        <element name="maxMemory">
+          <ref name="scaledInteger"/>
+          <attribute name="slots">
+            <ref name="unsignedInt"/>
+          </attribute>
+        </element>
+      </optional>
       <optional>
         <element name="currentMemory">
           <ref name='scaledInteger'/>
index ecb1758fc3431bfef01dcf04c3bbc77ab34be96f..25ef8524b021b0d674d633dc748ffdb76803adca 100644 (file)
@@ -67,6 +67,10 @@ bhyveDomainDefPostParse(virDomainDefPtr def,
                                        VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0)
         return -1;
 
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index ae7d8df8ed2b6a9e7542cd41bd256e7ab4ae1883..16b7bbd8f8b3efadeabf956213851fe2317cc9a2 100644 (file)
@@ -981,6 +981,27 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root,
 }
 
 
+/**
+ * virDomainDefCheckUnsupportedMemoryHotplug:
+ * @def: domain definition
+ *
+ * Returns -1 if the domain definition would enable memory hotplug via the
+ * <maxMemory> tunable and reports an error. Otherwise returns 0.
+ */
+int
+virDomainDefCheckUnsupportedMemoryHotplug(virDomainDefPtr def)
+{
+    /* memory hotplug tunables are not supported by this driver */
+    if (def->mem.max_memory > 0 || def->mem.memory_slots > 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("memory hotplug tunables <maxMemory> are not "
+                         "supported by this hypervisor driver"));
+        return -1;
+    }
+
+    return 0;
+}
+
 
 static void
 virDomainObjListDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
@@ -3238,6 +3259,22 @@ virDomainDefPostParseInternal(virDomainDefPtr def,
         def->mem.cur_balloon = virDomainDefGetMemoryActual(def);
     }
 
+    if ((def->mem.max_memory || def->mem.memory_slots) &&
+        !(def->mem.max_memory && def->mem.memory_slots)) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("both maximum memory size and "
+                         "memory slot count must be specified"));
+        return -1;
+    }
+
+    if (def->mem.max_memory &&
+        def->mem.max_memory < virDomainDefGetMemoryActual(def)) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("maximum memory size must be equal or greater than "
+                         "the actual memory size"));
+        return -1;
+    }
+
     /*
      * Some really crazy backcompat stuff for consoles
      *
@@ -13264,6 +13301,16 @@ virDomainDefParseXML(xmlDocPtr xml,
                              &def->mem.cur_balloon, false, true) < 0)
         goto error;
 
+    if (virDomainParseMemory("./maxMemory[1]", NULL, ctxt,
+                             &def->mem.max_memory, false, false) < 0)
+        goto error;
+
+    if (virXPathUInt("string(./maxMemory[1]/@slots)", ctxt, &def->mem.memory_slots) == -2) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("Failed to parse memory slot count"));
+        goto error;
+    }
+
     /* and info about it */
     if ((tmp = virXPathString("string(./memory[1]/@dumpCore)", ctxt)) &&
         (def->mem.dump_core = virTristateSwitchTypeFromString(tmp)) <= 0) {
@@ -16190,6 +16237,19 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
     if (!virDomainNumaCheckABIStability(src->numa, dst->numa))
         goto error;
 
+    if (src->mem.memory_slots != dst->mem.memory_slots) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain memory slots count '%u' doesn't match source '%u"),
+                       dst->mem.memory_slots, src->mem.memory_slots);
+        goto error;
+    }
+    if (src->mem.max_memory != dst->mem.max_memory) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target maximum memory size '%llu' doesn't match source '%llu'"),
+                       dst->mem.max_memory, src->mem.max_memory);
+        goto error;
+    }
+
     if (src->vcpus != dst->vcpus) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Target domain vCPU count %d does not match source %d"),
@@ -19879,6 +19939,12 @@ virDomainDefFormatInternal(virDomainDefPtr def,
         xmlIndentTreeOutput = oldIndentTreeOutput;
     }
 
+    if (def->mem.max_memory) {
+        virBufferAsprintf(buf,
+                          "<maxMemory slots='%u' unit='KiB'>%llu</maxMemory>\n",
+                          def->mem.memory_slots, def->mem.max_memory);
+    }
+
     virBufferAddLit(buf, "<memory");
     if (def->mem.dump_core)
         virBufferAsprintf(buf, " dumpCore='%s'",
index 9d314fa0c0b4598282a48c39d849eb0f73dbe867..bae9617f9baac04b740174ae23161b45720ba455 100644 (file)
@@ -2041,6 +2041,10 @@ struct _virDomainMemtune {
     virDomainHugePagePtr hugepages;
     size_t nhugepages;
 
+    /* maximum supported memory for a guest, for hotplugging */
+    unsigned long long max_memory; /* in kibibytes */
+    unsigned int memory_slots; /* maximum count of RAM memory slots */
+
     bool nosharepages;
     bool locked;
     int dump_core; /* enum virTristateSwitch */
@@ -2336,6 +2340,9 @@ virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
 bool virDomainObjTaint(virDomainObjPtr obj,
                        virDomainTaintFlags taint);
 
+
+int virDomainDefCheckUnsupportedMemoryHotplug(virDomainDefPtr def);
+
 void virDomainPanicDefFree(virDomainPanicDefPtr panic);
 void virDomainResourceDefFree(virDomainResourceDefPtr resource);
 void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def);
index 8141eba983d43a3467833bdc1d7df4068b26b4bd..9682589dcfff4006a12f18bedf6d22c40fc1f36d 100644 (file)
@@ -187,6 +187,7 @@ virDomainCpuPlacementModeTypeFromString;
 virDomainCpuPlacementModeTypeToString;
 virDomainDefAddImplicitControllers;
 virDomainDefCheckABIStability;
+virDomainDefCheckUnsupportedMemoryHotplug;
 virDomainDefClearCCWAddresses;
 virDomainDefClearDeviceAliases;
 virDomainDefClearPCIAddresses;
index 611ccf4214ba67dd7620b3a31ecf7c1970eb56b6..3843ae04deac74201006962f3968f53a8e91bdb9 100644 (file)
@@ -567,6 +567,11 @@ libxlDomainDefPostParse(virDomainDefPtr def,
         def->nconsoles = 1;
         def->consoles[0] = chrdef;
     }
+
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 55f5b49bb6decd5b4245c3ca30583fd25838638a..1367b0cf27483c6aef4cefa8a561807443b25c5c 100644 (file)
@@ -94,6 +94,10 @@ virLXCDomainDefPostParse(virDomainDefPtr def,
         !(def->emulator = virDomainDefGetDefaultEmulator(def, caps)))
         return -1;
 
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 71b0471e12e5adbae80209179ef953ce51e2e273..055670a55fa9cf6a38be72eb8e181cc8d04a72cf 100644 (file)
@@ -96,8 +96,15 @@ openvzDomainDefPostParse(virDomainDefPtr def,
                          void *opaque ATTRIBUTE_UNUSED)
 {
     /* fill the init path */
-    if (STREQ(def->os.type, "exe") && !def->os.init)
-        return VIR_STRDUP(def->os.init, "/sbin/init") < 0 ? -1 : 0;
+    if (STREQ(def->os.type, "exe") && !def->os.init) {
+        if (VIR_STRDUP(def->os.init, "/sbin/init") < 0)
+            return -1;
+    }
+
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 2a6a7c9b420a67cbdd9c9b28cdb241528b8b3ae3..f5e58a8fefbf6c2c1854ad5f18c1e181fed2482f 100644 (file)
@@ -161,10 +161,14 @@ parallelsConnectGetCapabilities(virConnectPtr conn)
 }
 
 static int
-parallelsDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED,
+parallelsDomainDefPostParse(virDomainDefPtr def,
                             virCapsPtr caps ATTRIBUTE_UNUSED,
                             void *opaque ATTRIBUTE_UNUSED)
 {
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 60a47ad22a799fc8e1ac6bd11c3b016e3aa90702..f4db2e0256ceac897a4fac7136ef2d2d92771701 100644 (file)
@@ -1094,10 +1094,14 @@ openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
 
 
 static int
-phypDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED,
+phypDomainDefPostParse(virDomainDefPtr def,
                        virCapsPtr caps ATTRIBUTE_UNUSED,
                        void *opaque ATTRIBUTE_UNUSED)
 {
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 949bf8b052ead7c7c02d413eb55f9c35d2b77003..8baa0402be1f42e74c116738fa23b89c7ba7e919 100644 (file)
@@ -1052,6 +1052,10 @@ qemuDomainDefPostParse(virDomainDefPtr def,
                                   VIR_DOMAIN_INPUT_BUS_USB) < 0)
         return -1;
 
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 27731f20bcf185f6e19c62dc2ff421d8673462c6..bdfc12e8e777382431e9848df657459f603fdf5b 100644 (file)
@@ -444,10 +444,14 @@ umlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
 
 
 static int
-umlDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED,
+umlDomainDefPostParse(virDomainDefPtr def,
                       virCapsPtr caps ATTRIBUTE_UNUSED,
                       void *opaque ATTRIBUTE_UNUSED)
 {
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 20211b21f14c3481ffaf73d20dc74a38a0b7422d..bb4de153ca68b41b905d0f70f19d45f039724aaf 100644 (file)
@@ -249,10 +249,14 @@ static char *vboxGenerateMediumName(PRUint32  storageBus,
 }
 
 static int
-vboxDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED,
+vboxDomainDefPostParse(virDomainDefPtr def,
                        virCapsPtr caps ATTRIBUTE_UNUSED,
                        void *opaque ATTRIBUTE_UNUSED)
 {
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 36f992b98321ca8f93275644992e4d490cd8814c..33829947b65c56e68451bb23e2509fcbbb650331 100644 (file)
@@ -83,10 +83,14 @@ vmwareDataFreeFunc(void *data)
 }
 
 static int
-vmwareDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED,
+vmwareDomainDefPostParse(virDomainDefPtr def,
                          virCapsPtr caps ATTRIBUTE_UNUSED,
                          void *opaque ATTRIBUTE_UNUSED)
 {
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 8cbf4d84f9f1421c19554e5569c0a8800da05108..8b814367b49d2dcdf003a4a00db864225bc03a13 100644 (file)
@@ -524,10 +524,14 @@ VIR_ENUM_IMPL(virVMXControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
  * Helpers
  */
 static int
-vmxDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED,
+vmxDomainDefPostParse(virDomainDefPtr def,
                       virCapsPtr caps ATTRIBUTE_UNUSED,
                       void *opaque ATTRIBUTE_UNUSED)
 {
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index 75778812f12d613236c26909f8ea377658f23829..b1042439052275c0ed6c2dd61c04001c7c68c909 100644 (file)
@@ -388,6 +388,10 @@ xenDomainDefPostParse(virDomainDefPtr def,
         def->memballoon = memballoon;
     }
 
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
index affc153bb7f73ccd9ac908800f187f6645ee4443..31344414d957f036a33babe66e97cd9d9a25686a 100644 (file)
@@ -70,10 +70,14 @@ xenapiDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
 
 
 static int
-xenapiDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED,
+xenapiDomainDefPostParse(virDomainDefPtr def,
                          virCapsPtr caps ATTRIBUTE_UNUSED,
                          void *opaque ATTRIBUTE_UNUSED)
 {
+    /* memory hotplug tunables are not supported by this driver */
+    if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+        return -1;
+
     return 0;
 }
 
diff --git a/tests/domainschemadata/maxMemory.xml b/tests/domainschemadata/maxMemory.xml
new file mode 100644 (file)
index 0000000..df2e3d8
--- /dev/null
@@ -0,0 +1,19 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <maxMemory slots='9' unit='KiB'>1233456789</maxMemory>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <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>