summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/formatdomain.html.in20
-rw-r--r--docs/schemas/domaincommon.rng8
-rw-r--r--src/bhyve/bhyve_domain.c4
-rw-r--r--src/conf/domain_conf.c66
-rw-r--r--src/conf/domain_conf.h7
-rw-r--r--src/libvirt_private.syms1
-rw-r--r--src/libxl/libxl_domain.c5
-rw-r--r--src/lxc/lxc_domain.c4
-rw-r--r--src/openvz/openvz_driver.c11
-rw-r--r--src/parallels/parallels_driver.c6
-rw-r--r--src/phyp/phyp_driver.c6
-rw-r--r--src/qemu/qemu_domain.c4
-rw-r--r--src/uml/uml_driver.c6
-rw-r--r--src/vbox/vbox_common.c6
-rw-r--r--src/vmware/vmware_driver.c6
-rw-r--r--src/vmx/vmx.c6
-rw-r--r--src/xen/xen_driver.c4
-rw-r--r--src/xenapi/xenapi_driver.c6
-rw-r--r--tests/domainschemadata/maxMemory.xml19
19 files changed, 186 insertions, 9 deletions
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index be35c82e7d..cc80efa73d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -675,6 +675,7 @@
<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;
...
@@ -708,6 +709,25 @@
<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
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index ebd9299371..a0dee17123 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -593,6 +593,14 @@
</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'/>
</element>
diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c
index ecb1758fc3..25ef8524b0 100644
--- a/src/bhyve/bhyve_domain.c
+++ b/src/bhyve/bhyve_domain.c
@@ -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;
}
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ae7d8df8ed..16b7bbd8f8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -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'",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9d314fa0c0..bae9617f9b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -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);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8141eba983..9682589dcf 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -187,6 +187,7 @@ virDomainCpuPlacementModeTypeFromString;
virDomainCpuPlacementModeTypeToString;
virDomainDefAddImplicitControllers;
virDomainDefCheckABIStability;
+virDomainDefCheckUnsupportedMemoryHotplug;
virDomainDefClearCCWAddresses;
virDomainDefClearDeviceAliases;
virDomainDefClearPCIAddresses;
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 611ccf4214..3843ae04de 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -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;
}
diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
index 55f5b49bb6..1367b0cf27 100644
--- a/src/lxc/lxc_domain.c
+++ b/src/lxc/lxc_domain.c
@@ -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;
}
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 71b0471e12..055670a55f 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -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;
}
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index 2a6a7c9b42..f5e58a8fef 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -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;
}
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index 60a47ad22a..f4db2e0256 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -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;
}
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 949bf8b052..8baa0402be 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -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;
}
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 27731f20bc..bdfc12e8e7 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -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;
}
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 20211b21f1..bb4de153ca 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -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;
}
diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
index 36f992b983..33829947b6 100644
--- a/src/vmware/vmware_driver.c
+++ b/src/vmware/vmware_driver.c
@@ -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;
}
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index 8cbf4d84f9..8b814367b4 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -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;
}
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 75778812f1..b104243905 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -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;
}
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index affc153bb7..31344414d9 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -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
index 0000000000..df2e3d8e42
--- /dev/null
+++ b/tests/domainschemadata/maxMemory.xml
@@ -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>