On Tue, Sep 18, 2012 at 03:39:00AM -0400, Laine Stump wrote: > 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; ACK, not functional but put the framework in place, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list