[libvirt] [Patch v2 2/3] Add -netdev bridge support

Michal Privoznik mprivozn at redhat.com
Wed Jul 4 15:37:49 UTC 2012


On 29.06.2012 20:08, rmarwah at linux.vnet.ibm.com wrote:
> From: Richa Marwaha <rmarwah at linux.vnet.ibm.com>
> 
> This patch adds the support to run the QEMU network helper
> under unprivileged user. It also adds the support for
> attach-interface option in virsh to run under unprivileged
> user.
> 
> Signed-off-by: Richa Marwaha <rmarwah at linux.vnet.ibm.com>
> Signed-off-by: Corey Bryant<coreyb at linux.vnet.ibm.com>
> ---
> v2
> - This patch attach-interface option is tested on
> commit cd15303fd123146b0ba53e387d08ef22b707223
> 
>  src/qemu/qemu_command.c |   61 +++++++++++++++++++++++++++++++++-------------
>  src/qemu/qemu_command.h |    2 +
>  src/qemu/qemu_hotplug.c |   31 ++++++++++++++++-------
>  3 files changed, 67 insertions(+), 27 deletions(-)
> 
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 6549f57..4eb8cd5 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -2851,6 +2851,8 @@ error:
>  
>  char *
>  qemuBuildHostNetStr(virDomainNetDefPtr net,
> +                    struct qemud_driver *driver,
> +                    virBitmapPtr qemuCaps,
>                      char type_sep,
>                      int vlan,
>                      const char *tapfd,
> @@ -2859,6 +2861,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
>      bool is_tap = false;
>      virBuffer buf = VIR_BUFFER_INITIALIZER;
>      enum virDomainNetType netType = virDomainNetGetActualType(net);
> +    const char *brname = NULL;
>  
>      if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
>          qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> @@ -2868,8 +2871,21 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
>      }
>  
>      switch (netType) {
> -    case VIR_DOMAIN_NET_TYPE_NETWORK:
> +    /*
> +     * If type='bridge', and we're running as privileged user
> +     * or -netdev bridge is not supported then it will fall
> +     * through, -net tap,fd
> +     */
>      case VIR_DOMAIN_NET_TYPE_BRIDGE:
> +        if (!driver->privileged &&
> +            qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE)) {
> +            brname = virDomainNetGetActualBridgeName(net);
> +            virBufferAsprintf(&buf, "bridge%cbr=%s", type_sep, brname);
> +            type_sep = ',';
> +            is_tap = true;
> +            break;
> +        }
> +    case VIR_DOMAIN_NET_TYPE_NETWORK:
>      case VIR_DOMAIN_NET_TYPE_DIRECT:
>          virBufferAsprintf(&buf, "tap%cfd=%s", type_sep, tapfd);
>          type_sep = ',';
> @@ -4997,7 +5013,7 @@ qemuBuildCommandLine(virConnectPtr conn,
>          for (i = 0 ; i < def->nnets ; i++) {
>              virDomainNetDefPtr net = def->nets[i];
>              char *nic, *host;
> -            char tapfd_name[50];
> +            char tapfd_name[50] = "";
>              char vhostfd_name[50] = "";
>              int vlan;
>              int bootindex = bootNet;
> @@ -5034,17 +5050,26 @@ qemuBuildCommandLine(virConnectPtr conn,
>  
>              if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
>                  actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
> -                int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net,
> -                                                    qemuCaps);
> -                if (tapfd < 0)
> -                    goto error;
> -
> -                last_good_net = i;
> -                virCommandTransferFD(cmd, tapfd);
> -
> -                if (snprintf(tapfd_name, sizeof(tapfd_name), "%d",
> -                             tapfd) >= sizeof(tapfd_name))
> -                    goto no_memory;
> +                /*
> +                 * If type='bridge' then we attempt to allocate the tap fd here only if
> +                 * running under a privilged user or -netdev bridge option is not
> +                 * supported.
> +                 */
> +                 if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
> +                     driver->privileged ||
> +                     (!qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) {
> +                     int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net,
> +                                                         qemuCaps);
> +                     if (tapfd < 0)
> +                         goto error;
> +
> +                     last_good_net = i;
> +                     virCommandTransferFD(cmd, tapfd);
> +
> +                      if (snprintf(tapfd_name, sizeof(tapfd_name), "%d",
> +                                   tapfd) >= sizeof(tapfd_name))
> +                          goto no_memory;
> +                 }
>              } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
>                  int tapfd = qemuPhysIfaceConnect(def, driver, net,
>                                                   qemuCaps, vmop);
> @@ -5087,8 +5112,9 @@ qemuBuildCommandLine(virConnectPtr conn,
>              if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
>                  qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
>                  virCommandAddArg(cmd, "-netdev");
> -                if (!(host = qemuBuildHostNetStr(net, ',', vlan,
> -                                                 tapfd_name, vhostfd_name)))
> +                if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
> +                                                 ',', vlan, tapfd_name,
> +                                                 vhostfd_name)))
>                      goto error;
>                  virCommandAddArg(cmd, host);
>                  VIR_FREE(host);
> @@ -5110,8 +5136,9 @@ qemuBuildCommandLine(virConnectPtr conn,
>              if (!(qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
>                    qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
>                  virCommandAddArg(cmd, "-net");
> -                if (!(host = qemuBuildHostNetStr(net, ',', vlan,
> -                                                 tapfd_name, vhostfd_name)))
> +                if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
> +                                                 ',', vlan, tapfd_name,
> +                                                 vhostfd_name)))
>                      goto error;
>                  virCommandAddArg(cmd, host);
>                  VIR_FREE(host);
> diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
> index 1eafeb3..ebf7ad0 100644
> --- a/src/qemu/qemu_command.h
> +++ b/src/qemu/qemu_command.h
> @@ -62,6 +62,8 @@ qemuBuildChrDeviceStr (virDomainChrDefPtr serial,
>  
>  /* With vlan == -1, use netdev syntax, else old hostnet */
>  char * qemuBuildHostNetStr(virDomainNetDefPtr net,
> +                           struct qemud_driver *driver,
> +                           virBitmapPtr qemuCaps,
>                             char type_sep,
>                             int vlan,
>                             const char *tapfd,
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index c2fa75b..deca4cb 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -699,12 +699,21 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
>  
>      if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
>          actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
> -        if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net,
> -                                             priv->qemuCaps)) < 0)
> -            goto cleanup;
> -        iface_connected = true;
> -        if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0)
> -            goto cleanup;
> +        /*
> +         * If type=bridge then we attempt to allocate the tap fd here only if
> +         * running under a privilged user or -netdev bridge option is not
> +         * supported.
> +         */
> +        if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
> +            driver->privileged ||
> +            (!qemuCapsGet (priv->qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) {
> +            if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net,
> +                                                 priv->qemuCaps)) < 0)
> +                goto cleanup;
> +            iface_connected = true;
> +            if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0)
> +                goto cleanup;
> +        }
>      } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
>          if ((tapfd = qemuPhysIfaceConnect(vm->def, driver, net,
>                                            priv->qemuCaps,
> @@ -752,12 +761,14 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
>  
>      if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
>          qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
> -        if (!(netstr = qemuBuildHostNetStr(net, ',',
> -                                           -1, tapfd_name, vhostfd_name)))
> +        if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps,
> +                                           ',', -1, tapfd_name,
> +                                           vhostfd_name)))
>              goto cleanup;
>      } else {
> -        if (!(netstr = qemuBuildHostNetStr(net, ' ',
> -                                           vlan, tapfd_name, vhostfd_name)))
> +        if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps,
> +                                           ' ', vlan, tapfd_name,
> +                                           vhostfd_name)))
>              goto cleanup;
>      }
>  
> 

ACK

I am not going to review next apparmor patch which has already been
reviewed.

Michal




More information about the libvir-list mailing list