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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list