[libvirt] [PATCH 2/4] nwfilter: don't reinstantiate filters if they are not changed

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Thu Oct 18 06:49:32 UTC 2018


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 at 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




More information about the libvir-list mailing list