<pre>
<domain>
...
+ <maxMemory slots='16' unit='KiB'>1524288</maxMemory>
<memory unit='KiB'>524288</memory>
<currentMemory unit='KiB'>524288</currentMemory>
...
<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><memory></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><memory></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
</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'/>
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;
}
}
+/**
+ * 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)
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
*
&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) {
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"),
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'",
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 */
bool virDomainObjTaint(virDomainObjPtr obj,
virDomainTaintFlags taint);
+
+int virDomainDefCheckUnsupportedMemoryHotplug(virDomainDefPtr def);
+
void virDomainPanicDefFree(virDomainPanicDefPtr panic);
void virDomainResourceDefFree(virDomainResourceDefPtr resource);
void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def);
virDomainCpuPlacementModeTypeToString;
virDomainDefAddImplicitControllers;
virDomainDefCheckABIStability;
+virDomainDefCheckUnsupportedMemoryHotplug;
virDomainDefClearCCWAddresses;
virDomainDefClearDeviceAliases;
virDomainDefClearPCIAddresses;
def->nconsoles = 1;
def->consoles[0] = chrdef;
}
+
+ /* memory hotplug tunables are not supported by this driver */
+ if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+ return -1;
+
return 0;
}
!(def->emulator = virDomainDefGetDefaultEmulator(def, caps)))
return -1;
+ /* memory hotplug tunables are not supported by this driver */
+ if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+ return -1;
+
return 0;
}
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;
}
}
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;
}
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;
}
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;
}
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;
}
}
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;
}
}
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;
}
* 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;
}
def->memballoon = memballoon;
}
+ /* memory hotplug tunables are not supported by this driver */
+ if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
+ return -1;
+
return 0;
}
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;
}
--- /dev/null
+<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>