[PATCH 0/3] Support network interface downscript

QEMU has the ability to run a script when a NIC is brought up and down. Libvirt only enables use of the up script at this time. This series add support for postscript when NIC is down/detached. Chen Hanxiao (3): downscript: Support network interface downscript downscript: add test case doc: downscript: updating the documentation docs/formatdomain.html.in | 6 ++- docs/schemas/domaincommon.rng | 8 ++++ src/conf/domain_conf.c | 9 ++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_extdevice.c | 4 ++ src/qemu/qemu_hotplug.c | 6 +++ tests/qemuxml2argvdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmloutdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 9 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/downscript.xml create mode 100644 tests/qemuxml2xmloutdata/downscript.xml -- 2.23.0

https://gitlab.com/libvirt/libvirt/-/issues/13 Add support for downscript: <interface type='ethernet'> <mac address='00:11:22:33:44:55'/> <script path='/etc/qemu-ifup'/> <downscript path='/path/to/my/downscript'/> </interface> Signed-off-by: Chen Hanxiao <chen_han_xiao@126.com> --- docs/schemas/domaincommon.rng | 8 ++++++++ src/conf/domain_conf.c | 9 +++++++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_extdevice.c | 4 ++++ src/qemu/qemu_hotplug.c | 6 ++++++ 5 files changed, 28 insertions(+) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 9d60b090f3..6727cd743b 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3191,6 +3191,14 @@ <empty/> </element> </optional> + <optional> + <element name="downscript"> + <attribute name="path"> + <ref name="filePath"/> + </attribute> + <empty/> + </element> + </optional> <optional> <element name="backenddomain"> <attribute name="name"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c201fc901d..1406cf079e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2520,6 +2520,7 @@ virDomainNetDefClear(virDomainNetDefPtr def) VIR_FREE(def->teaming.persistent); 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); @@ -11977,6 +11978,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, g_autofree char *ifname_guest = NULL; g_autofree char *ifname_guest_actual = NULL; g_autofree char *script = NULL; + g_autofree char *downscript = NULL; g_autofree char *address = NULL; g_autofree char *port = NULL; g_autofree char *localaddr = NULL; @@ -12149,6 +12151,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, } else if (!script && virXMLNodeNameEqual(cur, "script")) { script = virXMLPropString(cur, "path"); + } else if (!downscript && + virXMLNodeNameEqual(cur, "downscript")) { + downscript = virXMLPropString(cur, "path"); } else if (!domain_name && virXMLNodeNameEqual(cur, "backenddomain")) { domain_name = virXMLPropString(cur, "name"); @@ -12482,6 +12487,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, if (script != NULL) def->script = g_steal_pointer(&script); + if (downscript != NULL) + def->downscript = g_steal_pointer(&downscript); if (domain_name != NULL) def->domain_name = g_steal_pointer(&domain_name); if (ifname != NULL) @@ -26567,6 +26574,8 @@ virDomainNetDefFormat(virBufferPtr buf, virBufferEscapeString(buf, "<script path='%s'/>\n", def->script); + 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 ddc75d8de2..e152c599ca 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1055,6 +1055,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'/>) */ int managed_tap; /* enum virTristateBool - ABSENT == YES */ diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c index 2096272761..4962521de4 100644 --- a/src/qemu/qemu_extdevice.c +++ b/src/qemu/qemu_extdevice.c @@ -213,6 +213,7 @@ qemuExtDevicesStop(virQEMUDriverPtr driver, virDomainObjPtr vm) { virDomainDefPtr def = vm->def; + virDomainNetType actualType; size_t i; if (qemuExtDevicesInitPaths(driver, def) < 0) @@ -230,10 +231,13 @@ qemuExtDevicesStop(virQEMUDriverPtr driver, for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; + actualType = virDomainNetGetActualType(net); qemuSlirpPtr slirp = QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp; if (slirp) qemuSlirpStop(slirp, vm, driver, net); + if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET && net->downscript) + virNetDevRunEthernetScript(net->ifname, net->downscript); } for (i = 0; i < def->nfss; i++) { diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 5608566d69..97c6508a55 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -5942,6 +5942,12 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, ret = qemuDomainRemoveDevice(driver, vm, &detach); } + if ((virDomainDeviceType)match->type == VIR_DOMAIN_DEVICE_NET) { + virDomainNetDefPtr net = detach.data.net; + if (net->script) + virNetDevRunEthernetScript(net->ifname, net->downscript); + } + cleanup: if (!async) qemuDomainResetDeviceRemoval(vm); -- 2.23.0

On 5/21/20 3:59 PM, Chen Hanxiao wrote:
https://gitlab.com/libvirt/libvirt/-/issues/13
Add support for downscript:
<interface type='ethernet'> <mac address='00:11:22:33:44:55'/> <script path='/etc/qemu-ifup'/> <downscript path='/path/to/my/downscript'/> </interface>
Signed-off-by: Chen Hanxiao <chen_han_xiao@126.com> --- docs/schemas/domaincommon.rng | 8 ++++++++ src/conf/domain_conf.c | 9 +++++++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_extdevice.c | 4 ++++ src/qemu/qemu_hotplug.c | 6 ++++++ 5 files changed, 28 insertions(+)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 9d60b090f3..6727cd743b 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3191,6 +3191,14 @@ <empty/> </element> </optional> + <optional> + <element name="downscript"> + <attribute name="path"> + <ref name="filePath"/> + </attribute> + <empty/> + </element> + </optional> <optional> <element name="backenddomain"> <attribute name="name"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c201fc901d..1406cf079e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2520,6 +2520,7 @@ virDomainNetDefClear(virDomainNetDefPtr def) VIR_FREE(def->teaming.persistent); 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); @@ -11977,6 +11978,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, g_autofree char *ifname_guest = NULL; g_autofree char *ifname_guest_actual = NULL; g_autofree char *script = NULL; + g_autofree char *downscript = NULL; g_autofree char *address = NULL; g_autofree char *port = NULL; g_autofree char *localaddr = NULL; @@ -12149,6 +12151,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, } else if (!script && virXMLNodeNameEqual(cur, "script")) { script = virXMLPropString(cur, "path"); + } else if (!downscript && + virXMLNodeNameEqual(cur, "downscript")) { + downscript = virXMLPropString(cur, "path"); } else if (!domain_name && virXMLNodeNameEqual(cur, "backenddomain")) { domain_name = virXMLPropString(cur, "name"); @@ -12482,6 +12487,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
if (script != NULL) def->script = g_steal_pointer(&script); + if (downscript != NULL) + def->downscript = g_steal_pointer(&downscript); if (domain_name != NULL) def->domain_name = g_steal_pointer(&domain_name); if (ifname != NULL) @@ -26567,6 +26574,8 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferEscapeString(buf, "<script path='%s'/>\n", def->script); + 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 ddc75d8de2..e152c599ca 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1055,6 +1055,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'/>) */ int managed_tap; /* enum virTristateBool - ABSENT == YES */ diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c index 2096272761..4962521de4 100644 --- a/src/qemu/qemu_extdevice.c +++ b/src/qemu/qemu_extdevice.c @@ -213,6 +213,7 @@ qemuExtDevicesStop(virQEMUDriverPtr driver, virDomainObjPtr vm) { virDomainDefPtr def = vm->def; + virDomainNetType actualType; size_t i;
if (qemuExtDevicesInitPaths(driver, def) < 0) @@ -230,10 +231,13 @@ qemuExtDevicesStop(virQEMUDriverPtr driver,
for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; + actualType = virDomainNetGetActualType(net); qemuSlirpPtr slirp = QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp;
if (slirp) qemuSlirpStop(slirp, vm, driver, net); + if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET && net->downscript) + virNetDevRunEthernetScript(net->ifname, net->downscript); }
for (i = 0; i < def->nfss; i++) { diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 5608566d69..97c6508a55 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -5942,6 +5942,12 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, ret = qemuDomainRemoveDevice(driver, vm, &detach); }
+ if ((virDomainDeviceType)match->type == VIR_DOMAIN_DEVICE_NET) { + virDomainNetDefPtr net = detach.data.net; + if (net->script) + virNetDevRunEthernetScript(net->ifname, net->downscript); + }
The fact that you need to typecast the comparison should have raised a red flag. But this is not placed correctly anyway. The way the device detach works is: 1) we send the detach request to qemu, which in turn sends it to the guest 2) we wait couple of seconds to see whether the detach was successful, if it was, then qemuDomainRemoveDevice() is called, which handles the device removal and cleanup (e.g. executing down scripts) 3) if the detach timed out, then the control is returned back to user and we wait for DEVICE_DEL event, which eventually comes and then the qemuDomainRemoveDevice() is called, which calls the down script. Therefore, the proper place and form is: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index d831fcd4a6..7dde7c0c75 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4672,7 +4672,11 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver, virDomainNetReleaseActualDevice(conn, vm->def, net); else VIR_WARN("Unable to release network device '%s'", NULLSTR(net->ifname)); + } else if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET) { + if (net->script) + virNetDevRunEthernetScript(net->ifname, net->downscript); } + virDomainNetDefFree(net); return 0; } For the rest see my comment to the cover letter. Michal

add a testcase for new element. Signed-off-by: Chen Hanxiao <chen_han_xiao@126.com> --- tests/qemuxml2argvdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmloutdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 3 files changed, 121 insertions(+) create mode 100644 tests/qemuxml2argvdata/downscript.xml create mode 100644 tests/qemuxml2xmloutdata/downscript.xml diff --git a/tests/qemuxml2argvdata/downscript.xml b/tests/qemuxml2argvdata/downscript.xml new file mode 100644 index 0000000000..70c5f1d376 --- /dev/null +++ b/tests/qemuxml2argvdata/downscript.xml @@ -0,0 +1,60 @@ +<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'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/images/img1'/> + <target dev='vda' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + </disk> + <controller type='usb' index='0' model='piix3-uhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + </controller> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/export/fs1'/> + <target dir='fs1'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </filesystem> + <filesystem type='mount' accessmode='mapped'> + <driver type='path'/> + <source dir='/export/fs2'/> + <target dir='fs2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </filesystem> + <interface type='ethernet'> + <mac address='52:54:00:f6:66:88'/> + <script path='/home/hehe.sh'/> + <downscript path='/home/dada.sh'/> + <model type='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + </interface> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/downscript.xml b/tests/qemuxml2xmloutdata/downscript.xml new file mode 100644 index 0000000000..70c5f1d376 --- /dev/null +++ b/tests/qemuxml2xmloutdata/downscript.xml @@ -0,0 +1,60 @@ +<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'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/images/img1'/> + <target dev='vda' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + </disk> + <controller type='usb' index='0' model='piix3-uhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + </controller> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/export/fs1'/> + <target dir='fs1'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </filesystem> + <filesystem type='mount' accessmode='mapped'> + <driver type='path'/> + <source dir='/export/fs2'/> + <target dir='fs2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </filesystem> + <interface type='ethernet'> + <mac address='52:54:00:f6:66:88'/> + <script path='/home/hehe.sh'/> + <downscript path='/home/dada.sh'/> + <model type='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + </interface> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 033f81013e..dcc7b29ded 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1478,6 +1478,7 @@ mymain(void) DO_TEST_CAPS_ARCH_LATEST("x86_64-default-cpu-tcg-q35-4.2", "x86_64"); DO_TEST_CAPS_LATEST("virtio-9p-multidevs"); + DO_TEST("downscript", NONE); if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir); -- 2.23.0

We can give a postscript for some netdev. Signed-off-by: Chen Hanxiao <chen_han_xiao@126.com> --- docs/formatdomain.html.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 23eb029234..4e2320d537 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5879,7 +5879,10 @@ <p> After creating/opening the tap device, an optional shell script (given in the <code>path</code> attribute of - the <code><script></code> element) will be run; this can + the <code><script></code> element) will be run; + Also, after detaching/closing the tap device, an optional shell + script (given in the <code>path</code> attribute of + the <code><downscript></code> element) will be run; this can be used to do whatever extra host network integration is required. </p> @@ -5889,6 +5892,7 @@ <devices> <interface type='ethernet'> <script path='/etc/qemu-ifup-mynet'/> + <downscript path='/etc/qemu-ifdown-mynet'/> </interface> ... <interface type='ethernet'> -- 2.23.0

On 5/21/20 3:59 PM, Chen Hanxiao wrote:
QEMU has the ability to run a script when a NIC is brought up and down. Libvirt only enables use of the up script at this time. This series add support for postscript when NIC is down/detached.
Chen Hanxiao (3): downscript: Support network interface downscript downscript: add test case doc: downscript: updating the documentation
docs/formatdomain.html.in | 6 ++- docs/schemas/domaincommon.rng | 8 ++++ src/conf/domain_conf.c | 9 ++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_extdevice.c | 4 ++ src/qemu/qemu_hotplug.c | 6 +++ tests/qemuxml2argvdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmloutdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 9 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/downscript.xml create mode 100644 tests/qemuxml2xmloutdata/downscript.xml
I don't mean to be picky, especially with new contributors (well, you have one contribution already, exactly one month ago). Anyway, we usually structure patches differently. In the first patch we add XML parsing, formatting, RNG change, documentation and xml2xml test case. In the second the feature is implemented in the driver and xml2argv test case is introduced. In the third patch the news.xml is adjusted. The reason is that this way it is easier for downstream maintainers to backport patches. Mind posting a v2 which follows that? Apart from a small nit in 1/3 the rest looks good. Michal

At 2020-05-22 23:09:21, "Michal Privoznik" <mprivozn@redhat.com> wrote:
On 5/21/20 3:59 PM, Chen Hanxiao wrote:
QEMU has the ability to run a script when a NIC is brought up and down. Libvirt only enables use of the up script at this time. This series add support for postscript when NIC is down/detached.
Chen Hanxiao (3): downscript: Support network interface downscript downscript: add test case doc: downscript: updating the documentation
docs/formatdomain.html.in | 6 ++- docs/schemas/domaincommon.rng | 8 ++++ src/conf/domain_conf.c | 9 ++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_extdevice.c | 4 ++ src/qemu/qemu_hotplug.c | 6 +++ tests/qemuxml2argvdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmloutdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 9 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/downscript.xml create mode 100644 tests/qemuxml2xmloutdata/downscript.xml
I don't mean to be picky, especially with new contributors (well, you have one contribution already, exactly one month ago). Anyway, we usually structure patches differently. In the first patch we add XML parsing, formatting, RNG change, documentation and xml2xml test case. In the second the feature is implemented in the driver and xml2argv test case is introduced. In the third patch the news.xml is adjusted.
The reason is that this way it is easier for downstream maintainers to backport patches.
Mind posting a v2 which follows that? Apart from a small nit in 1/3 the rest looks good.
I've contributed to libvirt for years(from another email), but did not send patched for years either :). I'll post a v2 to address all the comments aroud the weekends. Regards, - Hanxiao

On 5/22/20 7:16 PM, Chen Hanxiao wrote:
At 2020-05-22 23:09:21, "Michal Privoznik" <mprivozn@redhat.com> wrote:
On 5/21/20 3:59 PM, Chen Hanxiao wrote:
QEMU has the ability to run a script when a NIC is brought up and down. Libvirt only enables use of the up script at this time. This series add support for postscript when NIC is down/detached.
Chen Hanxiao (3): downscript: Support network interface downscript downscript: add test case doc: downscript: updating the documentation
docs/formatdomain.html.in | 6 ++- docs/schemas/domaincommon.rng | 8 ++++ src/conf/domain_conf.c | 9 ++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_extdevice.c | 4 ++ src/qemu/qemu_hotplug.c | 6 +++ tests/qemuxml2argvdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmloutdata/downscript.xml | 60 +++++++++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 9 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/downscript.xml create mode 100644 tests/qemuxml2xmloutdata/downscript.xml
I don't mean to be picky, especially with new contributors (well, you have one contribution already, exactly one month ago). Anyway, we usually structure patches differently. In the first patch we add XML parsing, formatting, RNG change, documentation and xml2xml test case. In the second the feature is implemented in the driver and xml2argv test case is introduced. In the third patch the news.xml is adjusted.
The reason is that this way it is easier for downstream maintainers to backport patches.
Mind posting a v2 which follows that? Apart from a small nit in 1/3 the rest looks good.
I've contributed to libvirt for years(from another email), but did not send patched for years either :).
Ah sorry about that. I've done quick 'git log --author=' and found only one commit. BTW: you can update .mailmap in the top most directory to join authorship of older commits. https://git-scm.com/docs/git-shortlog#_mapping_authors
I'll post a v2 to address all the comments aroud the weekends.
Okay, I will review them. Michal
participants (2)
-
Chen Hanxiao
-
Michal Privoznik