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> > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list