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

[libvirt] [PATCHv2 06/10] conf: implement NetworkObj backend of virNetworkUpdate API



virNetworkObjUpdate takes care of all virNetworkUpdate-related changes
to the data stored in the in-memory virNetworkObj list. It should be
called by network drivers that use this in-memory list.

virNetworkObjUpdate *does not* take care of updating any disk-based
copies of the config, nor does it perform any other operations
necessary to have the new config data take effect (e.g. it won't
re-write dnsmasq host files, nor will it send a SIGHUP to dnsmasq) -
those things should all be taken care of in the network driver
function that calls virNetworkObjUpdate (assuming that it returns
success).
---

I'm resending this patch because, while implementing the backend for a
specific section (IP_DHCP_HOST), I realized that it will be much more
useful for virNetworkObjUpdate() to create an xmlDoc and
xmlXPathContext, and send that down to the section-specific functions
rather than the character string - they're all going to need an xmlDoc
anyway, so I may as well write the code once.


 src/conf/network_conf.c  | 287 +++++++++++++++++++++++++++++++++++++++++++++++
 src/conf/network_conf.h  |   7 ++
 src/libvirt_private.syms |   1 +
 3 files changed, 295 insertions(+)

diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index a48eb9e..d991b2a 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -2251,6 +2251,293 @@ void virNetworkSetBridgeMacAddr(virNetworkDefPtr def)
     }
 }
 
+/* NetworkObj backend of the virNetworkUpdate API */
+
+static void
+virNetworkDefUpdateNoSupport(virNetworkDefPtr def, const char *section)
+{
+    virReportError(VIR_ERR_NO_SUPPORT,
+                   _("can't update '%s' section of network '%s'"),
+                   section, def->name);
+}
+
+#if 0
+static int
+virNetworkDefUpdateCheckElementName(virNetworkDefPtr def,
+                                    xmlNodePtr node,
+                                    const char *section)
+{
+    if (!xmlStrEqual(node->name, BAD_CAST section)) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("unexpected element <%s>, expecting <%s>, "
+                         "while updating network '%s'"),
+                       node->name, section, def->name);
+        return -1;
+    }
+    return 0;
+}
+#endif
+
+static int
+virNetworkDefUpdateBridge(virNetworkDefPtr def,
+                          int parentIndex ATTRIBUTE_UNUSED,
+                          xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                          /* virNetworkUpdateFlags */
+                          unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "bridge");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateDomain(virNetworkDefPtr def,
+                          int parentIndex ATTRIBUTE_UNUSED,
+                          xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                          /* virNetworkUpdateFlags */
+                          unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "domain");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateIP(virNetworkDefPtr def,
+                      int parentIndex ATTRIBUTE_UNUSED,
+                      xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                      /* virNetworkUpdateFlags */
+                      unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "ip");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def,
+                              int parentIndex ATTRIBUTE_UNUSED,
+                              xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                              /* virNetworkUpdateFlags */
+                              unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "ip dhcp host");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr def,
+                               int parentIndex ATTRIBUTE_UNUSED,
+                               xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                               /* virNetworkUpdateFlags */
+                               unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "ip dhcp range");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateForward(virNetworkDefPtr def,
+                           int parentIndex ATTRIBUTE_UNUSED,
+                           xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                           /* virNetworkUpdateFlags */
+                           unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "forward");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateForwardInterface(virNetworkDefPtr def,
+                                    int parentIndex ATTRIBUTE_UNUSED,
+                                    xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                                    /* virNetworkUpdateFlags */
+                                    unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "forward interface");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateForwardPF(virNetworkDefPtr def,
+                             int parentIndex ATTRIBUTE_UNUSED,
+                             xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                             /* virNetworkUpdateFlags */
+                             unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "forward pf");
+    return -1;
+}
+
+static int
+virNetworkDefUpdatePortgroup(virNetworkDefPtr def,
+                             int parentIndex ATTRIBUTE_UNUSED,
+                             xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                             /* virNetworkUpdateFlags */
+                             unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "portgroup");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateDNSHost(virNetworkDefPtr def,
+                           int parentIndex ATTRIBUTE_UNUSED,
+                           xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                           /* virNetworkUpdateFlags */
+                           unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "dns host");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateDNSTxt(virNetworkDefPtr def,
+                          int parentIndex ATTRIBUTE_UNUSED,
+                          xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                          /* virNetworkUpdateFlags */
+                          unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "dns txt");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateDNSSrv(virNetworkDefPtr def,
+                          int parentIndex ATTRIBUTE_UNUSED,
+                          xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
+                          /* virNetworkUpdateFlags */
+                          unsigned int fflags ATTRIBUTE_UNUSED)
+{
+    virNetworkDefUpdateNoSupport(def, "dns txt");
+    return -1;
+}
+
+static int
+virNetworkDefUpdateSection(virNetworkDefPtr def,
+                           unsigned int section, /* virNetworkUpdateSection */
+                           int parentIndex,
+                           const char *xml,
+                           unsigned int flags)  /* virNetworkUpdateFlags */
+{
+    int ret = -1;
+    xmlDocPtr doc;
+    xmlXPathContextPtr ctxt = NULL;
+
+    if (!(doc = virXMLParseStringCtxt(xml, _("network_update_xml"), &ctxt)))
+        goto cleanup;
+
+    switch (section) {
+    case VIR_NETWORK_SECTION_BRIDGE:
+        ret = virNetworkDefUpdateBridge(def, parentIndex, ctxt, flags);
+        break;
+
+    case VIR_NETWORK_SECTION_DOMAIN:
+        ret = virNetworkDefUpdateDomain(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_IP:
+        ret = virNetworkDefUpdateIP(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_IP_DHCP_HOST:
+        ret = virNetworkDefUpdateIPDHCPHost(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_IP_DHCP_RANGE:
+        ret = virNetworkDefUpdateIPDHCPRange(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_FORWARD:
+        ret = virNetworkDefUpdateForward(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_FORWARD_INTERFACE:
+        ret = virNetworkDefUpdateForwardInterface(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_FORWARD_PF:
+        ret = virNetworkDefUpdateForwardPF(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_PORTGROUP:
+        ret = virNetworkDefUpdatePortgroup(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_DNS_HOST:
+        ret = virNetworkDefUpdateDNSHost(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_DNS_TXT:
+        ret = virNetworkDefUpdateDNSTxt(def, parentIndex, ctxt, flags);
+        break;
+    case VIR_NETWORK_SECTION_DNS_SRV:
+        ret = virNetworkDefUpdateDNSSrv(def, parentIndex, ctxt, flags);
+        break;
+    default:
+        virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                       _("can't update unrecognized section of network"));
+        break;
+    }
+
+cleanup:
+    xmlFreeDoc(doc);
+    xmlXPathFreeContext(ctxt);
+    return ret;
+}
+
+/*
+ * virNetworkObjUpdate:
+ *
+ * Apply the supplied update to the given virNetworkObj. Except for
+ * @network pointing to an actual network object rather than the
+ * opaque virNetworkPtr, parameters are identical to the public API
+ * virNetworkUpdate.
+ *
+ * The original virNetworkDefs are copied, and all modifications made
+ * to these copies. The originals are replaced with the copies only
+ * after success has been guaranteed.
+ *
+ * Returns: -1 on error, 0 on success.
+ */
+int
+virNetworkObjUpdate(virNetworkObjPtr network,
+                    unsigned int section, /* virNetworkUpdateSection */
+                    int parentIndex,
+                    const char *xml,
+                    unsigned int flags)  /* virNetworkUpdateFlags */
+{
+    int ret = -1;
+    virNetworkDefPtr def = NULL;
+
+    /* normalize config data, and check for common invalid requests. */
+    if (virNetworkConfigChangeSetup(network, flags) < 0)
+       goto cleanup;
+
+    if (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE) {
+        /* work on a copy of the def */
+        if (!(def = virNetworkDefCopy(network->def, 0)))
+            goto cleanup;
+        if (virNetworkDefUpdateSection(def, section,
+                                       parentIndex, xml, flags) < 0) {
+            goto cleanup;
+        }
+        /* successfully modified copy, now replace original */
+        virNetworkDefFree(network->def);
+        network->def = def;
+        def = NULL;
+    }
+
+    if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) {
+        /* work on a copy of the def */
+        if (!(def = virNetworkDefCopy(virNetworkObjGetPersistentDef(network),
+                                      VIR_NETWORK_XML_INACTIVE))) {
+            goto cleanup;
+        }
+        if (virNetworkDefUpdateSection(def, section,
+                                       parentIndex, xml, flags) < 0) {
+            goto cleanup;
+        }
+        /* successfully modified copy, now replace original */
+        if (virNetworkObjReplacePersistentDef(network, def) < 0)
+           goto cleanup;
+        def = NULL;
+    }
+
+    ret = 0;
+cleanup:
+    virNetworkDefFree(def);
+    return ret;
+}
+
 /*
  * virNetworkObjIsDuplicate:
  * @doms : virNetworkObjListPtr to search
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 0d37a8b..3d12f58 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -326,6 +326,13 @@ int virNetworkSetBridgeName(const virNetworkObjListPtr nets,
 
 void virNetworkSetBridgeMacAddr(virNetworkDefPtr def);
 
+int
+virNetworkObjUpdate(virNetworkObjPtr obj,
+                    unsigned int section, /* virNetworkUpdateSection */
+                    int parentIndex,
+                    const char *xml,
+                    unsigned int flags);  /* virNetworkUpdateFlags */
+
 int virNetworkObjIsDuplicate(virNetworkObjListPtr doms,
                              virNetworkDefPtr def,
                              unsigned int check_active);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9e87357..a24f626 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -863,6 +863,7 @@ virNetworkObjLock;
 virNetworkObjReplacePersistentDef;
 virNetworkObjSetDefTransient;
 virNetworkObjUnlock;
+virNetworkObjUpdate;
 virNetworkRemoveInactive;
 virNetworkSaveConfig;
 virNetworkSaveStatus;
-- 
1.7.11.4


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