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). --- src/conf/network_conf.c | 308 +++++++++++++++++++++++++++++++++++++++++++++++ src/conf/network_conf.h | 8 ++ src/libvirt_private.syms | 1 + 3 files changed, 317 insertions(+) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index a48eb9e..2a65f1d 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -2251,6 +2251,314 @@ 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, + unsigned int command ATTRIBUTE_UNUSED, + int parentIndex ATTRIBUTE_UNUSED, + xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, + /* virNetworkUpdateFlags */ + unsigned int fflags ATTRIBUTE_UNUSED) +{ + virNetworkDefUpdateNoSupport(def, "bridge"); + return -1; +} + +static int +virNetworkDefUpdateDomain(virNetworkDefPtr def, + unsigned int command ATTRIBUTE_UNUSED, + int parentIndex ATTRIBUTE_UNUSED, + xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, + /* virNetworkUpdateFlags */ + unsigned int fflags ATTRIBUTE_UNUSED) +{ + virNetworkDefUpdateNoSupport(def, "domain"); + return -1; +} + +static int +virNetworkDefUpdateIP(virNetworkDefPtr def, + unsigned int command ATTRIBUTE_UNUSED, + int parentIndex ATTRIBUTE_UNUSED, + xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, + /* virNetworkUpdateFlags */ + unsigned int fflags ATTRIBUTE_UNUSED) +{ + virNetworkDefUpdateNoSupport(def, "ip"); + return -1; +} + +static int +virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def, + unsigned int command ATTRIBUTE_UNUSED, + 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, + unsigned int command ATTRIBUTE_UNUSED, + 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, + unsigned int command ATTRIBUTE_UNUSED, + int parentIndex ATTRIBUTE_UNUSED, + xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, + /* virNetworkUpdateFlags */ + unsigned int fflags ATTRIBUTE_UNUSED) +{ + virNetworkDefUpdateNoSupport(def, "forward"); + return -1; +} + +static int +virNetworkDefUpdateForwardInterface(virNetworkDefPtr def, + unsigned int command ATTRIBUTE_UNUSED, + 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, + unsigned int command ATTRIBUTE_UNUSED, + 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, + unsigned int command ATTRIBUTE_UNUSED, + int parentIndex ATTRIBUTE_UNUSED, + xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, + /* virNetworkUpdateFlags */ + unsigned int fflags ATTRIBUTE_UNUSED) +{ + virNetworkDefUpdateNoSupport(def, "portgroup"); + return -1; +} + +static int +virNetworkDefUpdateDNSHost(virNetworkDefPtr def, + unsigned int command ATTRIBUTE_UNUSED, + 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, + unsigned int command ATTRIBUTE_UNUSED, + 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, + unsigned int command ATTRIBUTE_UNUSED, + 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 command, /* virNetworkUpdateCommand */ + 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, command, parentIndex, ctxt, flags); + break; + + case VIR_NETWORK_SECTION_DOMAIN: + ret = virNetworkDefUpdateDomain(def, command, parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_IP: + ret = virNetworkDefUpdateIP(def, command, parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_IP_DHCP_HOST: + ret = virNetworkDefUpdateIPDHCPHost(def, command, + parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_IP_DHCP_RANGE: + ret = virNetworkDefUpdateIPDHCPRange(def, command, + parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_FORWARD: + ret = virNetworkDefUpdateForward(def, command, + parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_FORWARD_INTERFACE: + ret = virNetworkDefUpdateForwardInterface(def, command, + parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_FORWARD_PF: + ret = virNetworkDefUpdateForwardPF(def, command, + parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_PORTGROUP: + ret = virNetworkDefUpdatePortgroup(def, command, + parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_DNS_HOST: + ret = virNetworkDefUpdateDNSHost(def, command, + parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_DNS_TXT: + ret = virNetworkDefUpdateDNSTxt(def, command, parentIndex, ctxt, flags); + break; + case VIR_NETWORK_SECTION_DNS_SRV: + ret = virNetworkDefUpdateDNSSrv(def, command, 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 command, /* virNetworkUpdateCommand */ + 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, command, 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, command, 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..c8ed2ea 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -326,6 +326,14 @@ int virNetworkSetBridgeName(const virNetworkObjListPtr nets, void virNetworkSetBridgeMacAddr(virNetworkDefPtr def); +int +virNetworkObjUpdate(virNetworkObjPtr obj, + unsigned int command, /* virNetworkUpdateCommand */ + 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 39e06e4..ec2e544 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list