提交 bc6d3121 编写于 作者: J Jaroslav Safka 提交者: Michal Privoznik

conf: Add new xml elements for file memorybacking support

This part introduces new xml elements for file based
memorybacking support and their parsing.
(It allows vhost-user to be used without hugepages.)

New xml elements:
<memoryBacking>
  <source type="file|anonymous"/>
  <access mode="shared|private"/>
  <allocation mode="immediate|ondemand"/>
</memoryBacking>
上级 48d9e6cd
...@@ -903,6 +903,9 @@ ...@@ -903,6 +903,9 @@
&lt;/hugepages&gt; &lt;/hugepages&gt;
&lt;nosharepages/&gt; &lt;nosharepages/&gt;
&lt;locked/&gt; &lt;locked/&gt;
&lt;source type="file|anonymous"/&gt;
&lt;access mode="shared|private"/&gt;
&lt;allocation mode="immediate|ondemand"/&gt;
&lt;/memoryBacking&gt; &lt;/memoryBacking&gt;
... ...
&lt;/domain&gt; &lt;/domain&gt;
...@@ -942,6 +945,12 @@ ...@@ -942,6 +945,12 @@
most of the host's memory). Doing so may be dangerous to both the most of the host's memory). Doing so may be dangerous to both the
domain and the host itself since the host's kernel may run out of domain and the host itself since the host's kernel may run out of
memory. <span class="since">Since 1.0.6</span></dd> memory. <span class="since">Since 1.0.6</span></dd>
<dt><code>source</code></dt>
<dd>In this attribute you can switch to file memorybacking or keep default anonymous.</dd>
<dt><code>access</code></dt>
<dd>Specify if memory is shared or private. This can be overridden per numa node by <code>memAccess</code></dd>
<dt><code>allocation</code></dt>
<dd>Specify when allocate the memory</dd>
</dl> </dl>
......
...@@ -565,6 +565,36 @@ ...@@ -565,6 +565,36 @@
<empty/> <empty/>
</element> </element>
</optional> </optional>
<optional>
<element name="source">
<attribute name="type">
<choice>
<value>file</value>
<value>anonymous</value>
</choice>
</attribute>
</element>
</optional>
<optional>
<element name="access">
<attribute name="mode">
<choice>
<value>shared</value>
<value>private</value>
</choice>
</attribute>
</element>
</optional>
<optional>
<element name="allocation">
<attribute name="mode">
<choice>
<value>immediate</value>
<value>ondemand</value>
</choice>
</attribute>
</element>
</optional>
</interleave> </interleave>
</element> </element>
</optional> </optional>
......
...@@ -837,6 +837,16 @@ VIR_ENUM_IMPL(virDomainDiskMirrorState, VIR_DOMAIN_DISK_MIRROR_STATE_LAST, ...@@ -837,6 +837,16 @@ VIR_ENUM_IMPL(virDomainDiskMirrorState, VIR_DOMAIN_DISK_MIRROR_STATE_LAST,
"abort", "abort",
"pivot") "pivot")
VIR_ENUM_IMPL(virDomainMemorySource, VIR_DOMAIN_MEMORY_SOURCE_LAST,
"none",
"file",
"anonymous")
VIR_ENUM_IMPL(virDomainMemoryAllocation, VIR_DOMAIN_MEMORY_ALLOCATION_LAST,
"none",
"immediate",
"ondemand")
VIR_ENUM_IMPL(virDomainLoader, VIR_ENUM_IMPL(virDomainLoader,
VIR_DOMAIN_LOADER_TYPE_LAST, VIR_DOMAIN_LOADER_TYPE_LAST,
"rom", "rom",
...@@ -16594,48 +16604,93 @@ virDomainDefParseXML(xmlDocPtr xml, ...@@ -16594,48 +16604,93 @@ virDomainDefParseXML(xmlDocPtr xml,
} }
VIR_FREE(tmp); VIR_FREE(tmp);
if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) { tmp = virXPathString("string(./memoryBacking/source/@type)", ctxt);
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", if (tmp) {
_("cannot extract hugepages nodes")); if ((def->mem.source = virDomainMemorySourceTypeFromString(tmp)) < 0) {
goto error; virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown memoryBacking/source/type '%s'"), tmp);
goto error;
}
VIR_FREE(tmp);
} }
if (n) { tmp = virXPathString("string(./memoryBacking/access/@mode)", ctxt);
if (VIR_ALLOC_N(def->mem.hugepages, n) < 0) if (tmp) {
if ((def->mem.access = virDomainMemoryAccessTypeFromString(tmp)) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown memoryBacking/access/mode '%s'"), tmp);
goto error; goto error;
}
VIR_FREE(tmp);
}
for (i = 0; i < n; i++) { tmp = virXPathString("string(./memoryBacking/allocation/@mode)", ctxt);
if (virDomainHugepagesParseXML(nodes[i], ctxt, if (tmp) {
&def->mem.hugepages[i]) < 0) if ((def->mem.allocation = virDomainMemoryAllocationTypeFromString(tmp)) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown memoryBacking/allocation/mode '%s'"), tmp);
goto error;
}
VIR_FREE(tmp);
}
if (virXPathNode("./memoryBacking/hugepages", ctxt)) {
/* hugepages will be used */
if (def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_ONDEMAND) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("hugepages are not allowed with memory allocation ondemand"));
goto error;
}
if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_ANONYMOUS) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("hugepages are not allowed with anonymous memory source"));
goto error;
}
if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot extract hugepages nodes"));
goto error;
}
if (n) {
if (VIR_ALLOC_N(def->mem.hugepages, n) < 0)
goto error; goto error;
def->mem.nhugepages++;
for (j = 0; j < i; j++) { for (i = 0; i < n; i++) {
if (def->mem.hugepages[i].nodemask && if (virDomainHugepagesParseXML(nodes[i], ctxt,
def->mem.hugepages[j].nodemask && &def->mem.hugepages[i]) < 0)
virBitmapOverlaps(def->mem.hugepages[i].nodemask,
def->mem.hugepages[j].nodemask)) {
virReportError(VIR_ERR_XML_DETAIL,
_("nodeset attribute of hugepages "
"of sizes %llu and %llu intersect"),
def->mem.hugepages[i].size,
def->mem.hugepages[j].size);
goto error;
} else if (!def->mem.hugepages[i].nodemask &&
!def->mem.hugepages[j].nodemask) {
virReportError(VIR_ERR_XML_DETAIL,
_("two master hugepages detected: "
"%llu and %llu"),
def->mem.hugepages[i].size,
def->mem.hugepages[j].size);
goto error; goto error;
def->mem.nhugepages++;
for (j = 0; j < i; j++) {
if (def->mem.hugepages[i].nodemask &&
def->mem.hugepages[j].nodemask &&
virBitmapOverlaps(def->mem.hugepages[i].nodemask,
def->mem.hugepages[j].nodemask)) {
virReportError(VIR_ERR_XML_DETAIL,
_("nodeset attribute of hugepages "
"of sizes %llu and %llu intersect"),
def->mem.hugepages[i].size,
def->mem.hugepages[j].size);
goto error;
} else if (!def->mem.hugepages[i].nodemask &&
!def->mem.hugepages[j].nodemask) {
virReportError(VIR_ERR_XML_DETAIL,
_("two master hugepages detected: "
"%llu and %llu"),
def->mem.hugepages[i].size,
def->mem.hugepages[j].size);
goto error;
}
} }
} }
}
VIR_FREE(nodes); VIR_FREE(nodes);
} else { } else {
if ((node = virXPathNode("./memoryBacking/hugepages", ctxt))) { /* no hugepage pages */
if (VIR_ALLOC(def->mem.hugepages) < 0) if (VIR_ALLOC(def->mem.hugepages) < 0)
goto error; goto error;
...@@ -23728,7 +23783,9 @@ virDomainDefFormatInternal(virDomainDefPtr def, ...@@ -23728,7 +23783,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAddLit(buf, "</memtune>\n"); virBufferAddLit(buf, "</memtune>\n");
} }
if (def->mem.nhugepages || def->mem.nosharepages || def->mem.locked) { if (def->mem.nhugepages || def->mem.nosharepages || def->mem.locked
|| def->mem.source || def->mem.access || def->mem.allocation)
{
virBufferAddLit(buf, "<memoryBacking>\n"); virBufferAddLit(buf, "<memoryBacking>\n");
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
if (def->mem.nhugepages) if (def->mem.nhugepages)
...@@ -23737,6 +23794,16 @@ virDomainDefFormatInternal(virDomainDefPtr def, ...@@ -23737,6 +23794,16 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAddLit(buf, "<nosharepages/>\n"); virBufferAddLit(buf, "<nosharepages/>\n");
if (def->mem.locked) if (def->mem.locked)
virBufferAddLit(buf, "<locked/>\n"); virBufferAddLit(buf, "<locked/>\n");
if (def->mem.source)
virBufferAsprintf(buf, "<source type='%s'/>\n",
virDomainMemorySourceTypeToString(def->mem.source));
if (def->mem.access)
virBufferAsprintf(buf, "<access mode='%s'/>\n",
virDomainMemoryAccessTypeToString(def->mem.access));
if (def->mem.allocation)
virBufferAsprintf(buf, "<allocation mode='%s'/>\n",
virDomainMemoryAllocationTypeToString(def->mem.allocation));
virBufferAdjustIndent(buf, -2); virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</memoryBacking>\n"); virBufferAddLit(buf, "</memoryBacking>\n");
} }
......
...@@ -586,6 +586,22 @@ typedef enum { ...@@ -586,6 +586,22 @@ typedef enum {
VIR_DOMAIN_DISK_MIRROR_STATE_LAST VIR_DOMAIN_DISK_MIRROR_STATE_LAST
} virDomainDiskMirrorState; } virDomainDiskMirrorState;
typedef enum {
VIR_DOMAIN_MEMORY_SOURCE_NONE = 0, /* No memory source defined */
VIR_DOMAIN_MEMORY_SOURCE_FILE, /* Memory source is set as file */
VIR_DOMAIN_MEMORY_SOURCE_ANONYMOUS, /* Memory source is set as anonymous */
VIR_DOMAIN_MEMORY_SOURCE_LAST,
} virDomainMemorySource;
typedef enum {
VIR_DOMAIN_MEMORY_ALLOCATION_NONE = 0, /* No memory allocation defined */
VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE, /* Memory allocation is set as immediate */
VIR_DOMAIN_MEMORY_ALLOCATION_ONDEMAND, /* Memory allocation is set as ondemand */
VIR_DOMAIN_MEMORY_ALLOCATION_LAST,
} virDomainMemoryAllocation;
/* Stores the virtual disk configuration */ /* Stores the virtual disk configuration */
struct _virDomainDiskDef { struct _virDomainDiskDef {
...@@ -2130,6 +2146,10 @@ struct _virDomainMemtune { ...@@ -2130,6 +2146,10 @@ struct _virDomainMemtune {
unsigned long long soft_limit; /* in kibibytes, limit at off_t bytes */ unsigned long long soft_limit; /* in kibibytes, limit at off_t bytes */
unsigned long long min_guarantee; /* in kibibytes, limit at off_t bytes */ unsigned long long min_guarantee; /* in kibibytes, limit at off_t bytes */
unsigned long long swap_hard_limit; /* in kibibytes, limit at off_t bytes */ unsigned long long swap_hard_limit; /* in kibibytes, limit at off_t bytes */
int source; /* enum virDomainMemorySource */
int access; /* enum virDomainMemoryAccess */
int allocation; /* enum virDomainMemoryAllocation */
}; };
typedef struct _virDomainPowerManagement virDomainPowerManagement; typedef struct _virDomainPowerManagement virDomainPowerManagement;
...@@ -3115,6 +3135,8 @@ VIR_ENUM_DECL(virDomainTPMModel) ...@@ -3115,6 +3135,8 @@ VIR_ENUM_DECL(virDomainTPMModel)
VIR_ENUM_DECL(virDomainTPMBackend) VIR_ENUM_DECL(virDomainTPMBackend)
VIR_ENUM_DECL(virDomainMemoryModel) VIR_ENUM_DECL(virDomainMemoryModel)
VIR_ENUM_DECL(virDomainMemoryBackingModel) VIR_ENUM_DECL(virDomainMemoryBackingModel)
VIR_ENUM_DECL(virDomainMemorySource)
VIR_ENUM_DECL(virDomainMemoryAllocation)
VIR_ENUM_DECL(virDomainIOMMUModel) VIR_ENUM_DECL(virDomainIOMMUModel)
VIR_ENUM_DECL(virDomainShmemModel) VIR_ENUM_DECL(virDomainShmemModel)
/* from libvirt.h */ /* from libvirt.h */
......
<domain type='qemu'>
<name>SomeDummyGuest</name>
<uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<memoryBacking>
<source type='file'/>
<access mode='shared'/>
<allocation mode='immediate'/>
</memoryBacking>
<vcpu placement='static'>2</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>
<memballoon model='virtio'/>
</devices>
</domain>
<domain type='qemu'>
<name>SomeDummyGuest</name>
<uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<memoryBacking>
<source type="anonymous"/>
<access mode="private"/>
<allocation mode="ondemand"/>
</memoryBacking>
<vcpu placement='static'>2</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>
<memballoon model='virtio'/>
</devices>
</domain>
<domain type='qemu'>
<name>SomeDummyGuest</name>
<uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<memoryBacking>
<source type='file'/>
<access mode='shared'/>
<allocation mode='immediate'/>
</memoryBacking>
<vcpu placement='static'>2</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>
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</memballoon>
</devices>
</domain>
<domain type='qemu'>
<name>SomeDummyGuest</name>
<uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<memoryBacking>
<source type='anonymous'/>
<access mode='private'/>
<allocation mode='ondemand'/>
</memoryBacking>
<vcpu placement='static'>2</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>
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</memballoon>
</devices>
</domain>
...@@ -1042,6 +1042,9 @@ mymain(void) ...@@ -1042,6 +1042,9 @@ mymain(void)
DO_TEST("virtio-input", NONE); DO_TEST("virtio-input", NONE);
DO_TEST("virtio-input-passthrough", NONE); DO_TEST("virtio-input-passthrough", NONE);
DO_TEST("memorybacking-set", NONE);
DO_TEST("memorybacking-unset", NONE);
virObjectUnref(cfg); virObjectUnref(cfg);
DO_TEST("acpi-table", NONE); DO_TEST("acpi-table", NONE);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册