mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 03:21:19 +00:00
conf: Add interface to parse and format memory device information
This patch adds code that parses and formats configuration for memory devices. A simple configuration would be: <memory model='dimm'> <target> <size unit='KiB'>524287</size> <node>0</node> </target> </memory> A complete configuration of a memory device: <memory model='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.
This commit is contained in:
parent
62b825a2d0
commit
3e4230d270
@ -684,7 +684,9 @@
|
|||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt><code>memory</code></dt>
|
<dt><code>memory</code></dt>
|
||||||
<dd>The maximum allocation of memory for the guest at boot time.
|
<dd>The maximum allocation of memory for the guest at boot time. The
|
||||||
|
memory allocation includes possible additional memory devices specified
|
||||||
|
at start or hotplugged later.
|
||||||
The units for this value are determined by the optional
|
The units for this value are determined by the optional
|
||||||
attribute <code>unit</code>, which defaults to "KiB"
|
attribute <code>unit</code>, which defaults to "KiB"
|
||||||
(kibibytes, 2<sup>10</sup> or blocks of 1024 bytes). Valid
|
(kibibytes, 2<sup>10</sup> or blocks of 1024 bytes). Valid
|
||||||
@ -702,6 +704,9 @@
|
|||||||
supported by the hypervisor. Some hypervisors also enforce a
|
supported by the hypervisor. Some hypervisors also enforce a
|
||||||
minimum, such as 4000KiB.
|
minimum, such as 4000KiB.
|
||||||
|
|
||||||
|
In case <a href="#elementsCPU">NUMA</a> is configured for the guest the
|
||||||
|
<code>memory</code> element can be omitted.
|
||||||
|
|
||||||
In the case of crash, optional attribute <code>dumpCore</code>
|
In the case of crash, optional attribute <code>dumpCore</code>
|
||||||
can be used to control whether the guest memory should be
|
can be used to control whether the guest memory should be
|
||||||
included in the generated coredump or not (values "on", "off").
|
included in the generated coredump or not (values "on", "off").
|
||||||
@ -5951,6 +5956,91 @@ qemu-kvm -net nic,model=? /dev/null
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<h4><a name="elementsMemory">Memory devices</a></h4>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In addition to the initial memory assigned to the guest, memory devices
|
||||||
|
allow additional memory to be assigned to the guest in the form of
|
||||||
|
memory modules.
|
||||||
|
|
||||||
|
A memory device can be hot-plugged or hot-unplugged depending on the
|
||||||
|
guests' memory resource needs.
|
||||||
|
|
||||||
|
Some hypervisors may require NUMA configured for the guest.
|
||||||
|
<span class="since">Since 1.2.14</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Example: usage of the memory devices
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
...
|
||||||
|
<devices>
|
||||||
|
<memory model='dimm'>
|
||||||
|
<target>
|
||||||
|
<size unit='KiB'>524287</size>
|
||||||
|
<node>0</node>
|
||||||
|
</target>
|
||||||
|
</memory>
|
||||||
|
<memory model='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>dimm</code> model is supported in order to
|
||||||
|
add a virtual DIMM module to the guest.
|
||||||
|
</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.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code>pagesize</code> can optionally be used to override the default
|
||||||
|
host page size used for backing the memory device.
|
||||||
|
|
||||||
|
The configured value must correspond to a page size supported by the
|
||||||
|
host.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code>nodemask</code> can optionally be used to override the default
|
||||||
|
set of 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 of the added memory from the perspective of the guest.
|
||||||
|
</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>
|
<h3><a name="seclabel">Security label</a></h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -4071,6 +4071,7 @@
|
|||||||
<ref name="rng"/>
|
<ref name="rng"/>
|
||||||
<ref name="tpm"/>
|
<ref name="tpm"/>
|
||||||
<ref name="shmem"/>
|
<ref name="shmem"/>
|
||||||
|
<ref name="memorydev"/>
|
||||||
</choice>
|
</choice>
|
||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
<optional>
|
<optional>
|
||||||
@ -4487,6 +4488,55 @@
|
|||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
<define name="memorydev">
|
||||||
|
<element name="memory">
|
||||||
|
<attribute name="model">
|
||||||
|
<choice>
|
||||||
|
<value>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">
|
<define name="rng">
|
||||||
<element name="rng">
|
<element name="rng">
|
||||||
<attribute name="model">
|
<attribute name="model">
|
||||||
|
@ -75,11 +75,14 @@ bhyveDomainDefPostParse(virDomainDefPtr def,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bhyveDomainDeviceDefPostParse(virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
|
bhyveDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
||||||
const virDomainDef *def ATTRIBUTE_UNUSED,
|
const virDomainDef *def ATTRIBUTE_UNUSED,
|
||||||
virCapsPtr caps ATTRIBUTE_UNUSED,
|
virCapsPtr caps ATTRIBUTE_UNUSED,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +236,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
|
|||||||
"rng",
|
"rng",
|
||||||
"shmem",
|
"shmem",
|
||||||
"tpm",
|
"tpm",
|
||||||
"panic")
|
"panic",
|
||||||
|
"memory")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
|
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
|
||||||
"none",
|
"none",
|
||||||
@ -780,6 +781,9 @@ VIR_ENUM_DECL(virDomainBlockJob)
|
|||||||
VIR_ENUM_IMPL(virDomainBlockJob, VIR_DOMAIN_BLOCK_JOB_TYPE_LAST,
|
VIR_ENUM_IMPL(virDomainBlockJob, VIR_DOMAIN_BLOCK_JOB_TYPE_LAST,
|
||||||
"", "", "copy", "", "active-commit")
|
"", "", "copy", "", "active-commit")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainMemoryModel, VIR_DOMAIN_MEMORY_MODEL_LAST,
|
||||||
|
"", "dimm")
|
||||||
|
|
||||||
static virClassPtr virDomainObjClass;
|
static virClassPtr virDomainObjClass;
|
||||||
static virClassPtr virDomainObjListClass;
|
static virClassPtr virDomainObjListClass;
|
||||||
static virClassPtr virDomainXMLOptionClass;
|
static virClassPtr virDomainXMLOptionClass;
|
||||||
@ -1004,6 +1008,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
|
static void
|
||||||
virDomainObjListDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
|
virDomainObjListDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
@ -1937,6 +1962,16 @@ void virDomainRedirFilterDefFree(virDomainRedirFilterDefPtr def)
|
|||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void virDomainMemoryDefFree(virDomainMemoryDefPtr def)
|
||||||
|
{
|
||||||
|
if (!def)
|
||||||
|
return;
|
||||||
|
|
||||||
|
virBitmapFree(def->sourceNodes);
|
||||||
|
virDomainDeviceInfoClear(&def->info);
|
||||||
|
VIR_FREE(def);
|
||||||
|
}
|
||||||
|
|
||||||
void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
|
void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
|
||||||
{
|
{
|
||||||
if (!def)
|
if (!def)
|
||||||
@ -2006,6 +2041,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
|
|||||||
case VIR_DOMAIN_DEVICE_PANIC:
|
case VIR_DOMAIN_DEVICE_PANIC:
|
||||||
virDomainPanicDefFree(def->data.panic);
|
virDomainPanicDefFree(def->data.panic);
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
|
virDomainMemoryDefFree(def->data.memory);
|
||||||
|
break;
|
||||||
case VIR_DOMAIN_DEVICE_LAST:
|
case VIR_DOMAIN_DEVICE_LAST:
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
break;
|
break;
|
||||||
@ -2203,6 +2241,10 @@ void virDomainDefFree(virDomainDefPtr def)
|
|||||||
virDomainRNGDefFree(def->rngs[i]);
|
virDomainRNGDefFree(def->rngs[i]);
|
||||||
VIR_FREE(def->rngs);
|
VIR_FREE(def->rngs);
|
||||||
|
|
||||||
|
for (i = 0; i < def->nmems; i++)
|
||||||
|
virDomainMemoryDefFree(def->mems[i]);
|
||||||
|
VIR_FREE(def->mems);
|
||||||
|
|
||||||
virDomainTPMDefFree(def->tpm);
|
virDomainTPMDefFree(def->tpm);
|
||||||
|
|
||||||
virDomainPanicDefFree(def->panic);
|
virDomainPanicDefFree(def->panic);
|
||||||
@ -2744,6 +2786,8 @@ virDomainDeviceGetInfo(virDomainDeviceDefPtr device)
|
|||||||
return &device->data.tpm->info;
|
return &device->data.tpm->info;
|
||||||
case VIR_DOMAIN_DEVICE_PANIC:
|
case VIR_DOMAIN_DEVICE_PANIC:
|
||||||
return &device->data.panic->info;
|
return &device->data.panic->info;
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
|
return &device->data.memory->info;
|
||||||
|
|
||||||
/* The following devices do not contain virDomainDeviceInfo */
|
/* The following devices do not contain virDomainDeviceInfo */
|
||||||
case VIR_DOMAIN_DEVICE_LEASE:
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
@ -3064,6 +3108,13 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device.type = VIR_DOMAIN_DEVICE_MEMORY;
|
||||||
|
for (i = 0; i < def->nmems; i++) {
|
||||||
|
device.data.memory = def->mems[i];
|
||||||
|
if (cb(def, &device, &def->mems[i]->info, opaque) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Coverity is not very happy with this - all dead_error_condition */
|
/* Coverity is not very happy with this - all dead_error_condition */
|
||||||
#if !STATIC_ANALYSIS
|
#if !STATIC_ANALYSIS
|
||||||
/* This switch statement is here to trigger compiler warning when adding
|
/* This switch statement is here to trigger compiler warning when adding
|
||||||
@ -3096,6 +3147,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
|
|||||||
case VIR_DOMAIN_DEVICE_PANIC:
|
case VIR_DOMAIN_DEVICE_PANIC:
|
||||||
case VIR_DOMAIN_DEVICE_LAST:
|
case VIR_DOMAIN_DEVICE_LAST:
|
||||||
case VIR_DOMAIN_DEVICE_RNG:
|
case VIR_DOMAIN_DEVICE_RNG:
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -7083,10 +7135,16 @@ unsigned long long
|
|||||||
virDomainDefGetMemoryInitial(virDomainDefPtr def)
|
virDomainDefGetMemoryInitial(virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
unsigned long long ret;
|
unsigned long long ret;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
/* return NUMA memory size total in case numa is enabled */
|
/* return NUMA memory size total in case numa is enabled */
|
||||||
if ((ret = virDomainNumaGetMemorySize(def->numa)) > 0)
|
if ((ret = virDomainNumaGetMemorySize(def->numa)) > 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
} else {
|
||||||
|
ret = def->mem.max_balloon;
|
||||||
|
for (i = 0; i < def->nmems; i++)
|
||||||
|
ret -= def->mems[i]->size;
|
||||||
|
}
|
||||||
|
|
||||||
return def->mem.max_balloon;
|
return def->mem.max_balloon;
|
||||||
}
|
}
|
||||||
@ -7118,7 +7176,17 @@ virDomainDefSetMemoryInitial(virDomainDefPtr def,
|
|||||||
unsigned long long
|
unsigned long long
|
||||||
virDomainDefGetMemoryActual(virDomainDefPtr def)
|
virDomainDefGetMemoryActual(virDomainDefPtr def)
|
||||||
{
|
{
|
||||||
return virDomainDefGetMemoryInitial(def);
|
unsigned long long ret;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if ((ret = virDomainNumaGetMemorySize(def->numa)) > 0) {
|
||||||
|
for (i = 0; i < def->nmems; i++)
|
||||||
|
ret += def->mems[i]->size;
|
||||||
|
} else {
|
||||||
|
ret = def->mem.max_balloon;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -11477,6 +11545,119 @@ virDomainPMStateParseXML(xmlXPathContextPtr ctxt,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainMemorySourceDefParseXML(xmlNodePtr node,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
|
virDomainMemoryDefPtr def)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
char *nodemask = NULL;
|
||||||
|
xmlNodePtr save = ctxt->node;
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
if (virDomainParseMemory("./pagesize", "./pagesize/@unit", ctxt,
|
||||||
|
&def->pagesize, false, false) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((nodemask = virXPathString("string(./nodemask)", ctxt))) {
|
||||||
|
if (virBitmapParse(nodemask, 0, &def->sourceNodes,
|
||||||
|
VIR_DOMAIN_CPUMASK_LEN) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(nodemask);
|
||||||
|
ctxt->node = save;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainMemoryTargetDefParseXML(xmlNodePtr node,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
|
virDomainMemoryDefPtr def)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
xmlNodePtr save = ctxt->node;
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
if (virXPathUInt("string(./node)", ctxt, &def->targetNode) < 0) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("invalid or missing value of memory device node"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virDomainParseMemory("./size", "./size/@unit", ctxt,
|
||||||
|
&def->size, true, false) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
ctxt->node = save;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static virDomainMemoryDefPtr
|
||||||
|
virDomainMemoryDefParseXML(xmlNodePtr memdevNode,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
char *tmp = NULL;
|
||||||
|
xmlNodePtr save = ctxt->node;
|
||||||
|
xmlNodePtr node;
|
||||||
|
virDomainMemoryDefPtr def;
|
||||||
|
|
||||||
|
ctxt->node = memdevNode;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(def) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(tmp = virXMLPropString(memdevNode, "model"))) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("missing memory model"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((def->model = virDomainMemoryModelTypeFromString(tmp)) < 0) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("invalid memory model '%s'"), tmp);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
|
||||||
|
/* source */
|
||||||
|
if ((node = virXPathNode("./source", ctxt)) &&
|
||||||
|
virDomainMemorySourceDefParseXML(node, ctxt, def) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* target */
|
||||||
|
if (!(node = virXPathNode("./target", ctxt))) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("missing <target> element for <memory> device"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virDomainMemoryTargetDefParseXML(node, ctxt, def) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virDomainDeviceInfoParseXML(memdevNode, NULL, &def->info, flags) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return def;
|
||||||
|
|
||||||
|
error:
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
virDomainMemoryDefFree(def);
|
||||||
|
ctxt->node = save;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virDomainDeviceDefPtr
|
virDomainDeviceDefPtr
|
||||||
virDomainDeviceDefParse(const char *xmlStr,
|
virDomainDeviceDefParse(const char *xmlStr,
|
||||||
const virDomainDef *def,
|
const virDomainDef *def,
|
||||||
@ -11611,6 +11792,10 @@ virDomainDeviceDefParse(const char *xmlStr,
|
|||||||
if (!(dev->data.panic = virDomainPanicDefParseXML(node)))
|
if (!(dev->data.panic = virDomainPanicDefParseXML(node)))
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
|
if (!(dev->data.memory = virDomainMemoryDefParseXML(node, ctxt, flags)))
|
||||||
|
goto error;
|
||||||
|
break;
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
case VIR_DOMAIN_DEVICE_LAST:
|
case VIR_DOMAIN_DEVICE_LAST:
|
||||||
break;
|
break;
|
||||||
@ -15010,6 +15195,23 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
ctxt->node = node;
|
ctxt->node = node;
|
||||||
VIR_FREE(nodes);
|
VIR_FREE(nodes);
|
||||||
|
|
||||||
|
/* analysis of memory devices */
|
||||||
|
if ((n = virXPathNodeSet("./devices/memory", ctxt, &nodes)) < 0)
|
||||||
|
goto error;
|
||||||
|
if (n && VIR_ALLOC_N(def->mems, n) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
virDomainMemoryDefPtr mem = virDomainMemoryDefParseXML(nodes[i],
|
||||||
|
ctxt,
|
||||||
|
flags);
|
||||||
|
if (!mem)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
def->mems[def->nmems++] = mem;
|
||||||
|
}
|
||||||
|
VIR_FREE(nodes);
|
||||||
|
|
||||||
/* analysis of the user namespace mapping */
|
/* analysis of the user namespace mapping */
|
||||||
if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0)
|
if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -16249,6 +16451,39 @@ virDomainPanicDefCheckABIStability(virDomainPanicDefPtr src,
|
|||||||
return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
|
return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
virDomainMemoryDefCheckABIStability(virDomainMemoryDefPtr src,
|
||||||
|
virDomainMemoryDefPtr dst)
|
||||||
|
{
|
||||||
|
if (src->model != dst->model) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Target memory device model '%s' "
|
||||||
|
"doesn't match source model '%s'"),
|
||||||
|
virDomainMemoryModelTypeToString(dst->model),
|
||||||
|
virDomainMemoryModelTypeToString(src->model));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->targetNode != dst->targetNode) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Target memory device targetNode '%u' "
|
||||||
|
"doesn't match source targetNode '%u'"),
|
||||||
|
dst->targetNode, src->targetNode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->size != dst->size) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Target memory device size '%llu' doesn't match "
|
||||||
|
"source memory device size '%llu'"),
|
||||||
|
dst->size, src->size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This compares two configurations and looks for any differences
|
/* This compares two configurations and looks for any differences
|
||||||
* which will affect the guest ABI. This is primarily to allow
|
* which will affect the guest ABI. This is primarily to allow
|
||||||
* validation of custom XML config passed in during migration
|
* validation of custom XML config passed in during migration
|
||||||
@ -16667,6 +16902,18 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (src->nmems != dst->nmems) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Target domain memory device count %zu "
|
||||||
|
"does not match source %zu"), dst->nmems, src->nmems);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < src->nmems; i++) {
|
||||||
|
if (!virDomainMemoryDefCheckABIStability(src->mems[i], dst->mems[i]))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Coverity is not very happy with this - all dead_error_condition */
|
/* Coverity is not very happy with this - all dead_error_condition */
|
||||||
#if !STATIC_ANALYSIS
|
#if !STATIC_ANALYSIS
|
||||||
/* This switch statement is here to trigger compiler warning when adding
|
/* This switch statement is here to trigger compiler warning when adding
|
||||||
@ -16698,6 +16945,7 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
|
|||||||
case VIR_DOMAIN_DEVICE_TPM:
|
case VIR_DOMAIN_DEVICE_TPM:
|
||||||
case VIR_DOMAIN_DEVICE_PANIC:
|
case VIR_DOMAIN_DEVICE_PANIC:
|
||||||
case VIR_DOMAIN_DEVICE_SHMEM:
|
case VIR_DOMAIN_DEVICE_SHMEM:
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -19185,6 +19433,81 @@ virDomainRNGDefFree(virDomainRNGDefPtr def)
|
|||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainMemorySourceDefFormat(virBufferPtr buf,
|
||||||
|
virDomainMemoryDefPtr def)
|
||||||
|
{
|
||||||
|
char *bitmap = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!def->pagesize && !def->sourceNodes)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
virBufferAddLit(buf, "<source>\n");
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
if (def->sourceNodes) {
|
||||||
|
if (!(bitmap = virBitmapFormat(def->sourceNodes)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
virBufferAsprintf(buf, "<nodemask>%s</nodemask>\n", bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def->pagesize)
|
||||||
|
virBufferAsprintf(buf, "<pagesize unit='KiB'>%llu</pagesize>\n",
|
||||||
|
def->pagesize);
|
||||||
|
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</source>\n");
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(bitmap);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virDomainMemoryTargetDefFormat(virBufferPtr buf,
|
||||||
|
virDomainMemoryDefPtr def)
|
||||||
|
{
|
||||||
|
virBufferAddLit(buf, "<target>\n");
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
virBufferAsprintf(buf, "<size unit='KiB'>%llu</size>\n", def->size);
|
||||||
|
virBufferAsprintf(buf, "<node>%u</node>\n", def->targetNode);
|
||||||
|
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</target>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainMemoryDefFormat(virBufferPtr buf,
|
||||||
|
virDomainMemoryDefPtr def,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
const char *model = virDomainMemoryModelTypeToString(def->model);
|
||||||
|
|
||||||
|
virBufferAsprintf(buf, "<memory model='%s'>\n", model);
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
if (virDomainMemorySourceDefFormat(buf, def) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
virDomainMemoryTargetDefFormat(buf, def);
|
||||||
|
|
||||||
|
if (virDomainDeviceInfoNeedsFormat(&def->info, flags)) {
|
||||||
|
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</memory>\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virDomainVideoAccelDefFormat(virBufferPtr buf,
|
virDomainVideoAccelDefFormat(virBufferPtr buf,
|
||||||
virDomainVideoAccelDefPtr def)
|
virDomainVideoAccelDefPtr def)
|
||||||
@ -20771,6 +21094,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
|||||||
if (virDomainShmemDefFormat(buf, def->shmems[n], flags) < 0)
|
if (virDomainShmemDefFormat(buf, def->shmems[n], flags) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
for (n = 0; n < def->nmems; n++)
|
||||||
|
if (virDomainMemoryDefFormat(buf, def->mems[n], flags) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
virBufferAdjustIndent(buf, -2);
|
virBufferAdjustIndent(buf, -2);
|
||||||
virBufferAddLit(buf, "</devices>\n");
|
virBufferAddLit(buf, "</devices>\n");
|
||||||
|
|
||||||
@ -22175,6 +22502,9 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
|
|||||||
case VIR_DOMAIN_DEVICE_PANIC:
|
case VIR_DOMAIN_DEVICE_PANIC:
|
||||||
rc = virDomainPanicDefFormat(&buf, src->data.panic);
|
rc = virDomainPanicDefFormat(&buf, src->data.panic);
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
|
rc = virDomainMemoryDefFormat(&buf, src->data.memory, flags);
|
||||||
|
break;
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
||||||
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
||||||
|
@ -132,6 +132,9 @@ typedef virDomainIdMapDef *virDomainIdMapDefPtr;
|
|||||||
typedef struct _virDomainPanicDef virDomainPanicDef;
|
typedef struct _virDomainPanicDef virDomainPanicDef;
|
||||||
typedef virDomainPanicDef *virDomainPanicDefPtr;
|
typedef virDomainPanicDef *virDomainPanicDefPtr;
|
||||||
|
|
||||||
|
typedef struct _virDomainMemoryDef virDomainMemoryDef;
|
||||||
|
typedef virDomainMemoryDef *virDomainMemoryDefPtr;
|
||||||
|
|
||||||
/* forward declarations virDomainChrSourceDef, required by
|
/* forward declarations virDomainChrSourceDef, required by
|
||||||
* virDomainNetDef
|
* virDomainNetDef
|
||||||
*/
|
*/
|
||||||
@ -168,6 +171,7 @@ typedef enum {
|
|||||||
VIR_DOMAIN_DEVICE_SHMEM,
|
VIR_DOMAIN_DEVICE_SHMEM,
|
||||||
VIR_DOMAIN_DEVICE_TPM,
|
VIR_DOMAIN_DEVICE_TPM,
|
||||||
VIR_DOMAIN_DEVICE_PANIC,
|
VIR_DOMAIN_DEVICE_PANIC,
|
||||||
|
VIR_DOMAIN_DEVICE_MEMORY,
|
||||||
|
|
||||||
VIR_DOMAIN_DEVICE_LAST
|
VIR_DOMAIN_DEVICE_LAST
|
||||||
} virDomainDeviceType;
|
} virDomainDeviceType;
|
||||||
@ -198,6 +202,7 @@ struct _virDomainDeviceDef {
|
|||||||
virDomainShmemDefPtr shmem;
|
virDomainShmemDefPtr shmem;
|
||||||
virDomainTPMDefPtr tpm;
|
virDomainTPMDefPtr tpm;
|
||||||
virDomainPanicDefPtr panic;
|
virDomainPanicDefPtr panic;
|
||||||
|
virDomainMemoryDefPtr memory;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1969,6 +1974,28 @@ struct _virDomainRNGDef {
|
|||||||
virDomainDeviceInfo info;
|
virDomainDeviceInfo info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_DOMAIN_MEMORY_MODEL_NONE,
|
||||||
|
VIR_DOMAIN_MEMORY_MODEL_DIMM, /* dimm hotpluggable memory device */
|
||||||
|
|
||||||
|
VIR_DOMAIN_MEMORY_MODEL_LAST
|
||||||
|
} virDomainMemoryModel;
|
||||||
|
|
||||||
|
struct _virDomainMemoryDef {
|
||||||
|
/* source */
|
||||||
|
virBitmapPtr sourceNodes;
|
||||||
|
unsigned long long pagesize; /* kibibytes */
|
||||||
|
|
||||||
|
/* target */
|
||||||
|
int model; /* virDomainMemoryModel */
|
||||||
|
unsigned int targetNode;
|
||||||
|
unsigned long long size; /* kibibytes */
|
||||||
|
|
||||||
|
virDomainDeviceInfo info;
|
||||||
|
};
|
||||||
|
|
||||||
|
void virDomainMemoryDefFree(virDomainMemoryDefPtr def);
|
||||||
|
|
||||||
struct _virDomainIdMapEntry {
|
struct _virDomainIdMapEntry {
|
||||||
unsigned int start;
|
unsigned int start;
|
||||||
unsigned int target;
|
unsigned int target;
|
||||||
@ -2189,6 +2216,9 @@ struct _virDomainDef {
|
|||||||
size_t nshmems;
|
size_t nshmems;
|
||||||
virDomainShmemDefPtr *shmems;
|
virDomainShmemDefPtr *shmems;
|
||||||
|
|
||||||
|
size_t nmems;
|
||||||
|
virDomainMemoryDefPtr *mems;
|
||||||
|
|
||||||
/* Only 1 */
|
/* Only 1 */
|
||||||
virDomainWatchdogDefPtr watchdog;
|
virDomainWatchdogDefPtr watchdog;
|
||||||
virDomainMemballoonDefPtr memballoon;
|
virDomainMemballoonDefPtr memballoon;
|
||||||
@ -2351,6 +2381,7 @@ bool virDomainObjTaint(virDomainObjPtr obj,
|
|||||||
|
|
||||||
|
|
||||||
int virDomainDefCheckUnsupportedMemoryHotplug(virDomainDefPtr def);
|
int virDomainDefCheckUnsupportedMemoryHotplug(virDomainDefPtr def);
|
||||||
|
int virDomainDeviceDefCheckUnsupportedMemoryDevice(virDomainDeviceDefPtr dev);
|
||||||
|
|
||||||
void virDomainPanicDefFree(virDomainPanicDefPtr panic);
|
void virDomainPanicDefFree(virDomainPanicDefPtr panic);
|
||||||
void virDomainResourceDefFree(virDomainResourceDefPtr resource);
|
void virDomainResourceDefFree(virDomainResourceDefPtr resource);
|
||||||
@ -2899,6 +2930,8 @@ VIR_ENUM_DECL(virDomainRNGModel)
|
|||||||
VIR_ENUM_DECL(virDomainRNGBackend)
|
VIR_ENUM_DECL(virDomainRNGBackend)
|
||||||
VIR_ENUM_DECL(virDomainTPMModel)
|
VIR_ENUM_DECL(virDomainTPMModel)
|
||||||
VIR_ENUM_DECL(virDomainTPMBackend)
|
VIR_ENUM_DECL(virDomainTPMBackend)
|
||||||
|
VIR_ENUM_DECL(virDomainMemoryModel)
|
||||||
|
VIR_ENUM_DECL(virDomainMemoryBackingModel)
|
||||||
/* from libvirt.h */
|
/* from libvirt.h */
|
||||||
VIR_ENUM_DECL(virDomainState)
|
VIR_ENUM_DECL(virDomainState)
|
||||||
VIR_ENUM_DECL(virDomainNostateReason)
|
VIR_ENUM_DECL(virDomainNostateReason)
|
||||||
|
@ -216,6 +216,7 @@ virDomainDefSetMemoryInitial;
|
|||||||
virDomainDeleteConfig;
|
virDomainDeleteConfig;
|
||||||
virDomainDeviceAddressIsValid;
|
virDomainDeviceAddressIsValid;
|
||||||
virDomainDeviceAddressTypeToString;
|
virDomainDeviceAddressTypeToString;
|
||||||
|
virDomainDeviceDefCheckUnsupportedMemoryDevice;
|
||||||
virDomainDeviceDefCopy;
|
virDomainDeviceDefCopy;
|
||||||
virDomainDeviceDefFree;
|
virDomainDeviceDefFree;
|
||||||
virDomainDeviceDefParse;
|
virDomainDeviceDefParse;
|
||||||
@ -333,6 +334,7 @@ virDomainLockFailureTypeFromString;
|
|||||||
virDomainLockFailureTypeToString;
|
virDomainLockFailureTypeToString;
|
||||||
virDomainMemballoonModelTypeFromString;
|
virDomainMemballoonModelTypeFromString;
|
||||||
virDomainMemballoonModelTypeToString;
|
virDomainMemballoonModelTypeToString;
|
||||||
|
virDomainMemoryDefFree;
|
||||||
virDomainNetAppendIpAddress;
|
virDomainNetAppendIpAddress;
|
||||||
virDomainNetDefFormat;
|
virDomainNetDefFormat;
|
||||||
virDomainNetDefFree;
|
virDomainNetDefFree;
|
||||||
|
@ -538,6 +538,9 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +113,10 @@ virLXCDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
|||||||
dev->data.chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE)
|
dev->data.chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE)
|
||||||
dev->data.chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC;
|
dev->data.chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC;
|
||||||
|
|
||||||
|
|
||||||
|
if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +130,9 @@ openvzDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1200,6 +1200,9 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -7656,6 +7656,9 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
|
|||||||
dev->data.rng = NULL;
|
dev->data.rng = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/*TODO: implement later */
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
case VIR_DOMAIN_DEVICE_FS:
|
case VIR_DOMAIN_DEVICE_FS:
|
||||||
case VIR_DOMAIN_DEVICE_INPUT:
|
case VIR_DOMAIN_DEVICE_INPUT:
|
||||||
@ -7733,6 +7736,8 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
|
|||||||
case VIR_DOMAIN_DEVICE_RNG:
|
case VIR_DOMAIN_DEVICE_RNG:
|
||||||
ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng);
|
ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng);
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
|
/* TODO: Implement later */
|
||||||
case VIR_DOMAIN_DEVICE_FS:
|
case VIR_DOMAIN_DEVICE_FS:
|
||||||
case VIR_DOMAIN_DEVICE_INPUT:
|
case VIR_DOMAIN_DEVICE_INPUT:
|
||||||
case VIR_DOMAIN_DEVICE_SOUND:
|
case VIR_DOMAIN_DEVICE_SOUND:
|
||||||
@ -7850,6 +7855,7 @@ qemuDomainUpdateDeviceLive(virConnectPtr conn,
|
|||||||
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
||||||
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
||||||
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
case VIR_DOMAIN_DEVICE_CHR:
|
case VIR_DOMAIN_DEVICE_CHR:
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
case VIR_DOMAIN_DEVICE_TPM:
|
case VIR_DOMAIN_DEVICE_TPM:
|
||||||
@ -7992,6 +7998,9 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps,
|
|||||||
dev->data.rng = NULL;
|
dev->data.rng = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
|
/* TODO: implement later */
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_INPUT:
|
case VIR_DOMAIN_DEVICE_INPUT:
|
||||||
case VIR_DOMAIN_DEVICE_SOUND:
|
case VIR_DOMAIN_DEVICE_SOUND:
|
||||||
case VIR_DOMAIN_DEVICE_VIDEO:
|
case VIR_DOMAIN_DEVICE_VIDEO:
|
||||||
@ -8117,6 +8126,9 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
|
|||||||
virDomainRNGDefFree(virDomainRNGRemove(vmdef, idx));
|
virDomainRNGDefFree(virDomainRNGRemove(vmdef, idx));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
|
/* TODO: implement later */
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_INPUT:
|
case VIR_DOMAIN_DEVICE_INPUT:
|
||||||
case VIR_DOMAIN_DEVICE_SOUND:
|
case VIR_DOMAIN_DEVICE_SOUND:
|
||||||
case VIR_DOMAIN_DEVICE_VIDEO:
|
case VIR_DOMAIN_DEVICE_VIDEO:
|
||||||
@ -8223,6 +8235,7 @@ qemuDomainUpdateDeviceConfig(virQEMUCapsPtr qemuCaps,
|
|||||||
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
||||||
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
||||||
case VIR_DOMAIN_DEVICE_CHR:
|
case VIR_DOMAIN_DEVICE_CHR:
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
case VIR_DOMAIN_DEVICE_TPM:
|
case VIR_DOMAIN_DEVICE_TPM:
|
||||||
case VIR_DOMAIN_DEVICE_PANIC:
|
case VIR_DOMAIN_DEVICE_PANIC:
|
||||||
|
@ -3083,6 +3083,9 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
|
|||||||
qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng);
|
qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* TODO: implement later */
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMORY:
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
case VIR_DOMAIN_DEVICE_LEASE:
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
case VIR_DOMAIN_DEVICE_FS:
|
case VIR_DOMAIN_DEVICE_FS:
|
||||||
|
@ -439,6 +439,9 @@ umlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,6 +370,9 @@ xenDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,9 @@ xenapiDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virDomainDeviceDefCheckUnsupportedMemoryDevice(dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
50
tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.xml
Normal file
50
tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.xml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<maxMemory slots='16' unit='KiB'>1099511627776</maxMemory>
|
||||||
|
<memory unit='KiB'>1267710</memory>
|
||||||
|
<currentMemory unit='KiB'>1267710</currentMemory>
|
||||||
|
<vcpu placement='static' cpuset='0-1'>2</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='i686' machine='pc'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<cpu>
|
||||||
|
<topology sockets='2' cores='1' threads='1'/>
|
||||||
|
<numa>
|
||||||
|
<cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
|
||||||
|
</numa>
|
||||||
|
</cpu>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<disk type='block' device='disk'>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
<target dev='hda' bus='ide'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='ide' index='0'/>
|
||||||
|
<controller type='usb' index='0'/>
|
||||||
|
<controller type='pci' index='0' model='pci-root'/>
|
||||||
|
<memballoon model='virtio'/>
|
||||||
|
<memory model='dimm'>
|
||||||
|
<target>
|
||||||
|
<size unit='KiB'>524287</size>
|
||||||
|
<node>0</node>
|
||||||
|
</target>
|
||||||
|
</memory>
|
||||||
|
<memory model='dimm'>
|
||||||
|
<source>
|
||||||
|
<nodemask>1-3</nodemask>
|
||||||
|
<pagesize unit='KiB'>4096</pagesize>
|
||||||
|
</source>
|
||||||
|
<target>
|
||||||
|
<size unit='KiB'>524287</size>
|
||||||
|
<node>0</node>
|
||||||
|
</target>
|
||||||
|
</memory>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
Loading…
Reference in New Issue
Block a user