0.9.11 (QEMU and KVM only)</span>, the optional attribute
<code>placement</code> can be used to indicate the CPU placement
mode for domain process, its value can be either "static" or
- "auto", defaults to "static" if <code>cpuset</code> is specified,
- "auto" indicates the domain process will be pinned to the advisory
- nodeset from querying numad, and the value of attribute
- <code>cpuset</code> will be ignored if it's specified. If both
- <code>cpuset</code> and <code>placement</code> are not specified,
- or if <code>placement</code> is "static", but no <code>cpuset</code>
- is specified, the domain process will be pinned to all the
- available physical CPUs.
+ "auto", defaults to <code>placement</code> of <code>numatune</code>,
+ or "static" if <code>cpuset</code> is specified. "auto" indicates
+ the domain process will be pinned to the advisory nodeset from querying
+ numad, and the value of attribute <code>cpuset</code> will be ignored
+ if it's specified. If both <code>cpuset</code> and <code>placement</code>
+ are not specified, or if <code>placement</code> is "static", but no
+ <code>cpuset</code> is specified, the domain process will be pinned to
+ all the available physical CPUs.
</dd>
</dl>
<dt><code>memory</code></dt>
<dd>
The optional <code>memory</code> element specifies how to allocate memory
- for the domain process on a NUMA host. It contains two attributes,
- attribute <code>mode</code> is either 'interleave', 'strict',
- or 'preferred',
- attribute <code>nodeset</code> specifies the NUMA nodes, it leads same
- syntax with attribute <code>cpuset</code> of element <code>vcpu</code>.
+ for the domain process on a NUMA host. It contains several optional
+ attributes. Attribute <code>mode</code> is either 'interleave',
+ 'strict', or 'preferred', defaults to 'strict'. Attribute
+ <code>nodeset</code> specifies the NUMA nodes, using the same syntax as
+ attribute <code>cpuset</code> of element <code>vcpu</code>. Attribute
+ <code>placement</code> (<span class='since'>since 0.9.12</span>) can be
+ used to indicate the memory placement mode for domain process, its value
+ can be either "static" or "auto", defaults to <code>placement</code> of
+ <code>vcpu</code>, or "static" if <code>nodeset</code> is specified.
+ "auto" indicates the domain process will only allocate memory from the
+ advisory nodeset returned from querying numad, and the value of attribute
+ <code>nodeset</code> will be ignored if it's specified.
+
+ If <code>placement</code> of <code>vcpu</code> is 'auto', and
+ <code>numatune</code> is not specified, a default <code>numatune</code>
+ with <code>placement</code> 'auto' and <code>mode</code> 'strict' will
+ be added implicitly.
+
<span class='since'>Since 0.9.3</span>
</dd>
</dl>
<element name="numatune">
<optional>
<element name="memory">
- <attribute name="mode">
- <choice>
- <value>strict</value>
- <value>preferred</value>
- <value>interleave</value>
- </choice>
- </attribute>
- <attribute name="nodeset">
- <ref name="cpuset"/>
- </attribute>
+ <optional>
+ <attribute name="mode">
+ <choice>
+ <value>strict</value>
+ <value>preferred</value>
+ <value>interleave</value>
+ </choice>
+ </attribute>
+ </optional>
+ <choice>
+ <group>
+ <optional>
+ <attribute name='placement'>
+ <value>static</value>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name='nodeset'>
+ <ref name='cpuset'/>
+ </attribute>
+ </optional>
+ </group>
+ <attribute name='placement'>
+ <value>auto</value>
+ </attribute>
+ </choice>
</element>
</optional>
</element>
"closed",
"open");
+VIR_ENUM_IMPL(virDomainNumatuneMemPlacementMode,
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST,
+ "default",
+ "static",
+ "auto");
+
#define virDomainReportError(code, ...) \
virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
if (virDomainCpuSetParse(set, 0, def->cpumask,
def->cpumasklen) < 0)
goto error;
- VIR_FREE(tmp);
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_DEFAULT)
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC;
+ VIR_FREE(tmp);
}
}
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
if (xmlStrEqual(cur->name, BAD_CAST "memory")) {
- tmp = virXMLPropString(cur, "nodeset");
+ char *mode = NULL;
+ char *placement = NULL;
+ char *nodeset = NULL;
- if (tmp) {
- char *set = tmp;
+ mode = virXMLPropString(cur, "mode");
+ if (mode) {
+ if ((def->numatune.memory.mode =
+ virDomainNumatuneMemModeTypeFromString(mode)) < 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("Unsupported NUMA memory "
+ "tuning mode '%s'"),
+ mode);
+ VIR_FREE(mode);
+ goto error;
+ }
+ VIR_FREE(mode);
+ } else {
+ def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+ }
+
+ nodeset = virXMLPropString(cur, "nodeset");
+ if (nodeset) {
+ char *set = nodeset;
int nodemasklen = VIR_DOMAIN_CPUMASK_LEN;
if (VIR_ALLOC_N(def->numatune.memory.nodemask,
goto error;
}
- /* "nodeset" leads same syntax with "cpuset". */
+ /* "nodeset" uses the same syntax as "cpuset". */
if (virDomainCpuSetParse(set, 0,
def->numatune.memory.nodemask,
- nodemasklen) < 0)
+ nodemasklen) < 0) {
+ VIR_FREE(nodeset);
goto error;
- VIR_FREE(tmp);
- } else {
- virDomainReportError(VIR_ERR_XML_ERROR, "%s",
- _("nodeset for NUMA memory "
- "tuning must be set"));
- goto error;
+ }
+ VIR_FREE(nodeset);
}
- tmp = virXMLPropString(cur, "mode");
- if (tmp) {
- if ((def->numatune.memory.mode =
- virDomainNumatuneMemModeTypeFromString(tmp)) < 0) {
+ placement = virXMLPropString(cur, "placement");
+ int placement_mode = 0;
+ if (placement) {
+ if ((placement_mode =
+ virDomainNumatuneMemPlacementModeTypeFromString(placement)) < 0) {
virDomainReportError(VIR_ERR_XML_ERROR,
- _("Unsupported NUMA memory "
- "tuning mode '%s'"),
- tmp);
+ _("Unsupported memory placement "
+ "mode '%s'"), placement);
+ VIR_FREE(placement);
goto error;
}
- VIR_FREE(tmp);
+ VIR_FREE(placement);
+ } else if (def->numatune.memory.nodemask) {
+ /* Defaults to "static" if nodeset is specified. */
+ placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
} else {
- def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+ /* Defaults to "placement" of <vcpu> if nodeset is
+ * not specified.
+ */
+ if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC)
+ placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+ else
+ placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
}
+
+ if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC &&
+ !def->numatune.memory.nodemask) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("nodeset for NUMA memory tuning must be set "
+ "if 'placement' is 'static'"));
+ goto error;
+ }
+
+ /* Ignore 'nodeset' if 'placement' is 'auto' finally */
+ if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
+ VIR_FREE(def->numatune.memory.nodemask);
+
+ def->numatune.memory.placement_mode = placement_mode;
} else {
virDomainReportError(VIR_ERR_XML_ERROR,
_("unsupported XML element %s"),
}
cur = cur->next;
}
+ } else {
+ /* Defaults NUMA memory placement mode to 'auto' if no <numatune>
+ * and 'placement' of <vcpu> is 'auto'.
+ */
+ if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
+ def->numatune.memory.placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
+ def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+ }
}
VIR_FREE(nodes);
def->cputune.period || def->cputune.quota)
virBufferAddLit(buf, " </cputune>\n");
- if (def->numatune.memory.nodemask) {
+ if (def->numatune.memory.nodemask ||
+ def->numatune.memory.placement_mode) {
virBufferAddLit(buf, " <numatune>\n");
const char *mode;
char *nodemask = NULL;
-
- nodemask = virDomainCpuSetFormat(def->numatune.memory.nodemask,
- VIR_DOMAIN_CPUMASK_LEN);
- if (nodemask == NULL) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("failed to format nodeset for "
- "NUMA memory tuning"));
- goto cleanup;
- }
+ const char *placement;
mode = virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode);
- virBufferAsprintf(buf, " <memory mode='%s' nodeset='%s'/>\n",
- mode, nodemask);
- VIR_FREE(nodemask);
+ virBufferAsprintf(buf, " <memory mode='%s' ", mode);
+ if (def->numatune.memory.placement_mode ==
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
+ nodemask = virDomainCpuSetFormat(def->numatune.memory.nodemask,
+ VIR_DOMAIN_CPUMASK_LEN);
+ if (nodemask == NULL) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to format nodeset for "
+ "NUMA memory tuning"));
+ goto cleanup;
+ }
+ virBufferAsprintf(buf, "nodeset='%s'/>\n", nodemask);
+ VIR_FREE(nodemask);
+ } else if (def->numatune.memory.placement_mode) {
+ placement = virDomainNumatuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
+ virBufferAsprintf(buf, "placement='%s'/>\n", placement);
+ }
virBufferAddLit(buf, " </numatune>\n");
}
VIR_DOMAIN_CPU_PLACEMENT_MODE_LAST,
};
+enum virDomainNumatuneMemPlacementMode {
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_DEFAULT = 0,
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC,
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO,
+
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST,
+};
+
typedef struct _virDomainTimerCatchupDef virDomainTimerCatchupDef;
typedef virDomainTimerCatchupDef *virDomainTimerCatchupDefPtr;
struct _virDomainTimerCatchupDef {
struct {
char *nodemask;
int mode;
+ int placement_mode; /* enum virDomainNumatuneMemPlacementMode */
} memory;
/* Future NUMA tuning related stuff should go here. */
VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
VIR_ENUM_DECL(virDomainNumatuneMemMode)
+VIR_ENUM_DECL(virDomainNumatuneMemPlacementMode)
VIR_ENUM_DECL(virDomainSnapshotState)
/* from libvirt.h */
VIR_ENUM_DECL(virDomainState)
virDomainNostateReasonTypeToString;
virDomainNumatuneMemModeTypeFromString;
virDomainNumatuneMemModeTypeToString;
+virDomainNumatuneMemPlacementModeTypeFromString;
+virDomainNumatuneMemPlacementModeTypeToString;
virDomainObjAssignDef;
virDomainObjCopyPersistentDef;
virDomainObjGetPersistentDef;
*/
#if HAVE_NUMACTL
static int
-qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm)
+qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
+ const char *nodemask)
{
nodemask_t mask;
int mode = -1;
int i = 0;
int maxnode = 0;
bool warned = false;
+ virDomainNumatuneDef numatune = vm->def->numatune;
+ const char *tmp_nodemask = NULL;
- if (!vm->def->numatune.memory.nodemask)
+ if (numatune.memory.placement_mode ==
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
+ if (!numatune.memory.nodemask)
+ return 0;
+ VIR_DEBUG("Set NUMA memory policy with specified nodeset");
+ tmp_nodemask = numatune.memory.nodemask;
+ } else if (numatune.memory.placement_mode ==
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
+ VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
+ tmp_nodemask = nodemask;
+ } else {
return 0;
-
- VIR_DEBUG("Setting NUMA memory policy");
+ }
if (numa_available() < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
}
maxnode = numa_max_node() + 1;
-
/* Convert nodemask to NUMA bitmask. */
nodemask_zero(&mask);
for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) {
- if (vm->def->numatune.memory.nodemask[i]) {
+ if (tmp_nodemask[i]) {
if (i > NUMA_NUM_NODES) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("Host cannot support NUMA node %d"), i);
VIR_WARN("nodeset is out of range, there is only %d NUMA "
"nodes on host", maxnode);
warned = true;
- }
+ }
nodemask_set(&mask, i);
}
}
- mode = vm->def->numatune.memory.mode;
+ mode = numatune.memory.mode;
if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
numa_set_bind_policy(1);
*/
static int
qemuProcessInitCpuAffinity(struct qemud_driver *driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ const char *nodemask)
{
int ret = -1;
int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN;
}
if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
- char *nodeset = NULL;
- char *nodemask = NULL;
-
- nodeset = qemuGetNumadAdvice(vm->def);
- if (!nodeset)
- goto cleanup;
-
- if (VIR_ALLOC_N(nodemask, VIR_DOMAIN_CPUMASK_LEN) < 0) {
- virReportOOMError();
- VIR_FREE(nodeset);
- goto cleanup;
- }
-
- if (virDomainCpuSetParse(nodeset, 0, nodemask,
- VIR_DOMAIN_CPUMASK_LEN) < 0) {
- VIR_FREE(nodemask);
- VIR_FREE(nodeset);
- goto cleanup;
- }
- VIR_FREE(nodeset);
-
+ VIR_DEBUG("Set CPU affinity with advisory nodeset from numad");
/* numad returns the NUMA node list, convert it to cpumap */
int prev_total_ncpus = 0;
for (i = 0; i < driver->caps->host.nnumaCell; i++) {
}
prev_total_ncpus += cur_ncpus;
}
-
- VIR_FREE(nodemask);
} else {
+ VIR_DEBUG("Set CPU affinity with specified cpuset");
if (vm->def->cpumask) {
/* XXX why don't we keep 'cpumask' in the libvirt cpumap
* format to start with ?!?! */
struct qemuProcessHookData *h = data;
int ret = -1;
int fd;
+ char *nodeset = NULL;
+ char *nodemask = NULL;
/* Some later calls want pid present */
h->vm->pid = getpid();
if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
goto cleanup;
+ if ((h->vm->def->placement_mode ==
+ VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
+ (h->vm->def->numatune.memory.placement_mode ==
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
+ nodeset = qemuGetNumadAdvice(h->vm->def);
+ if (!nodeset)
+ goto cleanup;
+
+ VIR_DEBUG("Nodeset returned from numad: %s", nodeset);
+
+ if (VIR_ALLOC_N(nodemask, VIR_DOMAIN_CPUMASK_LEN) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virDomainCpuSetParse(nodeset, 0, nodemask,
+ VIR_DOMAIN_CPUMASK_LEN) < 0)
+ goto cleanup;
+ }
+
/* This must be done after cgroup placement to avoid resetting CPU
* affinity */
VIR_DEBUG("Setup CPU affinity");
- if (qemuProcessInitCpuAffinity(h->driver, h->vm) < 0)
+ if (qemuProcessInitCpuAffinity(h->driver, h->vm, nodemask) < 0)
goto cleanup;
- if (qemuProcessInitNumaMemoryPolicy(h->vm) < 0)
- return -1;
+ if (qemuProcessInitNumaMemoryPolicy(h->vm, nodemask) < 0)
+ goto cleanup;
VIR_DEBUG("Setting up security labelling");
if (virSecurityManagerSetProcessLabel(h->driver->securityManager, h->vm->def) < 0)
cleanup:
VIR_DEBUG("Hook complete ret=%d", ret);
+ VIR_FREE(nodeset);
+ VIR_FREE(nodemask);
return ret;
}
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='auto'>2</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='1' threads='1'/>
+ </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'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--- /dev/null
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 2 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
+/dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='auto'>2</vcpu>
+ <numatune>
+ <memory mode='interleave' nodeset='0'/>
+ </numatune>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='1' threads='1'/>
+ </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'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>2</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='1' threads='1'/>
+ </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'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--- /dev/null
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 2 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
+/dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='auto'>2</vcpu>
+ <numatune>
+ <memory mode="interleave" placement='auto'/>
+ </numatune>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='1' threads='1'/>
+ </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'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
DO_TEST("blkiotune-device", false, QEMU_CAPS_NAME);
DO_TEST("cputune", false, QEMU_CAPS_NAME);
DO_TEST("numatune-memory", false, NONE);
+ DO_TEST("numad", false, NONE);
+ DO_TEST("numad-auto-vcpu-static-numatune", false, NONE);
DO_TEST("blkdeviotune", false, QEMU_CAPS_NAME, QEMU_CAPS_DEVICE,
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_IOTUNE);
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='auto'>2</vcpu>
+ <numatune>
+ <memory mode='strict' placement='auto'/>
+ </numatune>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='1' threads='1'/>
+ </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'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>2</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='1' threads='1'/>
+ </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'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
DO_TEST_FULL("seclabel-dynamic-override", false, WHEN_INACTIVE);
DO_TEST("seclabel-static");
DO_TEST("seclabel-none");
+ DO_TEST("numad-static-vcpu-no-numatune");
/* These tests generate different XML */
DO_TEST_DIFFERENT("balloon-device-auto");
DO_TEST_DIFFERENT("serial-target-port-auto");
DO_TEST_DIFFERENT("graphics-listen-network2");
DO_TEST_DIFFERENT("graphics-spice-timeout");
+ DO_TEST_DIFFERENT("numad-auto-vcpu-no-numatune");
DO_TEST_DIFFERENT("metadata");