[libvirt] [PATCH 0/2] Couple of sparse streams improvements
by Michal Privoznik
News entry & one simple fix.
Michal Privoznik (2):
news: Document sparse streams
virStream: Forbid negative seeks
docs/news.xml | 10 ++++++++++
src/internal.h | 7 +++++++
src/rpc/virnetclientstream.c | 1 +
src/util/virfdstream.c | 1 +
4 files changed, 19 insertions(+)
--
2.13.0
7 years, 6 months
[libvirt] [PATCH v2 1/2] util: Deduplicate code in virNetlinkEventServiceStopAll
by Wang King
Commit 15a71e60 introduced the virNetlinkEventServiceStopAll function, and
the code in virNetlinkEventServiceStop is copied to this function. can use
virNetlinkEventServiceStop instead.
---
src/util/virnetlink.c | 25 +++----------------------
1 file changed, 3 insertions(+), 22 deletions(-)
diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index 92ecf77..fad1e8e 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -775,32 +775,13 @@ virNetlinkEventServiceStop(unsigned int protocol)
int
virNetlinkEventServiceStopAll(void)
{
- size_t i, j;
+ size_t i;
virNetlinkEventSrvPrivatePtr srv = NULL;
VIR_INFO("stopping all netlink event services");
- for (i = 0; i < MAX_LINKS; i++) {
- srv = server[i];
- if (!srv)
- continue;
-
- virNetlinkEventServerLock(srv);
- nl_close(srv->netlinknh);
- virNetlinkFree(srv->netlinknh);
- virEventRemoveHandle(srv->eventwatch);
-
- for (j = 0; j < srv->handlesCount; j++) {
- if (srv->handles[j].deleted == VIR_NETLINK_HANDLE_VALID)
- virNetlinkEventRemoveClientPrimitive(j, i);
- }
-
- server[i] = NULL;
- virNetlinkEventServerUnlock(srv);
-
- virMutexDestroy(&srv->lock);
- VIR_FREE(srv);
- }
+ for (i = 0; i < MAX_LINKS; i++)
+ virNetlinkEventServiceStop(i);
return 0;
}
--
2.8.3
7 years, 6 months
[libvirt] [PATCH v4 0/6] Add mdev reporting capability to the nodedev driver
by Erik Skultety
since v1:
- dropped the <description> element from the parent device nested capability
- added missing RNG schema and tests
- updated the documentation to describe the MDEV elements in both the parent
and the child
since v2:
- I further split our PCI sub-capability parser into more blocks as suggested
- instead of one capability 'mdev' for both mdev device and physical parent I
introduced 2, so we can do virsh nodedev-list --cap 'mdev_types' | 'mdev' to
see either parent devices or the mediated devices themselves
- other minor adjustments pointed out during review.
since v3:
- fixed nits
- updated virsh man page to include mdev and mdev_types within the list of
supported capabilities
Erik Skultety (6):
mdev: Pass a uuidstr rather than an mdev object to some util functions
nodedev: conf: Split PCI sub-capability parsing to separate methods
nodedev: Introduce new mdev_types and mdev nodedev capabilities
nodedev: Introduce the mdev capability to a PCI parent device
nodedev: Introduce mdev capability for mediated devices
docs: Document the mediated devices within the nodedev driver
docs/drvnodedev.html.in | 168 +++++++++++-
docs/schemas/nodedev.rng | 43 +++
include/libvirt/libvirt-nodedev.h | 2 +
src/conf/node_device_conf.c | 290 ++++++++++++++++-----
src/conf/node_device_conf.h | 29 ++-
src/conf/virnodedeviceobj.c | 11 +-
src/libvirt-nodedev.c | 2 +
src/libvirt_private.syms | 1 +
src/node_device/node_device_driver.c | 2 +
src/node_device/node_device_udev.c | 165 +++++++++++-
src/qemu/qemu_domain.c | 8 +-
src/security/security_apparmor.c | 10 +-
src/security/security_dac.c | 20 +-
src/security/security_selinux.c | 20 +-
src/util/virmdev.c | 21 +-
src/util/virmdev.h | 4 +-
.../mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml | 8 +
.../pci_0000_02_10_7_mdev_types.xml | 32 +++
tests/nodedevxml2xmltest.c | 2 +
tools/virsh-nodedev.c | 6 +
tools/virsh.pod | 7 +-
21 files changed, 722 insertions(+), 129 deletions(-)
create mode 100644 tests/nodedevschemadata/mdev_3627463d_b7f0_4fea_b468_f1da537d301b.xml
create mode 100644 tests/nodedevschemadata/pci_0000_02_10_7_mdev_types.xml
--
2.13.0
7 years, 6 months
[libvirt] [PATCH] pci: fix link maximum speed detection
by Marek Marczykowski-Górecki
Commit 8e09663 "pci: recognize/report GEN4 (PCIe 4.0) card 16GT/s Link
speed" introduced another speed into enum, but mistakenly also altered
field width, so one bit of link width was included there.
Signed-off-by: Marek Marczykowski-Górecki <marmarek(a)invisiblethingslab.com>
---
src/util/virpci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 83c7e74..2c1b758 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -147,7 +147,7 @@ struct _virPCIDeviceList {
#define PCI_EXP_DEVCAP 0x4 /* Device capabilities */
#define PCI_EXP_DEVCAP_FLR (1<<28) /* Function Level Reset */
#define PCI_EXP_LNKCAP 0xc /* Link Capabilities */
-#define PCI_EXP_LNKCAP_SPEED 0x0001f /* Maximum Link Speed */
+#define PCI_EXP_LNKCAP_SPEED 0x0000f /* Maximum Link Speed */
#define PCI_EXP_LNKCAP_WIDTH 0x003f0 /* Maximum Link Width */
#define PCI_EXP_LNKSTA 0x12 /* Link Status */
#define PCI_EXP_LNKSTA_SPEED 0x000f /* Negotiated Link Speed */
--
2.7.4
7 years, 6 months
[libvirt] [PATCH] virDomainDefCheckABIStabilityFlags: Check for memoryBacking
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1450349
Problem is, memoryBacking is part of guest ABI. Therefore
changing it on migration/restore from an image can lead
qemu/guest to rejecting the image.
At the same time, move other partial checks of virDomainMemtune
into the same function: virDomainMemtuneCheckABIStability.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/conf/domain_conf.c | 101 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 75 insertions(+), 26 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9eba70a95..89b93f4ad 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19786,6 +19786,80 @@ virDomainTPMDefCheckABIStability(virDomainTPMDefPtr src,
return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info);
}
+
+static bool
+virDomainMemtuneCheckABIStability(const virDomainDef *src,
+ const virDomainDef *dst,
+ unsigned int flags)
+{
+ if (virDomainDefGetMemoryInitial(src) != virDomainDefGetMemoryInitial(dst)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target domain max memory %lld "
+ "does not match source %lld"),
+ virDomainDefGetMemoryInitial(dst),
+ virDomainDefGetMemoryInitial(src));
+ return false;
+ }
+
+ if (!(flags & VIR_DOMAIN_DEF_ABI_CHECK_SKIP_VOLATILE) &&
+ src->mem.cur_balloon != dst->mem.cur_balloon) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target domain current memory %lld "
+ "does not match source %lld"),
+ dst->mem.cur_balloon,
+ src->mem.cur_balloon);
+ return false;
+ }
+
+ if (src->mem.max_memory != dst->mem.max_memory) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target maximum memory size '%llu' "
+ "doesn't match source '%llu'"),
+ dst->mem.max_memory,
+ src->mem.max_memory);
+ return false;
+ }
+
+ if (src->mem.memory_slots != dst->mem.memory_slots) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target domain memory slots "
+ "count '%u' doesn't match source '%u'"),
+ dst->mem.memory_slots,
+ src->mem.memory_slots);
+ return false;
+ }
+
+ if (src->mem.source != dst->mem.source) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target memoryBacking source '%s' doesn't "
+ "match source memoryBacking source'%s'"),
+ virDomainMemorySourceTypeToString(dst->mem.source),
+ virDomainMemorySourceTypeToString(src->mem.source));
+ return false;
+ }
+
+ if (src->mem.access != dst->mem.access) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target memoryBacking access '%s' doesn't "
+ "match access memoryBacking access'%s'"),
+ virDomainMemoryAccessTypeToString(dst->mem.access),
+ virDomainMemoryAccessTypeToString(src->mem.access));
+ return false;
+ }
+
+ if (src->mem.allocation != dst->mem.allocation) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target memoryBacking allocation '%s' doesn't "
+ "match allocation memoryBacking allocation'%s'"),
+ virDomainMemoryAllocationTypeToString(dst->mem.allocation),
+ virDomainMemoryAllocationTypeToString(src->mem.allocation));
+ return false;
+ }
+
+ return true;
+}
+
+
static bool
virDomainMemoryDefCheckABIStability(virDomainMemoryDefPtr src,
virDomainMemoryDefPtr dst)
@@ -19940,37 +20014,12 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src,
goto error;
}
- if (virDomainDefGetMemoryInitial(src) != virDomainDefGetMemoryInitial(dst)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Target domain max memory %lld does not match source %lld"),
- virDomainDefGetMemoryInitial(dst),
- virDomainDefGetMemoryInitial(src));
+ if (!virDomainMemtuneCheckABIStability(src, dst, flags))
goto error;
- }
- if (!(flags & VIR_DOMAIN_DEF_ABI_CHECK_SKIP_VOLATILE) &&
- src->mem.cur_balloon != dst->mem.cur_balloon) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Target domain current memory %lld does not match source %lld"),
- dst->mem.cur_balloon, src->mem.cur_balloon);
- goto error;
- }
if (!virDomainNumaCheckABIStability(src->numa, dst->numa))
goto error;
- if (src->mem.memory_slots != dst->mem.memory_slots) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Target domain memory slots count '%u' doesn't match source '%u'"),
- dst->mem.memory_slots, src->mem.memory_slots);
- goto error;
- }
- if (src->mem.max_memory != dst->mem.max_memory) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Target maximum memory size '%llu' doesn't match source '%llu'"),
- dst->mem.max_memory, src->mem.max_memory);
- goto error;
- }
-
if (!virDomainDefVcpuCheckAbiStability(src, dst))
goto error;
--
2.13.0
7 years, 6 months
[libvirt] [PATCH] docs: Update pointer to networking information
by Andrea Bolognani
Commit 6fb5dd4fd804 removed docs/archnetwork.html.in, but
left behind a pointer to it in docs/formatnetwork.html.in.
Update it so that it points to the wiki, which contains
more detailed and recent information anyway.
---
docs/formatnetwork.html.in | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 777c341..b410dd6 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -8,9 +8,9 @@
</ul>
<p>
- This page provides an introduction to the network XML format. For background
- information on the concepts referred to here, consult the <a href="archnetwork.html">network driver architecture</a>
- page.
+ This page provides an introduction to the network XML format. For
+ background information on the concepts referred to here, consult the
+ <a href="https://wiki.libvirt.org/page/Networking">relevant wiki page</a>.
</p>
<h2><a name="elements">Element and attribute overview</a></h2>
--
2.7.4
7 years, 6 months
[libvirt] [PATCH v3 00/31] Implement sparse streams for libvirt
by Michal Privoznik
v3 of:
https://www.redhat.com/archives/libvir-list/2017-April/msg00671.html
All the patches can be found on my github:
https://github.com/zippy2/libvirt/tree/sparse_streams2
diff to v2:
- renamed APIs from Skip & GetHoleSize to SendHole & RecvHole
- switched from 'unsigned long long len' to 'long long len' (where len is size of a hole)
- introduced @flags to public APIs for future extensibility
- couple of coding style fixes
- couple of fixes suggested by John in review of v2
As expressed earlier, a lot of these patches should have Reviewed-by tag as
John reviewed majority of them. But we don't have a clear agreement when to use
the tag, so I'm not putting it in just yet. However, will do before pushing.
Some patches were ACKed. However, changes described above changed them, so I'm
not sure ACK still stands.
Michal Privoznik (31):
virfdstream: Use messages instead of pipe
util: Introduce virFileInData
Introduce virStreamRecvFlags
Implement virStreamRecvFlags to some drivers
Introduce virStreamSendHole
Introduce virStreamRecvHole
Introduce VIR_STREAM_RECV_STOP_AT_HOLE flag
Introduce virStreamSparseRecvAll
Introduce virStreamSparseSendAll
Introduce virStreamInData
virNetClientStreamNew: Track origin stream
Add new flag to daemonCreateClientStream and virNetClientStreamNew
RPC: Introduce virNetStreamHole
Introduce VIR_NET_STREAM_HOLE message type
Teach wireshark plugin about VIR_NET_STREAM_HOLE
daemon: Introduce virNetServerProgramSendStreamHole
virnetclientstream: Introduce virNetClientStreamSendHole
daemon: Implement VIR_NET_STREAM_HOLE handling
virnetclientstream: Introduce virNetClientStreamHandleHole
remote_driver: Implement virStreamSendHole
virNetClientStreamRecvPacket: Introduce @flags argument
Introduce virNetClientStreamRecvHole
remote: Implement virStreamRecvHole
virNetClientStream: Wire up VIR_NET_STREAM_HOLE
remote_driver: Implement VIR_STREAM_RECV_STOP_AT_HOLE
daemonStreamHandleRead: Wire up seekable stream
fdstream: Implement sparse stream
gendispatch: Introduce @sparseflag for our calls
Introduce virStorageVol{Download,Upload}Flags
virsh: Implement sparse stream to vol-download
virsh: Implement sparse stream to vol-upload
daemon/remote.c | 2 +-
daemon/stream.c | 148 ++++++++-
daemon/stream.h | 3 +-
include/libvirt/libvirt-storage.h | 9 +
include/libvirt/libvirt-stream.h | 115 ++++++-
src/driver-stream.h | 25 ++
src/esx/esx_stream.c | 16 +-
src/libvirt-storage.c | 4 +-
src/libvirt-stream.c | 526 ++++++++++++++++++++++++++++++
src/libvirt_internal.h | 4 +
src/libvirt_private.syms | 2 +
src/libvirt_public.syms | 9 +
src/libvirt_remote.syms | 3 +
src/remote/remote_driver.c | 99 +++++-
src/remote/remote_protocol.x | 2 +
src/rpc/gendispatch.pl | 21 +-
src/rpc/virnetclient.c | 1 +
src/rpc/virnetclientstream.c | 238 +++++++++++++-
src/rpc/virnetclientstream.h | 18 +-
src/rpc/virnetprotocol.x | 17 +-
src/rpc/virnetserverprogram.c | 35 ++
src/rpc/virnetserverprogram.h | 8 +
src/storage/storage_driver.c | 4 +-
src/storage/storage_util.c | 10 +-
src/util/virfdstream.c | 609 +++++++++++++++++++++++++++++++----
src/util/virfdstream.h | 1 +
src/util/virfile.c | 82 +++++
src/util/virfile.h | 4 +
src/virnetprotocol-structs | 5 +
tests/virfiletest.c | 203 ++++++++++++
tools/virsh-util.c | 65 ++++
tools/virsh-util.h | 29 ++
tools/virsh-volume.c | 50 ++-
tools/virsh.pod | 6 +-
tools/wireshark/src/packet-libvirt.c | 52 +++
tools/wireshark/src/packet-libvirt.h | 2 +
36 files changed, 2301 insertions(+), 126 deletions(-)
--
2.13.0
7 years, 6 months
[libvirt] [PATCH] util: do not leak handles in stop netlink event service
by Wang King
handles stored in virNetlinkEventSrvPrivatePtr should be freed when
stop netlink event service.
---
src/util/virnetlink.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index 92ecf77..b782cfa 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -758,6 +758,7 @@ virNetlinkEventServiceStop(unsigned int protocol)
}
server[protocol] = NULL;
+ VIR_FREE(srv->handles);
virNetlinkEventServerUnlock(srv);
virMutexDestroy(&srv->lock);
@@ -796,6 +797,7 @@ virNetlinkEventServiceStopAll(void)
}
server[i] = NULL;
+ VIR_FREE(srv->handles);
virNetlinkEventServerUnlock(srv);
virMutexDestroy(&srv->lock);
--
2.8.3
7 years, 6 months
[libvirt] [PATCH] virsh: add --io when attaching disks to guests
by Gordon Messmer
virt-install and virt-manager both default to explicitly setting
"io='native'" in the disk "driver" tag. virsh, however, does not and also
does not provide an option to specify that setting at all. As a result,
disks use a different IO mechanism (the default, "threads") when attached
post-setup using virsh. Adding this option allows users to keep disk
performance consistent for disks attached at install, and those attached
afterward.
---
tools/virsh-domain.c | 14 +++++++++++---
tools/virsh.pod | 3 ++-
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 0d19d0e..5c42021 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -267,6 +267,10 @@ static const vshCmdOptDef opts_attach_disk[] = {
.type = VSH_OT_STRING,
.help = N_("cache mode of disk device")
},
+ {.name = "io",
+ .type = VSH_OT_STRING,
+ .help = N_("io policy of disk device")
+ },
{.name = "type",
.type = VSH_OT_STRING,
.help = N_("target device type")
@@ -504,8 +508,9 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
virDomainPtr dom = NULL;
const char *source = NULL, *target = NULL, *driver = NULL,
*subdriver = NULL, *type = NULL, *mode = NULL,
- *iothread = NULL, *cache = NULL, *serial = NULL,
- *straddr = NULL, *wwn = NULL, *targetbus = NULL;
+ *iothread = NULL, *cache = NULL, *io = NULL,
+ *serial = NULL, *straddr = NULL, *wwn = NULL,
+ *targetbus = NULL;
struct DiskAddress diskAddr;
bool isFile = false, functionReturn = false;
int ret;
@@ -537,6 +542,7 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
vshCommandOptStringReq(ctl, cmd, "mode", &mode) < 0 ||
vshCommandOptStringReq(ctl, cmd, "iothread", &iothread) < 0 ||
vshCommandOptStringReq(ctl, cmd, "cache", &cache) < 0 ||
+ vshCommandOptStringReq(ctl, cmd, "io", &io) < 0 ||
vshCommandOptStringReq(ctl, cmd, "serial", &serial) < 0 ||
vshCommandOptStringReq(ctl, cmd, "wwn", &wwn) < 0 ||
vshCommandOptStringReq(ctl, cmd, "address", &straddr) < 0 ||
@@ -579,7 +585,7 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
virBufferAddLit(&buf, ">\n");
virBufferAdjustIndent(&buf, 2);
- if (driver || subdriver || iothread || cache) {
+ if (driver || subdriver || iothread || cache || io) {
virBufferAddLit(&buf, "<driver");
if (driver)
@@ -590,6 +596,8 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
virBufferAsprintf(&buf, " iothread='%s'", iothread);
if (cache)
virBufferAsprintf(&buf, " cache='%s'", cache);
+ if (io)
+ virBufferAsprintf(&buf, " io='%s'", io);
virBufferAddLit(&buf, "/>\n");
}
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 727acf6..f46fb4a 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -2838,7 +2838,7 @@ expected.
=item B<attach-disk> I<domain> I<source> I<target> [[[I<--live>] [I<--config>]
| [I<--current>]] | [I<--persistent>]] [I<--targetbus bus>] [I<--driver
driver>] [I<--subdriver subdriver>] [I<--iothread iothread>]
-[I<--cache cache>] [I<--type type>]
+[I<--cache cache>] [I<--io io>] [I<--type type>]
[I<--mode mode>] [I<--sourcetype sourcetype>] [I<--serial serial>] [I<--wwn
wwn>] [I<--rawio>] [I<--address address>] [I<--multifunction>] [I<--print-xml>]
@@ -2865,6 +2865,7 @@ I<mode> can specify the two specific mode I<readonly> or I<shareable>.
I<sourcetype> can indicate the type of source (block|file)
I<cache> can be one of "default", "none", "writethrough", "writeback",
"directsync" or "unsafe".
+I<io> controls specific policies on I/O; qemu guests support "threads" and "native".
I<iothread> is the number within the range of domain IOThreads to which
this disk may be attached (QEMU only).
I<serial> is the serial of disk device. I<wwn> is the wwn of disk device.
--
2.9.3
7 years, 6 months
[libvirt] [PATCH v2] qemu: Adding 'downscript' feature for QEMU network interfaces.
by Julio Faracco
This commit adds the support for 'downscript' feature:
- For QEMU command line with the option:
'-net downscript=/etc/qemu-ifdown,...'.
- For Domains with a network interface description:
'<interface type='ethernet'>
...
<downscript path='/etc/qemu-ifdown'/>
...
</interface>'
The options 'script' and 'downscript' accept the argument 'no' to disable
the script executions. The way that the code was implemented, the XML file
accepts '<[down]script path='no'>' to solve this problem.
This commit updates the tests and documentation too.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=825939
Signed-off-by: Julio Faracco <jcfaracco(a)gmail.com>
---
docs/formatdomain.html.in | 1 +
docs/schemas/domaincommon.rng | 8 ++++++++
src/conf/domain_conf.c | 13 +++++++++++++
src/conf/domain_conf.h | 1 +
src/qemu/qemu_parse_command.c | 4 ++++
tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.args | 2 +-
tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.xml | 1 +
tests/qemuargv2xmldata/qemuargv2xml-net-eth.args | 2 +-
tests/qemuargv2xmldata/qemuargv2xml-net-eth.xml | 1 +
tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml | 1 +
tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml | 1 +
tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth-ifname.xml | 1 +
tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth.xml | 1 +
13 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 8c884f4..89fe86d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4663,6 +4663,7 @@
<interface type='ethernet'>
<target dev='vnet7'/>
<script path='/etc/qemu-ifup-mynet'/>
+ <downscript path='/etc/qemu-ifdown-mynet'/>
</interface>
</devices>
...</pre>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 281309e..2f88dda 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2609,6 +2609,14 @@
</element>
</optional>
<optional>
+ <element name="downscript">
+ <attribute name="path">
+ <ref name="filePath"/>
+ </attribute>
+ <empty/>
+ </element>
+ </optional>
+ <optional>
<element name="backenddomain">
<attribute name="name">
<ref name="domainName"/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0ff216e..32d5720 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1935,6 +1935,7 @@ virDomainNetDefClear(virDomainNetDefPtr def)
VIR_FREE(def->backend.vhost);
VIR_FREE(def->virtPortProfile);
VIR_FREE(def->script);
+ VIR_FREE(def->downscript);
VIR_FREE(def->domain_name);
VIR_FREE(def->ifname);
VIR_FREE(def->ifname_guest);
@@ -9589,6 +9590,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
char *ifname_guest = NULL;
char *ifname_guest_actual = NULL;
char *script = NULL;
+ char *downscript = NULL;
char *address = NULL;
char *port = NULL;
char *localaddr = NULL;
@@ -9761,6 +9763,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
} else if (!script &&
xmlStrEqual(cur->name, BAD_CAST "script")) {
script = virXMLPropString(cur, "path");
+ } else if (!downscript &&
+ xmlStrEqual(cur->name, BAD_CAST "downscript")) {
+ downscript = virXMLPropString(cur, "path");
} else if (!domain_name &&
xmlStrEqual(cur->name, BAD_CAST "backenddomain")) {
domain_name = virXMLPropString(cur, "name");
@@ -10074,6 +10079,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
def->script = script;
script = NULL;
}
+ if (downscript != NULL) {
+ def->downscript = downscript;
+ downscript = NULL;
+ }
if (domain_name != NULL) {
def->domain_name = domain_name;
domain_name = NULL;
@@ -10356,6 +10365,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
VIR_FREE(dev);
virDomainActualNetDefFree(actual);
VIR_FREE(script);
+ VIR_FREE(downscript);
VIR_FREE(bridge);
VIR_FREE(model);
VIR_FREE(backend);
@@ -22158,6 +22168,9 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferEscapeString(buf, "<script path='%s'/>\n",
def->script);
+ if (def->downscript)
+ virBufferEscapeString(buf, "<downscript path='%s'/>\n",
+ def->downscript);
virBufferEscapeString(buf, "<backenddomain name='%s'/>\n", def->domain_name);
if (def->ifname &&
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 09fb7aa..9deca76 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1024,6 +1024,7 @@ struct _virDomainNetDef {
unsigned long sndbuf;
} tune;
char *script;
+ char *downscript;
char *domain_name; /* backend domain name */
char *ifname; /* interface name on the host (<target dev='x'/>) */
virNetDevIPInfo hostIP;
diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c
index af9063c..d773917 100644
--- a/src/qemu/qemu_parse_command.c
+++ b/src/qemu/qemu_parse_command.c
@@ -1060,6 +1060,10 @@ qemuParseCommandLineNet(virDomainXMLOptionPtr xmlopt,
def->script = values[i];
values[i] = NULL;
} else if (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
+ STREQ(keywords[i], "downscript") && STRNEQ(values[i], "")) {
+ def->downscript = values[i];
+ values[i] = NULL;
+ } else if (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
STREQ(keywords[i], "ifname")) {
def->ifname = values[i];
values[i] = NULL;
diff --git a/tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.args b/tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.args
index 4d74ae4..5d7129c 100644
--- a/tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.args
+++ b/tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.args
@@ -18,6 +18,6 @@ QEMU_AUDIO_DRV=none \
-usb \
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=ide,bus=0,unit=0 \
-net nic,macaddr=00:11:22:33:44:55,vlan=0,model=rtl8139,name=net0 \
--net tap,ifname=nic02,script=/etc/qemu-ifup,vlan=0,name=hostnet0 \
+-net tap,ifname=nic02,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown,vlan=0,name=hostnet0 \
-serial none \
-parallel none
diff --git a/tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.xml b/tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.xml
index fa9a892..8e04efb 100644
--- a/tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.xml
+++ b/tests/qemuargv2xmldata/qemuargv2xml-net-eth-ifname.xml
@@ -30,6 +30,7 @@
<interface type='ethernet'>
<mac address='00:11:22:33:44:55'/>
<script path='/etc/qemu-ifup'/>
+ <downscript path='/etc/qemu-ifdown'/>
<target dev='nic02'/>
<model type='rtl8139'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
diff --git a/tests/qemuargv2xmldata/qemuargv2xml-net-eth.args b/tests/qemuargv2xmldata/qemuargv2xml-net-eth.args
index 89eb4c1..0e3fa21 100644
--- a/tests/qemuargv2xmldata/qemuargv2xml-net-eth.args
+++ b/tests/qemuargv2xmldata/qemuargv2xml-net-eth.args
@@ -18,6 +18,6 @@ QEMU_AUDIO_DRV=none \
-usb \
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=ide,bus=0,unit=0 \
-net nic,macaddr=00:11:22:33:44:55,vlan=0,model=rtl8139,name=net0 \
--net tap,script=/etc/qemu-ifup,vlan=0,name=hostnet0 \
+-net tap,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown,vlan=0,name=hostnet0 \
-serial none \
-parallel none
diff --git a/tests/qemuargv2xmldata/qemuargv2xml-net-eth.xml b/tests/qemuargv2xmldata/qemuargv2xml-net-eth.xml
index 57c4be8..d177ca8 100644
--- a/tests/qemuargv2xmldata/qemuargv2xml-net-eth.xml
+++ b/tests/qemuargv2xmldata/qemuargv2xml-net-eth.xml
@@ -30,6 +30,7 @@
<interface type='ethernet'>
<mac address='00:11:22:33:44:55'/>
<script path='/etc/qemu-ifup'/>
+ <downscript path='/etc/qemu-ifdown'/>
<model type='rtl8139'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml
index dd0d752..21d8259 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml
@@ -26,6 +26,7 @@
<interface type='ethernet'>
<mac address='00:11:22:33:44:55'/>
<script path='/etc/qemu-ifup'/>
+ <downscript path='/etc/qemu-ifdown'/>
<target dev='nic02'/>
<model type='rtl8139'/>
</interface>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml
index 48acadf..9f40122 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml
@@ -26,6 +26,7 @@
<interface type='ethernet'>
<mac address='00:11:22:33:44:55'/>
<script path='/etc/qemu-ifup'/>
+ <downscript path='/etc/qemu-ifdown'/>
<model type='rtl8139'/>
</interface>
<input type='mouse' bus='ps2'/>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth-ifname.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth-ifname.xml
index c36baa0..b71fd5a 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth-ifname.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth-ifname.xml
@@ -30,6 +30,7 @@
<interface type='ethernet'>
<mac address='00:11:22:33:44:55'/>
<script path='/etc/qemu-ifup'/>
+ <downscript path='/etc/qemu-ifdown'/>
<target dev='nic02'/>
<model type='rtl8139'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth.xml
index 898bda6..c55cd68 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-eth.xml
@@ -30,6 +30,7 @@
<interface type='ethernet'>
<mac address='00:11:22:33:44:55'/>
<script path='/etc/qemu-ifup'/>
+ <downscript path='/etc/qemu-ifdown'/>
<model type='rtl8139'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
--
2.7.4
7 years, 6 months