https://bugzilla.redhat.com/show_bug.cgi?id=1607202
It's stated that if the admin wants to shoot themselves in the foot by removing the nwfilter binding while the domain is running we will certainly allow that. However, in doing so we also run the risk that a libvirtd restart will cause the domain to be shutdown, which isn't a good thing. So add another boolean to virDomainConfNWFilterInstantiate which allows us to recover somewhat gracefully in the event the virNWFilterBindingCreateXML fails when we come from qemuProcessReconnect and we determine that the filter has been deleted. It was there at some point (it had to be), but if it's missing, then we don't want to cause the guest to stop running, so issue a warning and continue on. Signed-off-by: John Ferlan <jfer...@redhat.com> --- src/conf/domain_nwfilter.c | 33 ++++++++++++++++++++++++++++----- src/conf/domain_nwfilter.h | 3 ++- src/lxc/lxc_process.c | 3 ++- src/qemu/qemu_hotplug.c | 7 ++++--- src/qemu/qemu_interface.c | 6 ++++-- src/qemu/qemu_process.c | 10 +++++++--- src/uml/uml_conf.c | 3 ++- 7 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/conf/domain_nwfilter.c b/src/conf/domain_nwfilter.c index f39c8a1f9b..3e6e462def 100644 --- a/src/conf/domain_nwfilter.c +++ b/src/conf/domain_nwfilter.c @@ -85,16 +85,19 @@ int virDomainConfNWFilterInstantiate(const char *vmname, const unsigned char *vmuuid, virDomainNetDefPtr net, - bool ignoreExists) + bool ignoreExists, + bool ignoreDeleted) { virConnectPtr conn = virGetConnectNWFilter(); virNWFilterBindingDefPtr def = NULL; virNWFilterBindingPtr binding = NULL; + virNWFilterPtr nwfilter = NULL; char *xml = NULL; int ret = -1; - VIR_DEBUG("vmname=%s portdev=%s filter=%s ignoreExists=%d", - vmname, NULLSTR(net->ifname), NULLSTR(net->filter), ignoreExists); + VIR_DEBUG("vmname=%s portdev=%s filter=%s ignoreExists=%d ignoreDeleted=%d", + vmname, NULLSTR(net->ifname), NULLSTR(net->filter), + ignoreExists, ignoreDeleted); if (!conn) goto cleanup; @@ -113,14 +116,34 @@ virDomainConfNWFilterInstantiate(const char *vmname, if (!(xml = virNWFilterBindingDefFormat(def))) goto cleanup; - if (!(binding = virNWFilterBindingCreateXML(conn, xml, 0))) - goto cleanup; + if (!(binding = virNWFilterBindingCreateXML(conn, xml, 0))) { + virErrorPtr orig_err; + + if (!ignoreDeleted) + goto cleanup; + + /* Let's determine if the error was because the filter was deleted. + * Save the orig_err just in case it's not a failure to find the + * filter by name. */ + orig_err = virSaveLastError(); + nwfilter = virNWFilterLookupByName(conn, def->filter); + virSetError(orig_err); + virFreeError(orig_err); + if (nwfilter) + goto cleanup; + + VIR_WARN("filter '%s' for binding '%s' has been deleted while the " + "guest was running, ignoring for restart processing", + def->filter, def->portdevname); + virResetLastError(); + } ret = 0; cleanup: VIR_FREE(xml); virNWFilterBindingDefFree(def); + virObjectUnref(nwfilter); virObjectUnref(binding); virObjectUnref(conn); return ret; diff --git a/src/conf/domain_nwfilter.h b/src/conf/domain_nwfilter.h index 6bda228fc8..e3a2f7a7f2 100644 --- a/src/conf/domain_nwfilter.h +++ b/src/conf/domain_nwfilter.h @@ -26,7 +26,8 @@ int virDomainConfNWFilterInstantiate(const char *vmname, const unsigned char *vmuuid, virDomainNetDefPtr net, - bool ignoreExists); + bool ignoreExists, + bool ignoreDeleted); void virDomainConfNWFilterTeardown(virDomainNetDefPtr net); void virDomainConfVMNWFilterTeardown(virDomainObjPtr vm); diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 33c806630b..b8b014ca72 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -303,7 +303,8 @@ virLXCProcessSetupInterfaceTap(virDomainDefPtr vm, } if (net->filter && - virDomainConfNWFilterInstantiate(vm->name, vm->uuid, net, false) < 0) + virDomainConfNWFilterInstantiate(vm->name, vm->uuid, net, + false, false) < 0) goto cleanup; ret = containerVeth; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 0b84a503bb..11b10cbe14 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -3434,8 +3434,8 @@ qemuDomainChangeNetFilter(virDomainObjPtr vm, virDomainConfNWFilterTeardown(olddev); if (newdev->filter && - virDomainConfNWFilterInstantiate(vm->def->name, - vm->def->uuid, newdev, false) < 0) { + virDomainConfNWFilterInstantiate(vm->def->name, vm->def->uuid, newdev, + false, false) < 0) { virErrorPtr errobj; virReportError(VIR_ERR_OPERATION_FAILED, @@ -3444,7 +3444,8 @@ qemuDomainChangeNetFilter(virDomainObjPtr vm, olddev->ifname); virErrorPreserveLast(&errobj); ignore_value(virDomainConfNWFilterInstantiate(vm->def->name, - vm->def->uuid, olddev, false)); + vm->def->uuid, olddev, + false, false)); virErrorRestore(&errobj); return -1; } diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c index a3f13093f5..fc5f39b76d 100644 --- a/src/qemu/qemu_interface.c +++ b/src/qemu/qemu_interface.c @@ -467,7 +467,8 @@ qemuInterfaceEthernetConnect(virDomainDefPtr def, goto cleanup; if (net->filter && - virDomainConfNWFilterInstantiate(def->name, def->uuid, net, false) < 0) { + virDomainConfNWFilterInstantiate(def->name, def->uuid, net, + false, false) < 0) { goto cleanup; } @@ -586,7 +587,8 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def, goto cleanup; if (net->filter && - virDomainConfNWFilterInstantiate(def->name, def->uuid, net, false) < 0) { + virDomainConfNWFilterInstantiate(def->name, def->uuid, net, + false, false) < 0) { goto cleanup; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index ab749389ee..4d8b3017b4 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3161,14 +3161,18 @@ qemuProcessNotifyNets(virDomainDefPtr def) } static int -qemuProcessFiltersInstantiate(virDomainDefPtr def, bool ignoreExists) +qemuProcessFiltersInstantiate(virDomainDefPtr def, + bool ignoreExists, + bool ignoreDeleted) { size_t i; for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; if ((net->filter) && (net->ifname)) { - if (virDomainConfNWFilterInstantiate(def->name, def->uuid, net, ignoreExists) < 0) + if (virDomainConfNWFilterInstantiate(def->name, def->uuid, net, + ignoreExists, + ignoreDeleted) < 0) return 1; } } @@ -7892,7 +7896,7 @@ qemuProcessReconnect(void *opaque) qemuProcessNotifyNets(obj->def); - if (qemuProcessFiltersInstantiate(obj->def, true)) + if (qemuProcessFiltersInstantiate(obj->def, true, true)) goto error; if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0) diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index f116e619ef..29d26848f3 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -137,7 +137,8 @@ umlConnectTapDevice(virDomainDefPtr vm, } if (net->filter) { - if (virDomainConfNWFilterInstantiate(vm->name, vm->uuid, net, false) < 0) { + if (virDomainConfNWFilterInstantiate(vm->name, vm->uuid, net, + false, false) < 0) { if (template_ifname) VIR_FREE(net->ifname); goto error; -- 2.17.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list