[libvirt] [PATCHv4 2/4] qemu: Move interface cmd line construction into a separate function

Laine Stump laine at laine.org
Tue May 21 15:43:52 UTC 2013


On 05/21/2013 10:18 AM, Michal Privoznik wrote:
> Currently, we have one huge function to construct qemu command line.
> This is very ineffective esp. if there's a fault somewhere.
> ---
>  src/qemu/qemu_command.c | 224 +++++++++++++++++++++++++-----------------------
>  1 file changed, 117 insertions(+), 107 deletions(-)
>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 33a1910..6f4028e 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -6406,6 +6406,117 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
>      return 0;
>  }
>  
> +static int
> +qemuBuildInterfaceCommandLine(virCommandPtr cmd,
> +                              virQEMUDriverPtr driver,
> +                              virConnectPtr conn,
> +                              virDomainDefPtr def,
> +                              virDomainNetDefPtr net,
> +                              virQEMUCapsPtr qemuCaps,
> +                              int vlan,
> +                              int bootindex,
> +                              enum virNetDevVPortProfileOp vmop)
> +{
> +    int ret = -1;
> +    int tapfd = -1;
> +    int vhostfd = -1;
> +    char *nic = NULL, *host = NULL;
> +    char *tapfdName = NULL;
> +    char *vhostfdName = NULL;
> +    int actualType = virDomainNetGetActualType(net);
> +
> +    if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
> +        /* NET_TYPE_HOSTDEV devices are really hostdev devices, so
> +         * their commandlines are constructed with other hostdevs.
> +         */
> +        return 0;
> +    }
> +
> +    if (!bootindex)
> +        bootindex = net->info.bootIndex;
> +
> +    if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
> +        actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
> +        tapfd = qemuNetworkIfaceConnect(def, conn, driver, net, qemuCaps);
> +        if (tapfd < 0)
> +            goto cleanup;
> +    } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
> +        tapfd = qemuPhysIfaceConnect(def, driver, net, qemuCaps, vmop);
> +        if (tapfd < 0)
> +            goto cleanup;
> +    }
> +
> +    if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
> +        actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
> +        actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
> +        actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
> +        /* Attempt to use vhost-net mode for these types of
> +           network device */
> +        if (qemuOpenVhostNet(def, net, qemuCaps, &vhostfd) < 0)
> +            goto cleanup;
> +    }
> +
> +    if (tapfd >= 0) {
> +        virCommandTransferFD(cmd, tapfd);
> +        if (virAsprintf(&tapfdName, "%d", tapfd) < 0) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +    }
> +
> +    if (vhostfd >= 0) {
> +        virCommandTransferFD(cmd, vhostfd);
> +        if (virAsprintf(&vhostfdName, "%d", vhostfd) < 0) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +    }
> +
> +    /* Possible combinations:
> +     *
> +     *  1. Old way:   -net nic,model=e1000,vlan=1 -net tap,vlan=1
> +     *  2. Semi-new:  -device e1000,vlan=1        -net tap,vlan=1
> +     *  3. Best way:  -netdev type=tap,id=netdev1 -device e1000,id=netdev1
> +     *
> +     * NB, no support for -netdev without use of -device
> +     */
> +    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
> +        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
> +        if (!(host = qemuBuildHostNetStr(net, driver,
> +                                         ',', vlan, tapfdName,
> +                                         vhostfdName)))
> +            goto cleanup;
> +        virCommandAddArgList(cmd, "-netdev", host, NULL);
> +    }
> +    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
> +        if (!(nic = qemuBuildNicDevStr(net, vlan, bootindex, qemuCaps)))
> +            goto cleanup;
> +        virCommandAddArgList(cmd, "-device", nic, NULL);
> +    } else {
> +        if (!(nic = qemuBuildNicStr(net, "nic,", vlan)))
> +            goto cleanup;
> +        virCommandAddArgList(cmd, "-net", nic, NULL);
> +    }
> +    if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
> +          virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
> +        if (!(host = qemuBuildHostNetStr(net, driver,
> +                                         ',', vlan, tapfdName,
> +                                         vhostfdName)))
> +            goto cleanup;
> +        virCommandAddArgList(cmd, "-net", host, NULL);
> +    }
> +
> +    ret = 0;
> +cleanup:
> +    if (ret < 0)
> +        virDomainConfNWFilterTeardown(net);
> +    VIR_FREE(nic);
> +    VIR_FREE(host);
> +    VIR_FREE(tapfdName);
> +    VIR_FREE(vhostfdName);
> +    return ret;
> +}
> +
>  qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
>      .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName,
>  };
> @@ -7344,118 +7455,17 @@ qemuBuildCommandLine(virConnectPtr conn,
>  
>          for (i = 0 ; i < def->nnets ; i++) {
>              virDomainNetDefPtr net = def->nets[i];
> -            char *nic, *host;
> -            char tapfd_name[50] = "";
> -            char vhostfd_name[50] = "";
> -            int vlan;
> -            int bootindex = bootNet;
> -            int actualType = virDomainNetGetActualType(net);
> -
> -            if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
> -                /* NET_TYPE_HOSTDEV devices are really hostdev devices, so
> -                 * their commandlines are constructed with other hostdevs.
> -                 */
> -                continue;
> -            }
> -
> -            bootNet = 0;
> -            if (!bootindex)
> -                bootindex = net->info.bootIndex;
> -
> +            int vlan = i;
>              /* VLANs are not used with -netdev, so don't record them */
>              if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
>                  virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
>                  vlan = -1;


A blank line after "int vlan = i;" would be nice.


> -            else
> -                vlan = i;
>  
> -            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;
> -            } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
> -                int tapfd = qemuPhysIfaceConnect(def, driver, net,
> -                                                 qemuCaps, vmop);
> -                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 (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
> -                actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
> -                actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
> -                actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
> -                /* Attempt to use vhost-net mode for these types of
> -                   network device */
> -                int vhostfd;
> -
> -                if (qemuOpenVhostNet(def, net, qemuCaps, &vhostfd) < 0)
> -                    goto error;
> -                if (vhostfd >= 0) {
> -                    virCommandTransferFD(cmd, vhostfd);
> -
> -                    if (snprintf(vhostfd_name, sizeof(vhostfd_name), "%d",
> -                                 vhostfd) >= sizeof(vhostfd_name))
> -                        goto no_memory;
> -                }
> -            }
> -            /* Possible combinations:
> -             *
> -             *  1. Old way:   -net nic,model=e1000,vlan=1 -net tap,vlan=1
> -             *  2. Semi-new:  -device e1000,vlan=1        -net tap,vlan=1
> -             *  3. Best way:  -netdev type=tap,id=netdev1 -device e1000,id=netdev1
> -             *
> -             * NB, no support for -netdev without use of -device
> -             */
> -            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
> -                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
> -                virCommandAddArg(cmd, "-netdev");
> -                if (!(host = qemuBuildHostNetStr(net, driver,
> -                                                 ',', vlan, tapfd_name,
> -                                                 vhostfd_name)))
> -                    goto error;
> -                virCommandAddArg(cmd, host);
> -                VIR_FREE(host);
> -            }
> -            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
> -                virCommandAddArg(cmd, "-device");
> -                nic = qemuBuildNicDevStr(net, vlan, bootindex, qemuCaps);
> -                if (!nic)
> -                    goto error;
> -                virCommandAddArg(cmd, nic);
> -                VIR_FREE(nic);
> -            } else {
> -                virCommandAddArg(cmd, "-net");
> -                if (!(nic = qemuBuildNicStr(net, "nic,", vlan)))
> -                    goto error;
> -                virCommandAddArg(cmd, nic);
> -                VIR_FREE(nic);
> -            }
> -            if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
> -                  virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
> -                virCommandAddArg(cmd, "-net");
> -                if (!(host = qemuBuildHostNetStr(net, driver,
> -                                                 ',', vlan, tapfd_name,
> -                                                 vhostfd_name)))
> -                    goto error;
> -                virCommandAddArg(cmd, host);
> -                VIR_FREE(host);
> -            }
> +            if (qemuBuildInterfaceCommandLine(cmd, driver, conn, def, net,
> +                                              qemuCaps, vlan, bootNet, vmop) < 0)
> +                goto error;
> +            last_good_net = i;
> +            bootNet = 0;
>          }
>      }
>  

ACK, but please add the blank line I mentioned above.





More information about the libvir-list mailing list