[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