On Thu, Feb 19, 2015 at 04:38:30PM +0100, Peter Krempa wrote:
This patch adds code that parses and formats configuration for memory
devices.
A simple configuration would be:
<memory model='acpi-dimm'>
<target>
<size unit='KiB'>524287</size>
<node>0</node>
</target>
</memory>
A complete configuration of a memory device:
<memory model='acpi-dimm'>
<source>
<pagesize unit='KiB'>4096</pagesize>
<nodemask>1-3</nodemask>
</source>
<target>
<size unit='KiB'>524287</size>
<node>1</node>
</target>
</memory>
This patch preemptively forbids use of the <memory> device in individual
drivers so the users are warned right away that the device is not
supported.
---
docs/formatdomain.html.in | 79 +++++
docs/schemas/domaincommon.rng | 50 ++++
src/bhyve/bhyve_domain.c | 5 +-
src/conf/domain_conf.c | 326 ++++++++++++++++++++-
src/conf/domain_conf.h | 33 +++
src/libvirt_private.syms | 2 +
src/libxl/libxl_domain.c | 3 +
src/lxc/lxc_domain.c | 4 +
src/openvz/openvz_driver.c | 3 +
src/qemu/qemu_domain.c | 3 +
src/qemu/qemu_driver.c | 13 +
src/qemu/qemu_hotplug.c | 3 +
src/uml/uml_driver.c | 3 +
src/xen/xen_driver.c | 3 +
src/xenapi/xenapi_driver.c | 3 +
.../qemuxml2argv-memory-hotplug-dimm.xml | 50 ++++
16 files changed, 580 insertions(+), 3 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 6320703..881e941 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -5866,6 +5866,85 @@ qemu-kvm -net nic,model=? /dev/null
</dd>
</dl>
+ <h4><a name="elementsMemory">Memory
devices</a></h4>
+
+ <p>
+ Apart from initial memory the memory device allow to add additional
Either "memory device allows adding additional" or "memory devices
allow adding ..."
+ memory for the guest in form of memory modules. These devices
also allow
+ hot-add and hot-remove of guest's memory.
+ <span class="since">Since 1.2.13</span>
+ </p>
+
+ <p>
+ Example: usage of the memory devices
+ </p>
+<pre>
+ ...
+ <devices>
+ <memory model='acpi-dimm'>
+ <target>
+ <size unit='KiB'>524287</size>
+ <node>0</node>
+ </target>
+ </memory>
+ <memory model='acpi-dimm'>
+ <source>
+ <pagesize unit='KiB'>4096</pagesize>
+ <nodemask>1-3</nodemask>
+ </source>
+ <target>
+ <size unit='KiB'>524287</size>
+ <node>1</node>
+ </target>
+ </memory>
+ </devices>
+ ...
+</pre>
+ <dl>
+ <dt><code>model</code></dt>
+ <dd>
+ <p>
+ Currently only the <code>acpi-dimm</code> model is supported that
Don't forget to s/acpi-dimm/dimm/ all of these (and sorry for the
added work).
+ will result in adding a virtual DIMM module to the guest.
Note that
+ hypervisors require having NUMA enabled for the guest for the memory
+ modules to work.
+ </p>
+ </dd>
+
+ <dt><code>source</code></dt>
+ <dd>
+ <p>
+ The optional source element allows to fine tune the source of the
+ memory used for the given memory device. If the element is not
+ provided defaults configured via <code>numatune</code> are used.
Seems like too much of "the", but I'm not native speaker.
+ </p>
+ <p>
+ <code>pagesize</code> can be used to override the default host
page
+ size used for backing of the memory device.
s/backing of/backing/ ?
+ </p>
+ <p>
+ <code>nodemask</code> can be used to override the default set of
NUMA
s/NUMA/NUMA nodes/ ?
+ where the memory would be allocated.
+ </p>
+ </dd>
+
+ <dt><code>target</code></dt>
+ <dd>
+ <p>
+ The mandatory <code>target</code> element configures the placement
and
+ sizing the added memory from the perspective of the guest.
s/sizing/sizing of/ ?
+ </p>
+ <p>
+ The mandatory <code>size</code> subelement configures the size of
the
+ added memory as a scaled integer.
+ </p>
+ <p>
+ The mandatory <code>node</code> subelement configures the guest
NUMA
+ node to attach the memory to.
+ </p>
+ </dd>
+ </dl>
+
<h3><a name="seclabel">Security label</a></h3>
<p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 1824741..a8c17a8 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4034,6 +4034,7 @@
<ref name="rng"/>
<ref name="tpm"/>
<ref name="shmem"/>
+ <ref name="memorydev"/>
</choice>
</zeroOrMore>
<optional>
@@ -4445,6 +4446,55 @@
</element>
</define>
+ <define name="memorydev">
+ <element name="memory">
+ <attribute name="model">
+ <choice>
+ <value>acpi-dimm</value>
+ </choice>
+ </attribute>
+ <interleave>
+ <optional>
+ <ref name="memorydev-source"/>
+ </optional>
+ <ref name="memorydev-target"/>
+ <optional>
+ <ref name="address"/>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+
+ <define name="memorydev-source">
+ <element name="source">
+ <interleave>
+ <optional>
+ <element name="pagesize">
+ <ref name="scaledInteger"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="nodemask">
+ <ref name="cpuset"/>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+
+ <define name="memorydev-target">
+ <element name="target">
+ <interleave>
+ <element name="size">
+ <ref name="scaledInteger"/>
+ </element>
+ <element name="node">
+ <ref name="unsignedInt"/>
+ </element>
+ </interleave>
+ </element>
+ </define>
+
<define name="rng">
<element name="rng">
<attribute name="model">
diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c
index 25ef852..890963e 100644
--- a/src/bhyve/bhyve_domain.c
+++ b/src/bhyve/bhyve_domain.c
@@ -75,11 +75,14 @@ bhyveDomainDefPostParse(virDomainDefPtr def,
}
static int
-bhyveDomainDeviceDefPostParse(virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+bhyveDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
const virDomainDef *def ATTRIBUTE_UNUSED,
virCapsPtr caps ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
+ if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
+ return -1;
+
return 0;
}
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b5d9c6f..3eb1426 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -236,7 +236,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
"rng",
"shmem",
"tpm",
- "panic")
+ "panic",
+ "memory")
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"none",
@@ -786,6 +787,12 @@ VIR_ENUM_DECL(virDomainBlockJob)
VIR_ENUM_IMPL(virDomainBlockJob, VIR_DOMAIN_BLOCK_JOB_TYPE_LAST,
"", "", "copy", "",
"active-commit")
+VIR_ENUM_IMPL(virDomainMemoryModel, VIR_DOMAIN_MEMORY_MODEL_LAST,
+ "", "acpi-dimm")
+
+#define VIR_DOMAIN_XML_WRITE_FLAGS VIR_DOMAIN_XML_SECURE
+#define VIR_DOMAIN_XML_READ_FLAGS VIR_DOMAIN_XML_INACTIVE
+
These two shouldn't be here I guess.
static virClassPtr virDomainObjClass;
static virClassPtr virDomainObjListClass;
static virClassPtr virDomainXMLOptionClass;
@@ -1010,6 +1017,27 @@ virDomainDefCheckUnsupportedMemoryHotplug(virDomainDefPtr def)
}
+/**
+ * virDomainDeviceDefCheckUnsupportedMemoryDevice:
+ * @dev: device definition
+ *
+ * Returns -1 if the device definition describes a memory device and reports an
+ * error. Otherwise returns 0.
+ */
+int
+virDomainDeviceDefCheckUnsupportedMemoryDevice(virDomainDeviceDefPtr dev)
+{
+ /* This driver doesn't yet know how to handle memory devices */
+ if (dev->type == VIR_DOMAIN_DEVICE_MEMORY) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("memory devices are not supported by this driver"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
static void
virDomainObjListDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
{
@@ -1941,6 +1969,15 @@ void virDomainRedirFilterDefFree(virDomainRedirFilterDefPtr def)
VIR_FREE(def);
}
+void virDomainMemoryDefFree(virDomainMemoryDefPtr def)
+{
+ if (!def)
+ return;
+
You're not cleaning def->sourceNodes here.
I'll continue the review tomorrow.