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 <dgurya...@parallels.com>
> ---
>  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
veill...@redhat.com  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | virtualization library  http://libvirt.org/

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to