[libvirt] [PATCH RFC] network: define new API virNetworkUpdate

Laine Stump laine at laine.org
Fri Sep 14 16:58:25 UTC 2012


This patch adds a new public API virNetworkUpdate that will permit
updating an existing network configuration without requiring that the
network be destroyed/restarted for the changes to take effect.

---

an example of use: to add a dhcp host entry to network "net", you would do this:


   virNetworkUpdate(net, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
                    "<host mac='00:11:22:33:44:55' ip='192.168.122.5'/>",
                    VIR_NETWORK_UPDATE_AFFECT_LIVE
                    | VIR_NETWORK_UPDATE_AFFECT_CONFIG
                    | VIR_NETWORK_UPDATE_ADD_LAST);

To delete that same entry:

   virNetworkUpdate(net, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1,
                    "<host mac='00:11:22:33:44:55'/>",
                    VIR_NETWORK_UPDATE_AFFECT_LIVE
                    | VIR_NETWORK_UPDATE_AFFECT_CONFIG
                    | VIR_NETWORK_UPDATE_DELETE);

If you wanted to force any of these to affect the dhcp host list in
the 3rd <ip> element of the network, you would replace "-1" with "2".

I'm still working on an example of one of the backends of this, but
need eyeballs on the API, since that's the most critical part before
the freeze. I would appreciate anyone with a few spare minutes who can
take a look.

Differences from email thread:

1) Aside from being actual code instead of just pseudo code, I've
changed the "index" arg into "parentIndex" to avoid confusion between
the index of the element we're looking at (e.g. which host in the list
of hosts in a <dhcp> element) and the index of the parent (e.g. which
<ip> element will contain the <dhcp> with the list of <hosts> we want
to update).

I also changed this from a unsigned into to an int so that it can hold
the special value "-1", which means "pick the most useful/only
item". Again, in the case of VIR_NETWORK_SECTION_IP_DHCP_HOST, this
would mean to pick the one <ip> element that actually has a <dhcp>
section (may not be the first, but there can only be one).

I'll follow with a backend implementation of at least one of the
update sections as soon as I get all the underlying utility functions
working properly.

2) added VIR_NETWORK_UPDATE_AFFECT_CURRENT similar to
   VIR_DOMAIN_AFFECT_CURRENT

 include/libvirt/libvirt.h.in | 50 ++++++++++++++++++++++++++++++++++++
 src/driver.h                 |  7 ++++++
 src/libvirt.c                | 60 +++++++++++++++++++++++++++++++++++++++++++-
 src/libvirt_public.syms      |  1 +
 4 files changed, 117 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index b0d34c5..d91e6c2 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2328,6 +2328,56 @@ virNetworkPtr           virNetworkDefineXML     (virConnectPtr conn,
 int                     virNetworkUndefine      (virNetworkPtr network);
 
 /*
+ *  virNetworkUpdateSection:
+ *
+ *    describes which section of a <network> definition the provided
+ *    xml should be applied to.
+ *
+ */
+typedef enum {
+    VIR_NETWORK_SECTION_BRIDGE            =  0,
+    VIR_NETWORK_SECTION_DOMAIN            =  1,
+    VIR_NETWORK_SECTION_IP                =  2,
+    VIR_NETWORK_SECTION_IP_DHCP_HOST      =  3,
+    VIR_NETWORK_SECTION_IP_DHCP_RANGE     =  4,
+    VIR_NETWORK_SECTION_FORWARD           =  5,
+    VIR_NETWORK_SECTION_FORWARD_INTERFACE =  6,
+    VIR_NETWORK_SECTION_FORWARD_PF        =  7,
+    VIR_NETWORK_SECTION_PORTGROUP         =  8,
+    VIR_NETWORK_SECTION_DNS_HOST          =  9,
+    VIR_NETWORK_SECTION_DNS_TXT           = 10,
+    VIR_NETWORK_SECTION_DNS_SRV           = 11,
+#ifdef VIR_ENUM_SENTINELS
+    VIR_NETWORK_SECTION_LAST
+#endif
+} virNetworkUpdateSection;
+
+/*
+ * virNetworkUpdateFlags:
+ *
+ *  Used to specify what type of operation to perform, and whether to
+ *  affect live network, persistent config, or both.
+ */
+typedef enum {
+    VIR_NETWORK_UPDATE_AFFECT_CURRENT = 0,
+    VIR_NETWORK_UPDATE_AFFECT_LIVE    = 1 << 0,
+    VIR_NETWORK_UPDATE_AFFECT_CONFIG  = 1 << 1,
+    VIR_NETWORK_UPDATE_EXISTING       = 1 << 2,
+    VIR_NETWORK_UPDATE_DELETE         = 1 << 3,
+    VIR_NETWORK_UPDATE_ADD_LAST       = 1 << 4,
+    VIR_NETWORK_UPDATE_ADD_FIRST      = 1 << 5,
+    } virNetworkUpdateFlags;
+
+/*
+ * Update an existing network definition
+ */
+int                     virNetworkUpdate(virNetworkPtr network,
+                                         unsigned int section, /* virNetworkUpdateSection */
+                                         int parentIndex,
+                                         const char *xml,
+                                         unsigned int flags);
+
+/*
  * Activate persistent network
  */
 int                     virNetworkCreate        (virNetworkPtr network);
diff --git a/src/driver.h b/src/driver.h
index 534da05..958712a 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -1101,6 +1101,12 @@ typedef virNetworkPtr
 typedef int
         (*virDrvNetworkUndefine)        (virNetworkPtr network);
 typedef int
+        (*virDrvNetworkUpdate)          (virNetworkPtr network,
+                                         unsigned int section, /* virNetworkUpdateSection */
+                                         int parentIndex,
+                                         const char *xml,
+                                         unsigned int flags);
+typedef int
         (*virDrvNetworkCreate)          (virNetworkPtr network);
 typedef int
         (*virDrvNetworkDestroy)         (virNetworkPtr network);
@@ -1150,6 +1156,7 @@ struct _virNetworkDriver {
         virDrvNetworkCreateXML      networkCreateXML;
         virDrvNetworkDefineXML      networkDefineXML;
         virDrvNetworkUndefine       networkUndefine;
+        virDrvNetworkUpdate         networkUpdate;
         virDrvNetworkCreate         networkCreate;
         virDrvNetworkDestroy        networkDestroy;
         virDrvNetworkGetXMLDesc     networkGetXMLDesc;
diff --git a/src/libvirt.c b/src/libvirt.c
index 5639850..133fbf5 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -10207,7 +10207,7 @@ error:
  * @conn: pointer to the hypervisor connection
  * @xml: the XML description for the network, preferably in UTF-8
  *
- * Define a network, but does not create it
+ * Define a network, but do not create it.
  *
  * Returns NULL in case of error, a pointer to the network otherwise
  */
@@ -10286,6 +10286,64 @@ error:
 }
 
 /**
+ * virNetworkUpdate:
+ * @network: pointer to a defined network
+ * @section: which section of the network to update
+ *           (virNetworkUpdateSection)
+ * @index:   which parent element if there are multiple parents
+ *           of the same type (e.g. which <ip> element when
+ *           modifying a <dhcp> element)
+ * @xml: the XML description for the network, preferably in UTF-8
+ * @flags: bitwise or of virNetworkDefineFlags (currently must be 0).
+ *
+ * Update the definition of an existing network, either its live
+ * running state, its persistent configuration, or both.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+virNetworkUpdate(virNetworkPtr network,
+                 unsigned int section, /* virNetworkUpdateSection */
+                 int parentIndex,
+                 const char *xml,
+                 unsigned int flags)
+{
+    virConnectPtr conn;
+    VIR_DEBUG("network=%p, section=%d, parentIndex=%d, xml=%s, flags=0x%x",
+              network, section, parentIndex, xml, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_NETWORK(network)) {
+        virLibNetworkError(VIR_ERR_INVALID_NETWORK, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+    conn = network->conn;
+    if (conn->flags & VIR_CONNECT_RO) {
+        virLibNetworkError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    virCheckNonNullArgGoto(xml, error);
+
+    if (conn->networkDriver && conn->networkDriver->networkUpdate) {
+        int ret;
+        ret = conn->networkDriver->networkUpdate(network, section,
+                                                 parentIndex, xml, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(network->conn);
+    return -1;
+}
+
+/**
  * virNetworkCreate:
  * @network: pointer to a defined network
  *
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 6ff5a77..f953f67 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -558,6 +558,7 @@ LIBVIRT_0.10.2 {
     global:
         virConnectListAllNetworks;
         virConnectListAllStoragePools;
+        virNetworkUpdate;
         virStoragePoolListAllVolumes;
 } LIBVIRT_0.10.0;
 
-- 
1.7.11.4




More information about the libvir-list mailing list