[libvirt] [PATCHv2.5 01/10] conf: Add support for parsing and formatting max memory and slot count
John Ferlan
jferlan at redhat.com
Fri Mar 13 03:46:26 UTC 2015
On 03/04/2015 11:24 AM, Peter Krempa wrote:
> 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.
> ---
> docs/formatdomain.html.in | 19 +++++++++++
> docs/schemas/domaincommon.rng | 8 +++++
> src/bhyve/bhyve_domain.c | 4 +++
> src/conf/domain_conf.c | 66 ++++++++++++++++++++++++++++++++++++
> src/conf/domain_conf.h | 7 ++++
> src/libvirt_private.syms | 1 +
> src/libxl/libxl_domain.c | 5 +++
> src/lxc/lxc_domain.c | 4 +++
> src/openvz/openvz_driver.c | 11 ++++--
> src/parallels/parallels_driver.c | 6 +++-
> src/phyp/phyp_driver.c | 6 +++-
> src/qemu/qemu_domain.c | 4 +++
> src/uml/uml_driver.c | 6 +++-
> src/vbox/vbox_common.c | 6 +++-
> src/vmware/vmware_driver.c | 6 +++-
> src/vmx/vmx.c | 6 +++-
> src/xen/xen_driver.c | 4 +++
> src/xenapi/xenapi_driver.c | 6 +++-
> tests/domainschemadata/maxMemory.xml | 19 +++++++++++
> 19 files changed, 185 insertions(+), 9 deletions(-)
> create mode 100644 tests/domainschemadata/maxMemory.xml
>
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index 6276a61..1f0f770 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -675,6 +675,7 @@
> <pre>
> <domain>
> ...
> + <maxMemory slots='16' unit='KiB'>1524288</maxMemory>
> <memory unit='KiB'>524288</memory>
> <currentMemory unit='KiB'>524288</currentMemory>
> ...
> @@ -708,6 +709,24 @@
> <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 <code><memory></code> can be increased by
> + hot-plugging of memory to the limit specified by this element.
Given the series I just reviewed - perhaps this needs a tweak to include
<memory> or <numa>
> +
> + The <code>unit</code> attribute behaves the same as for
> + <code>memory</code>.
<memory>
> +
> + 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 3272ad1..8e107e6 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 ecb1758..25ef852 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 84a9938..4d765f9 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -980,6 +980,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)
> @@ -3196,6 +3217,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
> *
> @@ -13150,6 +13187,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;
> + }
Should the virStrToLong_uip be used here?
> +
> /* and info about it */
> if ((tmp = virXPathString("string(./memory[1]/@dumpCore)", ctxt)) &&
> (def->mem.dump_core = virTristateSwitchTypeFromString(tmp)) <= 0) {
> @@ -16076,6 +16123,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"),
> @@ -19760,6 +19820,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 e27f7b2..3537b32 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2038,6 +2038,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 */
> @@ -2333,6 +2337,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 a217954..1289884 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 21c41d7..5d186c3 100644
> --- a/src/libxl/libxl_domain.c
> +++ b/src/libxl/libxl_domain.c
> @@ -576,6 +576,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;
> +
At the top of this function there's:
if (STREQ(def->os.type, "hvm"))
return 0;
So should this check go before that?
Everything else seems fine - ACK
John
> return 0;
> }
>
> diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
> index 55f5b49..1367b0c 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 f03fedb..8cc392e 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 bb3928a..9129940 100644
> --- a/src/parallels/parallels_driver.c
> +++ b/src/parallels/parallels_driver.c
> @@ -154,10 +154,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 60a47ad..f4db2e0 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 e5f11fc..5c31fb2 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 27731f2..bdfc12e 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 6697ecc..f3e72b8 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 36f992b..3382994 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 95c081b..7cfe1af 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 5e6ef68..f603477 100644
> --- a/src/xen/xen_driver.c
> +++ b/src/xen/xen_driver.c
> @@ -390,6 +390,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 b3dd852..c6acfc9 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 0000000..df2e3d8
> --- /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>
>
More information about the libvir-list
mailing list