On Tue, Dec 11, 2012 at 02:59:43PM +0400, Dmitry Guryanov wrote: > Allow changing network interfaces in domain configuration. > > ifname is used as iterface identifier: if there is interface > with some ifname in old config and there are no interfaces with > such name in the new config - issue prlctl command to delete > the network interface. And vice versa - if interface with > some ifname exists only in new config - issue prlctl command > to create it. > > Signed-off-by: Dmitry Guryanov <dguryanov@xxxxxxxxxxxxx> > --- > src/parallels/parallels_driver.c | 169 +++++++++++++++++++++++++++++++++++++- > 1 files changed, 168 insertions(+), 1 deletions(-) > > diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c > index 755816e..f29b6ca 100644 > --- a/src/parallels/parallels_driver.c > +++ b/src/parallels/parallels_driver.c > @@ -1776,6 +1776,170 @@ parallelsApplyDisksParams(virConnectPtr conn, parallelsDomObjPtr pdom, > return 0; > } > > +static int parallelsApplyIfaceParams(parallelsDomObjPtr pdom, > + virDomainNetDefPtr oldnet, > + virDomainNetDefPtr newnet) > +{ > + bool create = false; > + bool is_changed = false; > + virCommandPtr cmd; > + char strmac[VIR_MAC_STRING_BUFLEN]; > + int i; > + > + if (!oldnet) { > + create = true; > + if (VIR_ALLOC(oldnet) < 0) { > + virReportOOMError(); > + return -1; > + } > + } > + > + if (!create && oldnet->type != newnet->type) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("Changing network type is not supported")); > + return -1; > + } > + > + if (!STREQ_NULLABLE(oldnet->model, newnet->model)) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("Changing network device model is not supported")); > + return -1; > + } > + > + if (!STREQ_NULLABLE(oldnet->data.network.portgroup, > + newnet->data.network.portgroup)) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("Changing network portgroup is not supported")); > + return -1; > + } > + > + if (!virNetDevVPortProfileEqual(oldnet->virtPortProfile, > + newnet->virtPortProfile)) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("Changing virtual port profile is not supported")); > + return -1; > + } > + > + if (newnet->tune.sndbuf_specified) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("Setting send buffer size is not supported")); > + return -1; > + } > + > + if (!STREQ_NULLABLE(oldnet->script, newnet->script)) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("Setting startup script is not supported")); > + return -1; > + } > + > + if (!STREQ_NULLABLE(oldnet->filter, newnet->filter)) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("Changing filter params is not supported")); > + return -1; > + } > + > + if (newnet->bandwidth != NULL) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("Setting bandwidth params is not supported")); > + return -1; > + } > + > + for (i = 0; i < sizeof(newnet->vlan); i++) { > + if (((char *)&newnet->vlan)[i] != 0) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("Setting vlan params is not supported")); > + return -1; > + } > + } > + > + /* Here we know, that there are no differences, that are forbidden. > + * Check is something changed, if no - do nothing */ > + > + if (create) { > + cmd = virCommandNewArgList(PRLCTL, "set", pdom->uuid, > + "--device-add", "net", NULL); > + } else { > + cmd = virCommandNewArgList(PRLCTL, "set", pdom->uuid, > + "--device-set", newnet->ifname, NULL); > + } > + > + if (virMacAddrCmp(&oldnet->mac, &newnet->mac)) { > + virMacAddrFormat(&newnet->mac, strmac); > + virCommandAddArgFormat(cmd, "--mac=%s", strmac); > + is_changed = true; > + } > + > + if (!STREQ_NULLABLE(oldnet->data.network.name, newnet->data.network.name)) { > + virCommandAddArgFormat(cmd, "--network=%s", newnet->data.network.name); > + is_changed = true; > + } > + > + if (oldnet->linkstate != newnet->linkstate) { > + if (newnet->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP) { > + virCommandAddArgFormat(cmd, "--connect"); > + } else if (newnet->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) { > + virCommandAddArgFormat(cmd, "--disconnect"); > + } > + is_changed = true; > + } > + > + if (!create && !is_changed) { > + /* nothing changed - no need to run prlctl */ > + return 0; > + } > + > + if (virCommandRun(cmd, NULL)) > + return -1; > + > + return 0; > +} > + > +static int > +parallelsApplyIfacesParams(parallelsDomObjPtr pdom, > + virDomainNetDefPtr *oldnets, int nold, > + virDomainNetDefPtr *newnets, int nnew) > +{ > + int i, j; > + > + for (i = 0; i < nold; i++) { > + virDomainNetDefPtr newnet = NULL; > + virDomainNetDefPtr oldnet = oldnets[i]; let's move those declarations out of the loop > + for (j = 0; j < nnew; j++) { > + if (STREQ_NULLABLE(newnets[j]->ifname, oldnet->ifname)) { > + newnet = newnets[j]; > + break; > + } > + } > + > + if (!newnet) { > + if (parallelsCmdRun(PRLCTL, "set", pdom->uuid, > + "--device-del", oldnet->ifname, NULL) < 0) > + return -1; > + > + continue; > + } > + > + if (parallelsApplyIfaceParams(pdom, oldnet, newnet) < 0) > + return -1; > + } > + > + for (i = 0; i < nnew; i++) { > + virDomainNetDefPtr newnet = newnets[i]; > + bool found = false; > + same > + for (j = 0; j < nold; j++) > + if (STREQ_NULLABLE(oldnets[j]->ifname, newnet->ifname)) > + found = true; > + if (found) > + continue; > + > + if (parallelsApplyIfaceParams(pdom, NULL, newnet)) > + return -1; > + } > + > + return 0; > +} > + > static int > parallelsApplyChanges(virConnectPtr conn, virDomainObjPtr dom, virDomainDefPtr new) > { > @@ -1975,7 +2139,7 @@ parallelsApplyChanges(virConnectPtr conn, virDomainObjPtr dom, virDomainDefPtr n > new->graphics, new->ngraphics) < 0) > return -1; > > - if (new->nfss != 0 || new->nnets != 0 || > + if (new->nfss != 0 || > new->nsounds != 0 || new->nhostdevs != 0 || > new->nredirdevs != 0 || new->nsmartcards != 0 || > new->nparallels || new->nchannels != 0 || > @@ -2013,6 +2177,9 @@ parallelsApplyChanges(virConnectPtr conn, virDomainObjPtr dom, virDomainDefPtr n > if (parallelsApplyDisksParams(conn, pdom, old->disks, old->ndisks, > new->disks, new->ndisks) < 0) > return -1; > + if (parallelsApplyIfacesParams(pdom, old->nets, old->nnets, > + new->nets, new->nnets) < 0) > + return -1; > > return 0; > } ACK with associated fixup: diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c index f16777a..60507e7 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -1924,10 +1924,13 @@ parallelsApplyIfacesParams(parallelsDomObjPtr pdom, virDomainNetDefPtr *newnets, int nnew) { int i, j; + virDomainNetDefPtr newnet; + virDomainNetDefPtr oldnet; + bool found; for (i = 0; i < nold; i++) { - virDomainNetDefPtr newnet = NULL; - virDomainNetDefPtr oldnet = oldnets[i]; + newnet = NULL; + oldnet = oldnets[i]; for (j = 0; j < nnew; j++) { if (STREQ_NULLABLE(newnets[j]->ifname, oldnet->ifname)) { newnet = newnets[j]; @@ -1948,8 +1951,8 @@ parallelsApplyIfacesParams(parallelsDomObjPtr pdom, } for (i = 0; i < nnew; i++) { - virDomainNetDefPtr newnet = newnets[i]; - bool found = false; + newnet = newnets[i]; + found = false; for (j = 0; j < nold; j++) if (STREQ_NULLABLE(oldnets[j]->ifname, newnet->ifname)) Daniel -- Daniel Veillard | Open Source and Standards, Red Hat veillard@xxxxxxxxxx | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list