Skip binding's filter reinstantiation if it is not changed since it was instantiated last time. The purpose it to fasten libvirtd restart at least if filters won't changed, see RFC [1]. Thus we need to keep instantiated filter hash for binding in binding's status. This patch skips filters reinstantiation on firewalld reloads too but this will be fixed in next patch. [1] https://www.redhat.com/archives/libvir-list/2018-October/msg00657.html Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx> --- src/conf/virnwfilterbindingobj.c | 20 +++++++++++++ src/conf/virnwfilterbindingobj.h | 7 +++++ src/libvirt_private.syms | 2 ++ src/nwfilter/nwfilter_driver.c | 2 ++ src/nwfilter/nwfilter_gentech_driver.c | 52 +++++++++++++++++++++++++++++++--- src/nwfilter/nwfilter_gentech_driver.h | 3 ++ 6 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/conf/virnwfilterbindingobj.c b/src/conf/virnwfilterbindingobj.c index d145fe32..355981e 100644 --- a/src/conf/virnwfilterbindingobj.c +++ b/src/conf/virnwfilterbindingobj.c @@ -36,6 +36,7 @@ struct _virNWFilterBindingObj { bool removing; virNWFilterBindingDefPtr def; + char *filterhash; }; @@ -103,6 +104,22 @@ virNWFilterBindingObjSetRemoving(virNWFilterBindingObjPtr obj, } +void +virNWFilterBindingObjSetFilterhash(virNWFilterBindingObjPtr obj, + char *filterhash) +{ + VIR_FREE(obj->filterhash); + obj->filterhash = filterhash; +} + + +char* +virNWFilterBindingObjGetFilterhash(virNWFilterBindingObjPtr obj) +{ + return obj->filterhash; +} + + /** * virNWFilterBindingObjEndAPI: * @obj: binding object @@ -207,6 +224,8 @@ virNWFilterBindingObjParseXML(xmlDocPtr doc, if (!(ret = virNWFilterBindingObjNew())) return NULL; + ret->filterhash = virXPathString("string(./filterhash)", ctxt); + if (!(node = virXPathNode("./filterbinding", ctxt))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("filter binding status missing content")); @@ -284,6 +303,7 @@ virNWFilterBindingObjFormat(const virNWFilterBindingObj *obj) virBufferAddLit(&buf, "<filterbindingstatus>\n"); virBufferAdjustIndent(&buf, 2); + virBufferAsprintf(&buf, "<filterhash>%s</filterhash>\n", obj->filterhash); if (virNWFilterBindingDefFormatBuf(&buf, obj->def) < 0) { virBufferFreeAndReset(&buf); diff --git a/src/conf/virnwfilterbindingobj.h b/src/conf/virnwfilterbindingobj.h index 21ae85b..fbcee03 100644 --- a/src/conf/virnwfilterbindingobj.h +++ b/src/conf/virnwfilterbindingobj.h @@ -46,6 +46,13 @@ virNWFilterBindingObjSetRemoving(virNWFilterBindingObjPtr obj, bool removing); void +virNWFilterBindingObjSetFilterhash(virNWFilterBindingObjPtr obj, + char *filterhash); + +char* +virNWFilterBindingObjGetFilterhash(virNWFilterBindingObjPtr obj); + +void virNWFilterBindingObjEndAPI(virNWFilterBindingObjPtr *obj); char * diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a7cfe80..cc3aaba 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1057,11 +1057,13 @@ virNWFilterBindingObjDelete; virNWFilterBindingObjEndAPI; virNWFilterBindingObjFormat; virNWFilterBindingObjGetDef; +virNWFilterBindingObjGetFilterhash; virNWFilterBindingObjGetRemoving; virNWFilterBindingObjNew; virNWFilterBindingObjParseFile; virNWFilterBindingObjSave; virNWFilterBindingObjSetDef; +virNWFilterBindingObjSetFilterhash; virNWFilterBindingObjSetRemoving; diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c index 5591c0b..5d25d65 100644 --- a/src/nwfilter/nwfilter_driver.c +++ b/src/nwfilter/nwfilter_driver.c @@ -778,6 +778,8 @@ nwfilterBindingCreateXML(virConnectPtr conn, ret = NULL; goto cleanup; } + + virNWFilterBindingUpdateHash(driver->nwfilters, obj); virNWFilterBindingObjSave(obj, driver->bindingDir); cleanup: diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index d64621b..46b1144 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -982,10 +982,12 @@ enum { static int virNWFilterBuildOne(virNWFilterDriverStatePtr driver, - virNWFilterBindingDefPtr binding, + virNWFilterBindingObjPtr bindingobj, virHashTablePtr skipInterfaces, int step) { + virNWFilterBindingDefPtr binding = virNWFilterBindingObjGetDef(bindingobj); + virNWFilterObjPtr filter; bool skipIface; int ret = 0; VIR_DEBUG("Building filter for portdev=%s step=%d", binding->portdevname, step); @@ -1009,13 +1011,39 @@ virNWFilterBuildOne(virNWFilterDriverStatePtr driver, break; case STEP_SWITCH: - if (!virHashLookup(skipInterfaces, binding->portdevname)) + if (!virHashLookup(skipInterfaces, binding->portdevname)) { ret = virNWFilterTearOldFilter(binding); + + virNWFilterBindingUpdateHash(driver->nwfilters, bindingobj); + virNWFilterBindingObjSave(bindingobj, driver->bindingDir); + } break; case STEP_APPLY_CURRENT: + if ((filter = virNWFilterObjListFindByName(driver->nwfilters, + binding->filter))) { + char *filterhash = virNWFilterObjGetHash(filter); + char *bindinghash = virNWFilterBindingObjGetFilterhash(bindingobj); + + if (filterhash && bindinghash && STREQ(filterhash, bindinghash)) { + VIR_DEBUG("skip binding reinstantiating owner=%s portdevname=%s" + " filter=%s", + binding->ownername, binding->portdevname, + binding->filter); + + virNWFilterObjUnlock(filter); + break; + } + + virNWFilterObjUnlock(filter); + } + ret = virNWFilterInstantiateFilter(driver, binding); + if (ret == 0) { + virNWFilterBindingUpdateHash(driver->nwfilters, bindingobj); + virNWFilterBindingObjSave(bindingobj, driver->bindingDir); + } break; } @@ -1033,9 +1061,8 @@ static int virNWFilterBuildIter(virNWFilterBindingObjPtr binding, void *opaque) { struct virNWFilterBuildData *data = opaque; - virNWFilterBindingDefPtr def = virNWFilterBindingObjGetDef(binding); - return virNWFilterBuildOne(data->driver, def, + return virNWFilterBuildOne(data->driver, binding, data->skipInterfaces, data->step); } @@ -1084,3 +1111,20 @@ virNWFilterBuildAll(virNWFilterDriverStatePtr driver, } return ret; } + + +void +virNWFilterBindingUpdateHash(virNWFilterObjListPtr nwfilters, + virNWFilterBindingObjPtr binding) +{ + virNWFilterObjPtr filter; + virNWFilterBindingDefPtr def = virNWFilterBindingObjGetDef(binding); + char *filterhash = NULL; + + if ((filter = virNWFilterObjListFindByName(nwfilters, def->filter))) { + ignore_value(VIR_STRDUP_QUIET(filterhash, virNWFilterObjGetHash(filter))); + virNWFilterObjUnlock(filter); + } + + virNWFilterBindingObjSetFilterhash(binding, filterhash); +} diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter_gentech_driver.h index 2cd19c9..3c96c34 100644 --- a/src/nwfilter/nwfilter_gentech_driver.h +++ b/src/nwfilter/nwfilter_gentech_driver.h @@ -57,4 +57,7 @@ virHashTablePtr virNWFilterCreateVarHashmap(const char *macaddr, int virNWFilterBuildAll(virNWFilterDriverStatePtr driver, bool newFilters); +void virNWFilterBindingUpdateHash(virNWFilterObjListPtr nwfilters, + virNWFilterBindingObjPtr binding); + #endif -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list