[libvirt] [PATCH 14/14] Add support for network device detach

Daniel P. Berrange berrange at redhat.com
Mon Jul 20 16:34:25 UTC 2009


On Mon, Jul 20, 2009 at 12:51:24PM +0100, Mark McLoughlin wrote:
> qemu network devices are hot-unplugged in two stages - first the PCI NIC
> is removed using 'pci_del <pci_addr>' and then the backend is removed
> using 'host_net_remove <vlan> <name>'.
> 
> In order to perform these operations we need to have retained the
> PCI address, backend name and vlan number.
> 
> * src/qemu_driver.c: add qemudDomainDetachNetDevice()
> ---
>  src/qemu_driver.c |   95 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 93 insertions(+), 2 deletions(-)
> 
> diff --git a/src/qemu_driver.c b/src/qemu_driver.c
> index a3bb650..4fa946c 100644
> --- a/src/qemu_driver.c
> +++ b/src/qemu_driver.c
> @@ -4906,6 +4906,96 @@ cleanup:
>      return ret;
>  }
>  
> +static int
> +qemudDomainDetachNetDevice(virConnectPtr conn,
> +                           virDomainObjPtr vm,
> +                           virDomainDeviceDefPtr dev)
> +{
> +    int i, ret = -1;
> +    char *cmd = NULL;
> +    char *reply = NULL;
> +    virDomainNetDefPtr detach = NULL;
> +
> +    for (i = 0 ; i < vm->def->nnets ; i++) {
> +        virDomainNetDefPtr net = vm->def->nets[i];
> +
> +        if (!memcmp(net->mac, dev->data.net->mac,  sizeof(net->mac))) {
> +            detach = net;
> +            break;
> +        }
> +    }
> +
> +    if (!detach) {
> +        qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
> +                         _("network device %02x:%02x:%02x:%02x:%02x:%02x not found"),
> +                         detach->mac[0], detach->mac[1], detach->mac[2],
> +                         detach->mac[3], detach->mac[4], detach->mac[5]);
> +        goto cleanup;
> +    }
> +
> +    if (!detach->pci_addr || !detach->vlan || !detach->hostnet_name) {
> +        qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
> +                         "%s", _("network device cannot be detached - device state missing"));
> +        goto cleanup;
> +    }
> +
> +    if (virAsprintf(&cmd, "pci_del pci_addr=%s", detach->pci_addr) < 0) {
> +        virReportOOMError(conn);
> +        goto cleanup;
> +    }
> +
> +    if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
> +        qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
> +                          _("network device dettach command '%s' failed"), cmd);
> +        goto cleanup;
> +    }
> +
> +    DEBUG("%s: pci_del reply: %s", vm->def->name,  reply);
> +
> +    /* If the command fails due to a wrong PCI address qemu prints
> +     * 'invalid pci address'; nothing is printed on success */
> +    if (strstr(reply, "Invalid pci address")) {
> +        qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
> +                         _("failed to detach network device: invalid PCI address %s: %s"),
> +                         detach->pci_addr, reply);
> +        goto cleanup;
> +    }
> +
> +    VIR_FREE(reply);
> +    VIR_FREE(cmd);
> +
> +    if (virAsprintf(&cmd, "host_net_remove %d %s",
> +                    detach->vlan, detach->hostnet_name) < 0) {
> +        virReportOOMError(conn);
> +        goto cleanup;
> +    }
> +
> +    if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
> +        qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
> +                          _("network device dettach command '%s' failed"), cmd);
> +        goto cleanup;
> +    }
> +
> +    DEBUG("%s: host_net_remove reply: %s", vm->def->name,  reply);
> +
> +    if (vm->def->nnets > 1) {
> +        vm->def->nets[i] = vm->def->nets[--vm->def->nnets];
> +        if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets) < 0) {
> +            virReportOOMError(conn);
> +            goto cleanup;
> +        }
> +    } else {
> +        VIR_FREE(vm->def->nets[0]);
> +        vm->def->nnets = 0;
> +    }
> +    ret = 0;
> +
> +cleanup:
> +    VIR_FREE(reply);
> +    VIR_FREE(cmd);
> +    return ret;
> +}
> +
>  static int qemudDomainDetachDevice(virDomainPtr dom,
>                                     const char *xml) {
>      struct qemud_driver *driver = dom->conn->privateData;
> @@ -4944,8 +5034,9 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
>              driver->securityDriver->domainRestoreSecurityImageLabel(dom->conn, dev->data.disk);
>          if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 1) < 0)
>              VIR_WARN0("Fail to restore disk device ownership");
> -    }
> -    else
> +    } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
> +        ret = qemudDomainDetachNetDevice(dom->conn, vm, dev);
> +    } else
>          qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
>                           "%s", _("only SCSI or virtio disk device can be detached dynamically"));
>  
> -- 


ACK

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list