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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux