[libvirt] [PATCH v2 00/18] Implement original label remembering
by Michal Privoznik
v2 of:
https://www.redhat.com/archives/libvir-list/2018-November/msg00862.html
diff to v1:
- in 03/18 I've implemented FreeBSD support as discussed in v1
Michal Prívozník (18):
security: Unify header conditionals
util: Introduce xattr getter/setter/remover
security: Include security_util
security_dac: Restore label on failed chown() attempt
virSecurityDACTransactionRun: Implement rollback
virSecurityDACRestoreAllLabel: Reorder device relabeling
virSecurityDACRestoreAllLabel: Restore more labels
security_dac: Allow callers to enable/disable label remembering/recall
security_dac: Remember old labels
virSecurityDACRestoreImageLabelInt: Restore even shared/RO disks
security_selinux: Track if transaction is restore
security_selinux: Remember old labels
security_selinux: Restore label on failed setfilecon() attempt
virSecuritySELinuxTransactionRun: Implement rollback
virSecuritySELinuxRestoreAllLabel: Reorder device relabeling
virSecuritySELinuxRestoreAllLabel: Restore more labels
tools: Provide a script to recover fubar'ed XATTRs setup
qemu.conf: Allow users to enable/disable label remembering
src/libvirt_private.syms | 3 +
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 6 +
src/qemu/qemu_conf.c | 4 +
src/qemu/test_libvirtd_qemu.aug.in | 1 +
src/security/Makefile.inc.am | 2 +
src/security/security_apparmor.h | 6 +-
src/security/security_dac.c | 212 +++++++++++++++++-------
src/security/security_dac.h | 6 +-
src/security/security_driver.h | 6 +-
src/security/security_manager.h | 6 +-
src/security/security_nop.h | 6 +-
src/security/security_selinux.c | 256 +++++++++++++++++++++--------
src/security/security_selinux.h | 6 +-
src/security/security_stack.h | 6 +-
src/security/security_util.c | 226 +++++++++++++++++++++++++
src/security/security_util.h | 32 ++++
src/util/virfile.c | 121 ++++++++++++++
src/util/virfile.h | 11 ++
tools/Makefile.am | 1 +
tools/libvirt_recover_xattrs.sh | 89 ++++++++++
21 files changed, 857 insertions(+), 150 deletions(-)
create mode 100644 src/security/security_util.c
create mode 100644 src/security/security_util.h
create mode 100755 tools/libvirt_recover_xattrs.sh
--
2.18.1
5 years, 11 months
[libvirt] [PATCH] qemu: Add support for postcopy-requests migration statistics
by Jiri Denemark
QEMU can report how many times during post-copy migration the domain
running on the destination host tried to access a page which has not
been migrated yet.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
include/libvirt/libvirt-domain.h | 10 ++++++++++
src/qemu/qemu_domain.c | 5 ++++-
src/qemu/qemu_migration_cookie.c | 5 +++++
src/qemu/qemu_monitor.h | 1 +
src/qemu/qemu_monitor_json.c | 2 ++
tools/virsh-domain.c | 8 ++++++++
6 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 71debd92b8..897b06e6d0 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -3378,6 +3378,16 @@ typedef enum {
*/
# define VIR_DOMAIN_JOB_MEMORY_ITERATION "memory_iteration"
+/**
+ * VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS:
+ *
+ * virDomainGetJobStats field: number page requests received from the
+ * destination host during post-copy migration, as VIR_TYPED_PARAM_ULLONG.
+ * This counter is incremented whenever the migrated domain tries to access
+ * a memory page which has not been transferred from the source host yet.
+ */
+# define VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS "memory_postcopy_requests"
+
/**
* VIR_DOMAIN_JOB_DISK_TOTAL:
*
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index fbe63e2e1d..3dbd9d47ca 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -609,7 +609,10 @@ qemuDomainMigrationJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
stats->ram_dirty_rate) < 0 ||
virTypedParamsAddULLong(&par, &npar, &maxpar,
VIR_DOMAIN_JOB_MEMORY_ITERATION,
- stats->ram_iteration) < 0)
+ stats->ram_iteration) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS,
+ stats->ram_postcopy_reqs) < 0)
goto error;
if (stats->ram_page_size > 0 &&
diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
index 60df449d53..84f0101382 100644
--- a/src/qemu/qemu_migration_cookie.c
+++ b/src/qemu/qemu_migration_cookie.c
@@ -703,6 +703,9 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
VIR_DOMAIN_JOB_MEMORY_ITERATION,
stats->ram_iteration);
+ virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
+ VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS,
+ stats->ram_postcopy_reqs);
virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n",
VIR_DOMAIN_JOB_MEMORY_PAGE_SIZE,
@@ -1102,6 +1105,8 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
ctxt, &stats->ram_dirty_rate);
virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_ITERATION "[1])",
ctxt, &stats->ram_iteration);
+ virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS "[1])",
+ ctxt, &stats->ram_postcopy_reqs);
virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_PAGE_SIZE "[1])",
ctxt, &stats->ram_page_size);
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 48b142a4f4..3430426c4b 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -706,6 +706,7 @@ struct _qemuMonitorMigrationStats {
unsigned long long ram_dirty_rate;
unsigned long long ram_page_size;
unsigned long long ram_iteration;
+ unsigned long long ram_postcopy_reqs;
unsigned long long disk_transferred;
unsigned long long disk_remaining;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 3de298c9e2..4c151dd405 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3296,6 +3296,8 @@ qemuMonitorJSONGetMigrationStatsReply(virJSONValuePtr reply,
&stats->ram_page_size));
ignore_value(virJSONValueObjectGetNumberUlong(ram, "dirty-sync-count",
&stats->ram_iteration));
+ ignore_value(virJSONValueObjectGetNumberUlong(ram, "postcopy-requests",
+ &stats->ram_postcopy_reqs));
disk = virJSONValueObjectGetObject(ret, "disk");
if (disk) {
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 372bdb95d3..a71cc9d0be 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -6233,6 +6233,14 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd)
} else if (rc) {
vshPrint(ctl, "%-17s %-12llu\n", _("Iteration:"), value);
}
+
+ if ((rc = virTypedParamsGetULLong(params, nparams,
+ VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS,
+ &value)) < 0) {
+ goto save_error;
+ } else if (rc) {
+ vshPrint(ctl, "%-17s %-12llu\n", _("Postcopy requests:"), value);
+ }
}
if (info.fileTotal || info.fileRemaining || info.fileProcessed) {
--
2.19.1
5 years, 11 months
[libvirt] [PATCH RFC v2] qemu: fix deadlock when waiting in non async jobs
by Nikolay Shirokovskiy
Block job abort operation can not handle properly qemu crashes when waiting for
abort/pivot completion. Deadlock scenario is next:
- qemuDomainBlockJobAbort waits for pivot/abort completion
- qemu crashes, then qemuProcessBeginStopJob broadcasts for VM condition and
then waits for job condition (taken by qemuDomainBlockJobAbort)
- qemuDomainBlockJobAbort awakes but nothing really changed, VM is still
active (vm->def->id != -1) so thread starts waiting for completion again.
Now two threads are in deadlock.
First let's remove broadcast in qemuProcessBeginStopJob. It is simply wrong
because it is not set any condition before broadcast so that awaked threads can
not detect any changes. Crashing domain during async job will continue to be
handled properly because destroy job can run concurrently with async job and
destroy job calls qemuProcessStop which sets vm->def->id to -1 and broadcasts.
Second let's introduce flag that EOF is received and broadcast after that.
Now non async jobs can check this flag in wait loop.
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy(a)virtuozzo.com>
---
Diff from v1:
- patches 1 and 2 are already merged
- don't bother with reporting monitor EOF reason to user as most of
time it is simply "unexpected eof" (this implies dropping patch 3)
- drop patch 5 as we now always report "domain is being stopped"
in qemuDomainObjWait
- don't signal on monitor error for simplicity (otherwise we need to report
something more elaborate that "domain is being stopped" as we don't
kill domain on monitor errors. On the other hand I guess monitor
error is rare case to handle it right now)
- keep virDomainObjWait for async jobs
It's a bit uneven that for async jobs domain is destroyed concurrently and for
non async jobs it will be actually destroyed after job get completed. Also if
non async job needs issuing commands to qemu on cleanup then we will send these
commands in vain polluting logs etc because qemu process in not running at this
moment but typical check (virDomainObjIsActive) will think it is still running.
Domain is destroyed (qemuProcessStop) in a job due to patches [1] and [2].
However AFAIU it is not neccessary. If qemuProcessStop does not drop VM lock
then we don't need extra job to make qemuProcessStop and main job not
interleave. And we can drop the lock now only in qemuDomainObjBeginNestedJob in
qemuProcessStop which is introduced in [2]. AFAIU we can fix issues mentioned in
[2] the other way for example like it is done for qemu agent - we save agent
monitor reference on stack for entering/exiting agent monitor.
So I wonder can we instead of this fix remove job for qemuProcessStop and run
destroying domain cuncurrently for non async jobs too.
[1]
commit 8c9ff9960b29d4703a99efdd1cadcf6f48799cc0
Author: Jiri Denemark <jdenemar(a)redhat.com>
Date: Thu Feb 11 15:32:48 2016 +0100
qemu: Process monitor EOF in a job
[2]
commit 81f50cb92d16643bcd749e3ab5b404b8b7cec643
Author: Jiri Denemark <jdenemar(a)redhat.com>
Date: Thu Feb 11 11:20:28 2016 +0100
qemu: Avoid calling qemuProcessStop without a job
src/qemu/qemu_domain.c | 39 +++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 4 ++++
src/qemu/qemu_driver.c | 2 +-
src/qemu/qemu_hotplug.c | 4 ++--
src/qemu/qemu_process.c | 9 +++++----
5 files changed, 51 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 939b2a3..aead72b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -13534,3 +13534,42 @@ qemuDomainRunningReasonToResumeEvent(virDomainRunningReason reason)
return VIR_DOMAIN_EVENT_RESUMED_UNPAUSED;
}
+
+
+/**
+ * Waits for domain condition to be triggered for a specific period of time.
+ * if @until is 0 then waits indefinetely.
+ *
+ * Returns:
+ * -1 on error
+ * 0 on success
+ * 1 on timeout
+ */
+int
+qemuDomainObjWait(virDomainObjPtr vm, unsigned long long until)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ int rc;
+
+ if (until)
+ rc = virCondWaitUntil(&vm->cond, &vm->parent.lock, until);
+ else
+ rc = virCondWait(&vm->cond, &vm->parent.lock);
+
+ if (rc < 0) {
+ if (until && errno == ETIMEDOUT)
+ return 1;
+
+ virReportSystemError(errno, "%s",
+ _("failed to wait for domain condition"));
+ return -1;
+ }
+
+ if (priv->monEOF) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("domain is being stopped"));
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 2f8a1bf..36ab294 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -281,6 +281,7 @@ struct _qemuDomainObjPrivate {
virDomainChrSourceDefPtr monConfig;
bool monJSON;
bool monError;
+ bool monEOF;
unsigned long long monStart;
qemuAgentPtr agent;
@@ -1085,4 +1086,7 @@ void qemuDomainStorageIdReset(qemuDomainObjPrivatePtr priv);
virDomainEventResumedDetailType
qemuDomainRunningReasonToResumeEvent(virDomainRunningReason reason);
+int
+qemuDomainObjWait(virDomainObjPtr vm, unsigned long long until);
+
#endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b238309..f4250da 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17142,7 +17142,7 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
qemuBlockJobUpdate(vm, QEMU_ASYNC_JOB_NONE, disk, NULL);
while (diskPriv->blockjob) {
- if (virDomainObjWait(vm) < 0) {
+ if (qemuDomainObjWait(vm, 0) < 0) {
ret = -1;
goto endjob;
}
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 4558a3c..8189629 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -165,7 +165,7 @@ qemuHotplugWaitForTrayEject(virDomainObjPtr vm,
return -1;
while (disk->tray_status != VIR_DOMAIN_DISK_TRAY_OPEN) {
- if ((rc = virDomainObjWaitUntil(vm, now + CHANGE_MEDIA_TIMEOUT)) < 0)
+ if ((rc = qemuDomainObjWait(vm, now + CHANGE_MEDIA_TIMEOUT)) < 0)
return -1;
if (rc > 0) {
@@ -5002,7 +5002,7 @@ qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
until += qemuDomainRemoveDeviceWaitTime;
while (priv->unplug.alias) {
- if ((rc = virDomainObjWaitUntil(vm, until)) == 1)
+ if ((rc = qemuDomainObjWait(vm, until)) == 1)
return 0;
if (rc < 0) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 29b0ba1..dd03269 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -290,9 +290,12 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon,
virObjectLock(vm);
+ priv = vm->privateData;
+ priv->monEOF = true;
+ virDomainObjBroadcast(vm);
+
VIR_DEBUG("Received EOF on %p '%s'", vm, vm->def->name);
- priv = vm->privateData;
if (priv->beingDestroyed) {
VIR_DEBUG("Domain is being destroyed, EOF is expected");
goto cleanup;
@@ -5996,6 +5999,7 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver,
priv->monJSON = true;
priv->monError = false;
+ priv->monEOF = false;
priv->monStart = 0;
priv->gotShutdown = false;
priv->runningReason = VIR_DOMAIN_RUNNING_UNKNOWN;
@@ -6965,9 +6969,6 @@ qemuProcessBeginStopJob(virQEMUDriverPtr driver,
if (qemuProcessKill(vm, killFlags) < 0)
goto cleanup;
- /* Wake up anything waiting on domain condition */
- virDomainObjBroadcast(vm);
-
if (qemuDomainObjBeginJob(driver, vm, job) < 0)
goto cleanup;
--
1.8.3.1
5 years, 11 months
[libvirt] [PATCH 0/7] Restructure firewall rules for virtual networks into private chains
by Daniel P. Berrangé
The virtual networks in NAT mode are supposed to only allow outbound
network access for guests. Unfortunately due to ordering of the firewall
rules libvirt creates, when you have multiple virtual networks, guests
on the more recently created virtual networks can connect to guests on
old virtual networks.
This was reported way back in 2008 but we always thought the fix would
be very complicated to deal with, so we've been putting it off forever.
In parallel with this there's also been a long standing desire since
2009 to move our firewall rules out of the builtin chains, to libvirt
private chains. This is to make it easier for admins to use hook scripts
to setup rules in the builtin chains that take priority over rules
libvirt creates.
In implementing the changes to use private chains, I suddenly realized
that fixing the network to network traffic blocking problem was trivial
if I grouped the forwarding rules into three distinct sets.
So this series finally fixes an annoying 10 year old bug, and implements
a 9 year old RFE.
It may take us a while, but we'll get to your bugs eventually ;-)
Daniel P. Berrangé (7):
util: refactor iptables APIs to share more code
util: add iptables API for creating base chains
util: prepare iptables for putting rules into private chains
network: setup default iptables chains
util: switch over to creating rules in private chains
tests: remove duplicated test case in networkxml2firewalltest
tests: fix dry run handling in network firewall test
src/libvirt_private.syms | 1 +
src/network/bridge_driver_linux.c | 3 +
src/util/viriptables.c | 317 ++++++++++++++----
src/util/viriptables.h | 2 +
.../nat-default-linux.args | 150 ++++++++-
.../nat-ipv6-linux.args | 166 +++++++--
.../nat-many-ips-linux.args | 178 ++++++++--
.../nat-no-dhcp-linux.args | 164 +++++++--
.../nat-tftp-linux.args | 152 ++++++++-
.../route-default-linux.args | 140 +++++++-
tests/networkxml2firewalltest.c | 17 +-
11 files changed, 1107 insertions(+), 183 deletions(-)
--
2.19.1
5 years, 11 months
[libvirt] [PATCH v3 00/11] Autoselect a DRM node for egl-headless add it to cmdline
by Erik Skultety
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1628892.
The problem is that we didn't put the DRI device into the namespace for QEMU to
access, but that was only a part of the issue. The other part of the issue is
that QEMU doesn't support specifying 'rendernode' for egl-headless yet (patches
are already in upstream) Instead, QEMU's been autoselecting the DRI device on
its own. There's no compelling reason for libvirt not doing that instead and
thus prevent any permission-related issues.
Since v1:
- updated capabilities to 3.1.0-rc2 containing the necessary QEMU patches
- provided more test cases as requested
- added a new XML sub-element <gl> for egl-headless graphics type
Since v2:
- The cmdline code wouldn't play nicely with old QEMU where I'd pick a
rendernode automatically and then fail if we didn't have the corresponding
capability, so this was fixed for v3
- v2 converted some tests to CAPS_LATEST only which would also be wrong because
QEMU can still pick a DRM node so that's a valid use case (not a practical one
though)
- the 3.1.0 capabilities patch was merged separately
Erik Skultety (11):
util: Introduce virHostGetDRMRenderNode helper
conf: Introduce virDomainGraphics-related helpers
qemu: process: spice: Pick the first available DRM render node
qemu: command: Introduce qemuBuildGraphicsEGLHeadlessCommandLine
helper
qemu: caps: Introduce QEMU_EGL_HEADLESS_RENDERNODE capability
conf: gfx: Add egl-headless as a member to virDomainGraphicsDef struct
conf: gfx: egl-headless: Introduce a new <gl> subelement
qemu: domain: egl-headless: Add the DRI device into the namespace
qemu: cgroup: gfx: egl-headless: Add the DRI device into the cgroup
list
security: dac: gfx: egl-headless: Relabel the DRI device
qemu: command: gfx: egl-headless: Add 'rendernode' option to the
cmdline
docs/formatdomain.html.in | 11 ++-
docs/schemas/domaincommon.rng | 17 +++-
src/conf/domain_conf.c | 84 +++++++++++++++++++
src/conf/domain_conf.h | 12 +++
src/libvirt_private.syms | 4 +
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_cgroup.c | 10 +--
src/qemu/qemu_command.c | 42 +++++++++-
src/qemu/qemu_domain.c | 9 +-
src/qemu/qemu_process.c | 32 ++++++-
src/security/security_dac.c | 15 ++--
src/util/virutil.c | 53 ++++++++++++
src/util/virutil.h | 2 +
.../caps_3.1.0.x86_64.xml | 1 +
...egl-headless-rendernode.x86_64-latest.args | 31 +++++++
.../graphics-egl-headless-rendernode.xml | 33 ++++++++
.../graphics-egl-headless.x86_64-latest.args | 31 +++++++
.../graphics-spice-gl-no-rendernode.args | 25 ++++++
.../graphics-spice-gl-no-rendernode.xml | 24 ++++++
...play-spice-egl-headless.x86_64-latest.args | 2 +-
...isplay-vnc-egl-headless.x86_64-latest.args | 2 +-
tests/qemuxml2argvmock.c | 9 ++
tests/qemuxml2argvtest.c | 2 +
.../graphics-egl-headless-rendernode.xml | 41 +++++++++
tests/qemuxml2xmltest.c | 2 +
26 files changed, 464 insertions(+), 33 deletions(-)
create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless-rendernode.x86_64-latest.args
create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless-rendernode.xml
create mode 100644 tests/qemuxml2argvdata/graphics-egl-headless.x86_64-latest.args
create mode 100644 tests/qemuxml2argvdata/graphics-spice-gl-no-rendernode.args
create mode 100644 tests/qemuxml2argvdata/graphics-spice-gl-no-rendernode.xml
create mode 100644 tests/qemuxml2xmloutdata/graphics-egl-headless-rendernode.xml
--
2.19.1
5 years, 11 months
[libvirt] [PATCH 0/2] qemu: arm guest on x86
by infos@nafets.de
From: Stefan Schallenberg <nafets227(a)users.noreply.github.com>
*** BLURB HERE ***
Stefan Schallenberg (2):
Add armv6l Support as guest
qemu: Add Default PCI Device for arm guests
docs/news.xml | 9 +++++
docs/schemas/basictypes.rng | 1 +
src/qemu/qemu_capabilities.c | 5 ++-
src/qemu/qemu_command.c | 4 +-
src/qemu/qemu_domain.c | 20 ++++++++--
src/qemu/qemu_domain_address.c | 6 ++-
tests/capabilityschemadata/caps-qemu-kvm.xml | 10 +++++
tests/testutilsqemu.c | 40 +++++++++++++++++++-
8 files changed, 84 insertions(+), 11 deletions(-)
--
2.19.2
5 years, 11 months
[libvirt] [PATCH v2] qemu: handle multicast overflow on macvtap NIC_RX_FILTER_CHANGED
by Jason Baron
Guest network devices can set 'overflow' when there are a number of multicast
ips configured. For virtio_net, the limit is only 64. In this case, the list
of mac addresses is empty and the 'overflow' condition is set. Thus, the guest
will currently receive no multicast traffic in this state.
When 'overflow' is set in the guest, let's turn this into ALLMULTI on the host.
Signed-off-by: Jason Baron <jbaron(a)akamai.com>
---
v1->v2:
1. check for < 0 in virNetDevSetRcvAllMulti() (Michal Privoznik)
2. restrict overflow check to VIR_NETDEV_RX_FILTER_MODE_NORMAL mode as to
avoid unnecessarily calling rx filter updates for other modes
3. update virNetDevSetRcvAllMulti() call to use guestFilter->multicast.overflow
directly (Michal Privoznik)
src/qemu/qemu_driver.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7fb9102..f4bbfea 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4443,11 +4443,12 @@ static void
syncNicRxFilterMultiMode(char *ifname, virNetDevRxFilterPtr guestFilter,
virNetDevRxFilterPtr hostFilter)
{
- if (hostFilter->multicast.mode != guestFilter->multicast.mode) {
+ if (hostFilter->multicast.mode != guestFilter->multicast.mode ||
+ (guestFilter->multicast.overflow &&
+ guestFilter->multicast.mode == VIR_NETDEV_RX_FILTER_MODE_NORMAL)) {
switch (guestFilter->multicast.mode) {
case VIR_NETDEV_RX_FILTER_MODE_ALL:
if (virNetDevSetRcvAllMulti(ifname, true)) {
-
VIR_WARN("Couldn't set allmulticast flag to 'on' for "
"device %s while responding to "
"NIC_RX_FILTER_CHANGED", ifname);
@@ -4455,17 +4456,24 @@ syncNicRxFilterMultiMode(char *ifname, virNetDevRxFilterPtr guestFilter,
break;
case VIR_NETDEV_RX_FILTER_MODE_NORMAL:
- if (virNetDevSetRcvMulti(ifname, true)) {
+ if (guestFilter->multicast.overflow &&
+ (hostFilter->multicast.mode == VIR_NETDEV_RX_FILTER_MODE_ALL)) {
+ break;
+ }
+ if (virNetDevSetRcvMulti(ifname, true)) {
VIR_WARN("Couldn't set multicast flag to 'on' for "
"device %s while responding to "
"NIC_RX_FILTER_CHANGED", ifname);
}
- if (virNetDevSetRcvAllMulti(ifname, false)) {
- VIR_WARN("Couldn't set allmulticast flag to 'off' for "
- "device %s while responding to "
- "NIC_RX_FILTER_CHANGED", ifname);
+ if (virNetDevSetRcvAllMulti(ifname,
+ guestFilter->multicast.overflow) < 0) {
+ VIR_WARN("Couldn't set allmulticast flag to '%s' for "
+ "device %s while responding to "
+ "NIC_RX_FILTER_CHANGED",
+ virTristateSwitchTypeToString(virTristateSwitchFromBool(guestFilter->multicast.overflow)),
+ ifname);
}
break;
--
2.7.4
5 years, 11 months
[libvirt] [PATCH v2] openvswitch: Add new port VLAN mode "dot1q-tunnel"
by luzhipeng@uniudc.com
From: ZhiPeng Lu <luzhipeng(a)uniudc.com>
Signed-off-by: ZhiPeng Lu <luzhipeng(a)uniudc.com>
---
v1->v2:
1. Fix "make syntax-check" failure
docs/formatnetwork.html.in | 17 +++++++++--------
docs/schemas/networkcommon.rng | 1 +
src/conf/netdev_vlan_conf.c | 2 +-
src/util/virnetdevopenvswitch.c | 5 +++++
src/util/virnetdevvlan.h | 1 +
5 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 363a72b..3c1ae62 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -688,16 +688,17 @@
</p>
<p>
For network connections using Open vSwitch it is also possible
- to configure 'native-tagged' and 'native-untagged' VLAN modes
+ to configure 'native-tagged' and 'native-untagged' and 'dot1q-tunnel'
+ VLAN modes.
<span class="since">Since 1.1.0.</span> This is done with the
- optional <code>nativeMode</code> attribute on
- the <code><tag></code> subelement: <code>nativeMode</code>
- may be set to 'tagged' or 'untagged'. The <code>id</code>
- attribute of the <code><tag></code> subelement
- containing <code>nativeMode</code> sets which VLAN is considered
- to be the "native" VLAN for this interface, and
+ optional <code>nativeMode</code> attribute on the
+ <code><tag></code> subelement: <code>nativeMode</code>
+ may be set to 'tagged' or 'untagged' or 'dot1q-tunnel'.
+ The <code>id</code> attribute of the <code><tag></code>
+ subelement containing <code>nativeMode</code> sets which VLAN is
+ considered to be the "native" VLAN for this interface, and
the <code>nativeMode</code> attribute determines whether or not
- traffic for that VLAN will be tagged.
+ traffic for that VLAN will be tagged or QinQ.
</p>
<p>
<code><vlan></code> elements can also be specified in
diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
index 2699555..11c48ff 100644
--- a/docs/schemas/networkcommon.rng
+++ b/docs/schemas/networkcommon.rng
@@ -223,6 +223,7 @@
<choice>
<value>tagged</value>
<value>untagged</value>
+ <value>dot1q-tunnel</value>
</choice>
</attribute>
</optional>
diff --git a/src/conf/netdev_vlan_conf.c b/src/conf/netdev_vlan_conf.c
index dff49c6..79710d9 100644
--- a/src/conf/netdev_vlan_conf.c
+++ b/src/conf/netdev_vlan_conf.c
@@ -29,7 +29,7 @@
#define VIR_FROM_THIS VIR_FROM_NONE
VIR_ENUM_IMPL(virNativeVlanMode, VIR_NATIVE_VLAN_MODE_LAST,
- "default", "tagged", "untagged")
+ "default", "tagged", "untagged", "dot1q-tunnel")
int
virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr def)
diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c
index 8fe06fd..ba5e333 100644
--- a/src/util/virnetdevopenvswitch.c
+++ b/src/util/virnetdevopenvswitch.c
@@ -91,6 +91,11 @@ virNetDevOpenvswitchConstructVlans(virCommandPtr cmd, virNetDevVlanPtr virtVlan)
virCommandAddArg(cmd, "vlan_mode=native-untagged");
virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag);
break;
+ case VIR_NATIVE_VLAN_MODE_DOT1Q_TUNNEL:
+ virCommandAddArg(cmd, "vlan_mode=dot1q-tunnel");
+ virCommandAddArg(cmd, "other_config:qinq-ethtype=802.1q");
+ virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag);
+ break;
case VIR_NATIVE_VLAN_MODE_DEFAULT:
default:
break;
diff --git a/src/util/virnetdevvlan.h b/src/util/virnetdevvlan.h
index be85f59..0667f9d 100644
--- a/src/util/virnetdevvlan.h
+++ b/src/util/virnetdevvlan.h
@@ -29,6 +29,7 @@ typedef enum {
VIR_NATIVE_VLAN_MODE_DEFAULT = 0,
VIR_NATIVE_VLAN_MODE_TAGGED,
VIR_NATIVE_VLAN_MODE_UNTAGGED,
+ VIR_NATIVE_VLAN_MODE_DOT1Q_TUNNEL,
VIR_NATIVE_VLAN_MODE_LAST
} virNativeVlanMode;
--
1.8.3.1
5 years, 11 months
[libvirt] [RFC v2 2/3] nvdimm: update qemu command-line generating for NVDIMM memory
by Luyao Zhong
According to the result parsing from xml, add corresponding properties
into QEMU command line, including 'align', 'pmem', 'unarmed' and
'nvdimm-persistence'.
Signed-off-by: Luyao Zhong <luyao.zhong(a)intel.com>
---
src/qemu/qemu_capabilities.c | 17 +++++++
src/qemu/qemu_capabilities.h | 5 ++
src/qemu/qemu_command.c | 50 ++++++++++++++++++-
src/qemu/qemu_command.h | 3 +-
src/qemu/qemu_hotplug.c | 2 +-
.../memory-hotplug-nvdimm-align.args | 31 ++++++++++++
.../memory-hotplug-nvdimm-persistence.args | 31 ++++++++++++
.../memory-hotplug-nvdimm-pmem.args | 31 ++++++++++++
.../memory-hotplug-nvdimm-unarmed.args | 31 ++++++++++++
tests/qemuxml2argvtest.c | 15 ++++++
10 files changed, 212 insertions(+), 4 deletions(-)
create mode 100644 tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.args
create mode 100644 tests/qemuxml2argvdata/memory-hotplug-nvdimm-persistence.args
create mode 100644 tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.args
create mode 100644 tests/qemuxml2argvdata/memory-hotplug-nvdimm-unarmed.args
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 20a1a0c201..1bb9ceb888 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -516,6 +516,11 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"memory-backend-memfd.hugetlb",
"iothread.poll-max-ns",
"machine.pseries.cap-nested-hv",
+ "nvdimm-align",
+ "nvdimm-pmem",
+
+ /* 325 */
+ "nvdimm-unarmed",
);
@@ -4190,6 +4195,18 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM))
virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM);
+ if (qemuCaps->version < 2001200 &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE_ALIGN))
+ virQEMUCapsClear(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE_ALIGN);
+
+ if (qemuCaps->version < 3000000 &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM_UNARMED))
+ virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM_UNARMED);
+
+ if (qemuCaps->version < 3001000 &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE_PMEM))
+ virQEMUCapsClear(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE_PMEM);
+
if (ARCH_IS_X86(qemuCaps->arch) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_CACHE);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index b1990b6bb8..8d5fc5e8e5 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -500,6 +500,11 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_OBJECT_MEMORY_MEMFD_HUGETLB, /* -object memory-backend-memfd.hugetlb */
QEMU_CAPS_IOTHREAD_POLLING, /* -object iothread.poll-max-ns */
QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, /* -machine pseries.cap-nested-hv */
+ QEMU_CAPS_OBJECT_MEMORY_FILE_ALIGN, /* -object memory-backend-file supports align property */
+ QEMU_CAPS_OBJECT_MEMORY_FILE_PMEM, /* -object memory-backend-file supports pmem property*/
+
+ /* 325 */
+ QEMU_CAPS_DEVICE_NVDIMM_UNARMED, /* -device nvdimm supports unarmed property*/
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 315419c71b..219f5734d1 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3400,6 +3400,34 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps,
if (virJSONValueObjectAdd(props, "U:size", mem->size * 1024, NULL) < 0)
goto cleanup;
+ if (mem->alignsize) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE_ALIGN)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("align property is not available "
+ "with this QEMU binary"));
+ goto cleanup;
+ }
+ if (virJSONValueObjectAdd(props,
+ "U:align",
+ mem->alignsize * 1024,
+ NULL) < 0)
+ goto cleanup;
+ }
+
+ if (mem->nvdimmPmem) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE_PMEM)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("pmem property is not available "
+ "with this QEMU binary"));
+ goto cleanup;
+ }
+ if (virJSONValueObjectAdd(props,
+ "s:pmem",
+ mem->nvdimmPmem ? "on" : "off",
+ NULL) < 0)
+ goto cleanup;
+ }
+
if (mem->sourceNodes) {
nodemask = mem->sourceNodes;
} else {
@@ -3541,8 +3569,10 @@ qemuBuildMemoryDimmBackendStr(virBufferPtr buf,
char *
-qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem)
+qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
+ qemuDomainObjPrivatePtr priv)
{
+ virQEMUCapsPtr qemuCaps = priv->qemuCaps;
virBuffer buf = VIR_BUFFER_INITIALIZER;
const char *device;
@@ -3569,6 +3599,17 @@ qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem)
if (mem->labelsize)
virBufferAsprintf(&buf, "label-size=%llu,", mem->labelsize * 1024);
+ if (mem->nvdimmUnarmed) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM_UNARMED)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unarmed is not available "
+ "with this QEMU binary"));
+ return NULL;
+ }
+ virBufferAsprintf(&buf, "unarmed=%s,",
+ mem->nvdimmUnarmed ? "on" : "off");
+ }
+
virBufferAsprintf(&buf, "memdev=mem%s,id=%s",
mem->info.alias, mem->info.alias);
@@ -7383,6 +7424,11 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
goto cleanup;
}
virBufferAddLit(&buf, ",nvdimm=on");
+
+ if (def->mems[i]->nvdimmPersistence) {
+ virBufferAsprintf(&buf, ",nvdimm-persistence=%s",
+ virDomainMemoryPersistenceTypeToString(def->mems[i]->nvdimmPersistence));
+ }
break;
}
}
@@ -7860,7 +7906,7 @@ qemuBuildMemoryDeviceCommandLine(virCommandPtr cmd,
virCommandAddArg(cmd, "-object");
virCommandAddArgBuffer(cmd, &buf);
- if (!(dimmStr = qemuBuildMemoryDeviceStr(def->mems[i])))
+ if (!(dimmStr = qemuBuildMemoryDeviceStr(def->mems[i], priv)))
return -1;
virCommandAddArgList(cmd, "-device", dimmStr, NULL);
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index d382cd592a..eee13a20d8 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -131,7 +131,8 @@ int qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps,
virBitmapPtr autoNodeset,
bool force);
-char *qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem);
+char *qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
+ qemuDomainObjPrivatePtr priv);
/* Current, best practice */
char *qemuBuildPCIHostdevDevStr(const virDomainDef *def,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 5f756b7267..2da056ed1f 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2564,7 +2564,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
if (virAsprintf(&objalias, "mem%s", mem->info.alias) < 0)
goto cleanup;
- if (!(devstr = qemuBuildMemoryDeviceStr(mem)))
+ if (!(devstr = qemuBuildMemoryDeviceStr(mem, priv)))
goto cleanup;
if (qemuBuildMemoryBackendProps(&props, objalias, cfg,
diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.args
new file mode 100644
index 0000000000..432f6222a1
--- /dev/null
+++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.args
@@ -0,0 +1,31 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-i686 \
+-name QEMUGuest1 \
+-S \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+-m size=219136k,slots=16,maxmem=1099511627776k \
+-smp 2,sockets=2,cores=1,threads=1 \
+-numa node,nodeid=0,cpus=0-1,mem=214 \
+-object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+share=no,size=536870912,align=2097152 \
+-device nvdimm,node=0,memdev=memnvdimm0,id=nvdimm0,slot=0 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,\
+bootindex=1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-persistence.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-persistence.args
new file mode 100644
index 0000000000..8ff03e3ca3
--- /dev/null
+++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-persistence.args
@@ -0,0 +1,31 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-i686 \
+-name QEMUGuest1 \
+-S \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on,nvdimm-persistence=mem-ctrl \
+-m size=219136k,slots=16,maxmem=1099511627776k \
+-smp 2,sockets=2,cores=1,threads=1 \
+-numa node,nodeid=0,cpus=0-1,mem=214 \
+-object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+share=no,size=536870912 \
+-device nvdimm,node=0,memdev=memnvdimm0,id=nvdimm0,slot=0 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,\
+bootindex=1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.args
new file mode 100644
index 0000000000..d34ac5b4c5
--- /dev/null
+++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.args
@@ -0,0 +1,31 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-i686 \
+-name QEMUGuest1 \
+-S \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+-m size=219136k,slots=16,maxmem=1099511627776k \
+-smp 2,sockets=2,cores=1,threads=1 \
+-numa node,nodeid=0,cpus=0-1,mem=214 \
+-object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+share=no,size=536870912,pmem=on \
+-device nvdimm,node=0,memdev=memnvdimm0,id=nvdimm0,slot=0 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,\
+bootindex=1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-unarmed.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-unarmed.args
new file mode 100644
index 0000000000..64dcc5a250
--- /dev/null
+++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-unarmed.args
@@ -0,0 +1,31 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-i686 \
+-name QEMUGuest1 \
+-S \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+-m size=219136k,slots=16,maxmem=1099511627776k \
+-smp 2,sockets=2,cores=1,threads=1 \
+-numa node,nodeid=0,cpus=0-1,mem=214 \
+-object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+share=no,size=536870912 \
+-device nvdimm,node=0,unarmed=on,memdev=memnvdimm0,id=nvdimm0,slot=0 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,\
+bootindex=1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index eae2b7edf7..5a1677ec01 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2754,6 +2754,21 @@ mymain(void)
DO_TEST("memory-hotplug-nvdimm-label",
QEMU_CAPS_DEVICE_NVDIMM,
QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("memory-hotplug-nvdimm-align",
+ QEMU_CAPS_DEVICE_NVDIMM,
+ QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE,
+ QEMU_CAPS_OBJECT_MEMORY_FILE_ALIGN);
+ DO_TEST("memory-hotplug-nvdimm-pmem",
+ QEMU_CAPS_DEVICE_NVDIMM,
+ QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE,
+ QEMU_CAPS_OBJECT_MEMORY_FILE_PMEM);
+ DO_TEST("memory-hotplug-nvdimm-unarmed",
+ QEMU_CAPS_DEVICE_NVDIMM,
+ QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE,
+ QEMU_CAPS_DEVICE_NVDIMM_UNARMED);
+ DO_TEST("memory-hotplug-nvdimm-persistence",
+ QEMU_CAPS_DEVICE_NVDIMM,
+ QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("machine-aeskeywrap-on-caps",
QEMU_CAPS_AES_KEY_WRAP,
--
2.17.1
5 years, 11 months