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(a)virtuozzo.com>
---
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