[libvirt] [PATCH v3 2/2] network: Taint networks that are using hook script

Michal Privoznik mprivozn at redhat.com
Mon Feb 10 18:52:35 UTC 2014


Basically, the idea is copied from domain code, where tainting
exists for a while. Currently, only one taint reason exists -
VIR_NETWORK_TAINT_HOOK to mark those networks which caused invoking
of hook script.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/conf/network_conf.c     | 52 ++++++++++++++++++++++++++++++++++++++++++++-
 src/conf/network_conf.h     | 17 +++++++++++++++
 src/libvirt_private.syms    |  3 +++
 src/network/bridge_driver.c | 26 +++++++++++++++++++++++
 4 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index dd3fa19..341b24b 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -72,6 +72,22 @@ VIR_ENUM_IMPL(virNetworkDNSForwardPlainNames,
               "yes",
               "no")
 
+VIR_ENUM_IMPL(virNetworkTaint, VIR_NETWORK_TAINT_LAST,
+              "hook-script");
+
+bool
+virNetworkObjTaint(virNetworkObjPtr obj,
+                   enum virNetworkTaintFlags taint)
+{
+    unsigned int flag = (1 << taint);
+
+    if (obj->taint & flag)
+        return false;
+
+    obj->taint |= flag;
+    return true;
+}
+
 virNetworkObjPtr virNetworkFindByUUID(virNetworkObjListPtr nets,
                                       const unsigned char *uuid)
 {
@@ -2784,6 +2800,7 @@ virNetworkObjFormat(virNetworkObjPtr net,
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     char *class_id = virBitmapFormat(net->class_id);
+    size_t i;
 
     if (!class_id)
         goto no_memory;
@@ -2793,6 +2810,12 @@ virNetworkObjFormat(virNetworkObjPtr net,
     virBufferAsprintf(&buf, "  <floor sum='%llu'/>\n", net->floor_sum);
     VIR_FREE(class_id);
 
+    for (i = 0; i < VIR_NETWORK_TAINT_LAST; i++) {
+        if (net->taint & (1 << i))
+            virBufferAsprintf(&buf, "  <taint flag='%s'/>\n",
+                              virNetworkTaintTypeToString(i));
+    }
+
     virBufferAdjustIndent(&buf, 2);
     if (virNetworkDefFormatInternal(&buf, net->def, flags) < 0)
         goto error;
@@ -2903,10 +2926,13 @@ virNetworkLoadState(virNetworkObjListPtr nets,
     virNetworkDefPtr def = NULL;
     virNetworkObjPtr net = NULL;
     xmlDocPtr xml = NULL;
-    xmlNodePtr node = NULL;
+    xmlNodePtr node = NULL, *nodes = NULL;
     xmlXPathContextPtr ctxt = NULL;
     virBitmapPtr class_id_map = NULL;
     unsigned long long floor_sum_val = 0;
+    unsigned int taint = 0;
+    int n;
+    size_t i;
 
 
     if ((configFile = virNetworkConfigFile(stateDir, name)) == NULL)
@@ -2962,6 +2988,27 @@ virNetworkLoadState(virNetworkObjListPtr nets,
             goto error;
         }
         VIR_FREE(floor_sum);
+
+        if ((n = virXPathNodeSet("./taint", ctxt, &nodes)) < 0)
+            goto error;
+
+        for (i = 0; i < n; i++) {
+            char *str = virXMLPropString(nodes[i], "flag");
+            if (str) {
+                int flag = virNetworkTaintTypeFromString(str);
+                if (flag < 0) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("Unknown taint flag %s"), str);
+                    VIR_FREE(str);
+                    goto error;
+                }
+                VIR_FREE(str);
+                /* Compute taint mask here. The network object does not
+                 * exist yet, so we can't use virNetworkObjtTaint. */
+                taint |= (1 << flag);
+            }
+        }
+        VIR_FREE(nodes);
     }
 
     /* create the object */
@@ -2978,6 +3025,8 @@ virNetworkLoadState(virNetworkObjListPtr nets,
     if (floor_sum_val > 0)
         net->floor_sum = floor_sum_val;
 
+    net->taint = taint;
+
 cleanup:
     VIR_FREE(configFile);
     xmlFreeDoc(xml);
@@ -2985,6 +3034,7 @@ cleanup:
     return net;
 
 error:
+    VIR_FREE(nodes);
     virBitmapFree(class_id_map);
     virNetworkDefFree(def);
     goto cleanup;
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index b84762a..edcc49f 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -287,6 +287,8 @@ struct _virNetworkObj {
 
     virBitmapPtr class_id; /* bitmap of class IDs for QoS */
     unsigned long long floor_sum; /* sum of all 'floor'-s of attached NICs */
+
+    unsigned int taint;
 };
 
 typedef struct _virNetworkObjList virNetworkObjList;
@@ -296,12 +298,26 @@ struct _virNetworkObjList {
     virNetworkObjPtr *objs;
 };
 
+enum virNetworkTaintFlags {
+    VIR_NETWORK_TAINT_HOOK,                 /* Hook script was executed over
+                                               network. We can't guarantee
+                                               connectivity or other settings
+                                               as the script may have played
+                                               with iptables, tc, you name it.
+                                             */
+
+    VIR_NETWORK_TAINT_LAST
+};
+
 static inline int
 virNetworkObjIsActive(const virNetworkObj *net)
 {
     return net->active;
 }
 
+bool virNetworkObjTaint(virNetworkObjPtr obj,
+                        enum virNetworkTaintFlags taint);
+
 virNetworkObjPtr virNetworkFindByUUID(virNetworkObjListPtr nets,
                                       const unsigned char *uuid);
 virNetworkObjPtr virNetworkFindByName(virNetworkObjListPtr nets,
@@ -452,4 +468,5 @@ virNetworkDefUpdateSection(virNetworkDefPtr def,
                            const char *xml,
                            unsigned int flags);  /* virNetworkUpdateFlags */
 
+VIR_ENUM_DECL(virNetworkTaint)
 #endif /* __NETWORK_CONF_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 2c9536a..e1cfca0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -527,6 +527,7 @@ virNetworkObjListFree;
 virNetworkObjLock;
 virNetworkObjReplacePersistentDef;
 virNetworkObjSetDefTransient;
+virNetworkObjTaint;
 virNetworkObjUnlock;
 virNetworkObjUnsetDefTransient;
 virNetworkObjUpdate;
@@ -535,6 +536,8 @@ virNetworkSaveConfig;
 virNetworkSaveStatus;
 virNetworkSetBridgeMacAddr;
 virNetworkSetBridgeName;
+virNetworkTaintTypeFromString;
+virNetworkTaintTypeToString;
 virPortGroupFindByName;
 
 
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 90852d5..285b26b 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -112,6 +112,9 @@ static int networkPlugBandwidth(virNetworkObjPtr net,
 static int networkUnplugBandwidth(virNetworkObjPtr net,
                                   virDomainNetDefPtr iface);
 
+static void networkNetworkObjTaint(virNetworkObjPtr net,
+                                   enum virNetworkTaintFlags taint);
+
 static virNetworkDriverStatePtr driverState = NULL;
 
 static virNetworkObjPtr
@@ -2027,6 +2030,8 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
          */
         if (hookret < 0)
             goto cleanup;
+
+        networkNetworkObjTaint(network, VIR_NETWORK_TAINT_HOOK);
     }
 
     switch (network->def->forward.type) {
@@ -2066,6 +2071,8 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
          */
         if (hookret < 0)
             goto cleanup;
+
+        networkNetworkObjTaint(network, VIR_NETWORK_TAINT_HOOK);
     }
 
     /* Persist the live configuration now that anything autogenerated
@@ -3679,6 +3686,8 @@ validate:
          */
         if (hookret < 0)
             goto error;
+
+        networkNetworkObjTaint(network, VIR_NETWORK_TAINT_HOOK);
     }
 
     if (dev) {
@@ -4103,6 +4112,8 @@ success:
                     VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGED,
                     VIR_HOOK_SUBOP_BEGIN, NULL, xml, NULL);
         VIR_FREE(xml);
+
+        networkNetworkObjTaint(network, VIR_NETWORK_TAINT_HOOK);
     }
 
     VIR_DEBUG("Releasing network %s, %d connections",
@@ -4439,3 +4450,18 @@ networkUnplugBandwidth(virNetworkObjPtr net,
 cleanup:
     return ret;
 }
+
+static void
+networkNetworkObjTaint(virNetworkObjPtr net,
+                       enum virNetworkTaintFlags taint)
+{
+    if (virNetworkObjTaint(net, taint)) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(net->def->uuid, uuidstr);
+
+        VIR_WARN("Network name='%s' uuid=%s is tainted: %s",
+                 net->def->name,
+                 uuidstr,
+                 virNetworkTaintTypeToString(taint));
+    }
+}
-- 
1.8.5.3




More information about the libvir-list mailing list