On Thu, Sep 20, 2012 at 10:25:41PM -0400, Laine Stump wrote: > portgroup elements are located in the toplevel of <network> > objects. There can be multiple <portgroup> elements, and they each > have a unique name attribute. > > Add, delete, and modify are all supported for portgroup. When deleting > a portgroup, only the name must be specified in the provided xml - all > other attributes and subelements are ignored for the purposes of > matching and existing portgroup. > > The bridge driver and virsh already know about the portgroup element, > so providing this backend should cause the entire stack to work. Note > that in the case of portgroup, there is no external daemon based on > the portgroup config, so nothing must be restarted. > > It is important to note that guests make a copy of the appropriate > network's portgroup data when they are started, so although an updated > portgroup's configuration will have an affect on new guests started > after the cahange, existing guests won't magically have their > bandwidth changed, for example. If something like that is desired, it > will take a lot of redesign work in the way network devices are setup > (there is currently no link from the network back to the individual > interfaces using it, much less from a portgroup within a network back > to the individual interfaces). > --- > src/conf/network_conf.c | 85 +++++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 79 insertions(+), 6 deletions(-) > > diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c > index 7fc559f..34487dd 100644 > --- a/src/conf/network_conf.c > +++ b/src/conf/network_conf.c > @@ -2625,15 +2625,88 @@ virNetworkDefUpdateForwardPF(virNetworkDefPtr def, > } > > static int > -virNetworkDefUpdatePortgroup(virNetworkDefPtr def, > - unsigned int command ATTRIBUTE_UNUSED, > +virNetworkDefUpdatePortGroup(virNetworkDefPtr def, > + unsigned int command, > int parentIndex ATTRIBUTE_UNUSED, > - xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, > + xmlXPathContextPtr ctxt, > /* virNetworkUpdateFlags */ > unsigned int fflags ATTRIBUTE_UNUSED) > { > - virNetworkDefUpdateNoSupport(def, "portgroup"); > - return -1; > + int ii, ret = -1; > + virPortGroupDef portgroup; > + > + memset(&portgroup, 0, sizeof(portgroup)); > + > + if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "portgroup") < 0) > + goto cleanup; > + > + if (virNetworkPortGroupParseXML(&portgroup, ctxt->node, ctxt) < 0) > + goto cleanup; > + > + /* check if a portgroup with same name already exists */ > + for (ii = 0; ii < def->nPortGroups; ii++) { > + if (STREQ(portgroup.name, def->portGroups[ii].name)) > + break; > + } > + if (ii == def->nPortGroups && > + ((command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) || > + (command == VIR_NETWORK_UPDATE_COMMAND_DELETE))) { > + virReportError(VIR_ERR_OPERATION_INVALID, > + _("couldn't find a portgroup entry " > + "in network '%s' matching <portgroup name='%s'>"), > + def->name, portgroup.name); > + goto cleanup; > + } else if (ii < def->nPortGroups && > + ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) || > + (command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST))) { > + virReportError(VIR_ERR_OPERATION_INVALID, > + _("there is an existing portgroup entry in " > + "network '%s' that matches " > + "\"<portgroup name='%s'>\""), > + def->name, portgroup.name); > + goto cleanup; > + } > + > + if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) { > + > + /* replace existing entry */ > + virPortGroupDefClear(&def->portGroups[ii]); > + def->portGroups[ii] = portgroup; > + memset(&portgroup, 0, sizeof(portgroup)); > + > + } else if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) || > + (command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) { > + > + /* add to beginning/end of list */ > + if (VIR_REALLOC_N(def->portGroups, def->nPortGroups +1) < 0) { > + virReportOOMError(); > + goto cleanup; > + } > + > + if (command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST) { > + def->portGroups[def->nPortGroups] = portgroup; > + } else { /* implied (command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) */ > + memmove(def->portGroups + 1, def->portGroups, > + sizeof(*def->portGroups) * def->nPortGroups); > + def->portGroups[0] = portgroup; > + } > + def->nPortGroups++; > + memset(&portgroup, 0, sizeof(portgroup)); > + > + } else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) { > + > + /* remove it */ > + virPortGroupDefClear(&def->portGroups[ii]); > + memmove(def->portGroups + ii, def->portGroups + ii + 1, > + sizeof(*def->portGroups) * (def->nPortGroups - ii - 1)); > + def->nPortGroups--; > + ignore_value(VIR_REALLOC_N(def->portGroups, def->nPortGroups)); > + } > + > + ret = 0; > +cleanup: > + virPortGroupDefClear(&portgroup); > + return ret; > } > > static int > @@ -2719,7 +2792,7 @@ virNetworkDefUpdateSection(virNetworkDefPtr def, > parentIndex, ctxt, flags); > break; > case VIR_NETWORK_SECTION_PORTGROUP: > - ret = virNetworkDefUpdatePortgroup(def, command, > + ret = virNetworkDefUpdatePortGroup(def, command, > parentIndex, ctxt, flags); > break; > case VIR_NETWORK_SECTION_DNS_HOST: ACK too, but same remark as for patch 1 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