[libvirt] [PATCH] Device reattach: Check if device is assigned to guest before reattaching

Osier Yang jyang at redhat.com
Thu Jan 6 16:09:49 UTC 2011


于 2011年01月05日 21:54, Yufang Zhang 写道:
> Reattaching pci device back to host without destroying guest or detaching
> device from guest would cause host to crash. This patch adds a check before
> doing device reattach. If the device is being assigned to guest, libvirt
> refuses to reattach device to host. Note that the patch only works for Xen,
> for it just checks xenstore to get pci device information.

So the subject of the patch could be:
xen: Check if device is assigned to guest before reattaching

>
> Signed-off-by: Yufang Zhang<yuzhang at redhat.com>
> ---
>   src/xen/xen_driver.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 files changed, 67 insertions(+), 0 deletions(-)
>
> diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
> index 4c11b11..5773d3b 100644
> --- a/src/xen/xen_driver.c
> +++ b/src/xen/xen_driver.c
> @@ -1891,11 +1891,70 @@ out:
>   }
>
>   static int
> +xenUnifiedNodeDeviceIsAssigned (virNodeDevicePtr dev)
> +{
> +    int numdomains;
> +    int ret = -1, i;
> +    int *ids = NULL;
> +    char *bdf = NULL;
> +    char *xref = NULL;
> +    unsigned domain, bus, slot, function;

unsigned int

> +    virConnectPtr conn = dev->conn;
> +    xenUnifiedPrivatePtr priv = conn->privateData;
> +
> +    /* Get active domains */
> +    numdomains = xenUnifiedNumOfDomains(conn);
> +    if (numdomains<  0) {
> +        return(ret);

Generally we use "return ret;"

> +    }
> +    if (numdomains>  0){
> +        if (VIR_ALLOC_N(ids, numdomains)<  0){
> +            virReportOOMError();
> +            goto out;
> +        }
> +        if ((numdomains = xenUnifiedListDomains(conn,&ids[0], numdomains))<  0){
> +            goto out;
> +        }
> +    }
> +
> +    /* Get pci bdf */
> +    if (xenUnifiedNodeDeviceGetPciInfo(dev,&domain,&bus,&slot,&function)<  0)
> +        goto out;
> +
> +    if (virAsprintf(&bdf, "%04x:%02x:%02x.%0x",
> +                    domain, bus, slot, function)<  0) {
> +        virReportOOMError();
> +        goto out;
> +    }
> +
> +    /* Check if bdf is assigned to one of active domains */
> +    for (i = 0; i<  numdomains; i++ ){
> +        xenUnifiedLock(priv);
> +        xref = xenStoreDomainGetPCIID(conn, ids[i], bdf);
> +        xenUnifiedUnlock(priv);
> +        if (xref == NULL)
> +            continue;
> +        else {
> +            ret = ids[i];
> +            break;
> +        }
> +    }
> +
> +    VIR_FREE(xref);
> +    VIR_FREE(bdf);
> +out:
> +    VIR_FREE(ids);
> +
> +    return(ret);
> +}

Generally, a function "*Is*" will return a bool value, TRUE/FALSE,
altough seems you want to get the domain ID to use in following
function to print. But does it make sense to find a better method?
or a better function name?

> +
> +static int
>   xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev)
>   {
>       pciDevice *pci;
>       unsigned domain, bus, slot, function;
>       int ret = -1;
> +    int dom;

 From the code, it should be "domain id" here. so probly you need
a better variable name here.

>
>       if (xenUnifiedNodeDeviceGetPciInfo(dev,&domain,&bus,&slot,&function)<  0)
>           return -1;
> @@ -1904,6 +1963,14 @@ xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev)
>       if (!pci)
>           return -1;
>
> +    /* Check if device is assigned to an active guest */
> +    if ((dom = xenUnifiedNodeDeviceIsAssigned(dev))>= 0){
> +        xenUnifiedError(VIR_ERR_INTERNAL_ERROR,
> +                        _("Device %s has been assigned to guest %d"),
> +                        dev->name, dom);
> +        goto out;
> +    }
> +
>       if (pciReAttachDevice(pci, NULL)<  0)
>           goto out;
>

Anyway, I like the idea, we have bug (host will crash or reboot if
try to reattach a PCI device to host which is using by guest) of
qemu driver. Though we can't resolve the problem in the similar way,
as kvm doesn't record the PCI/domain pair like xenstore. It still
gives some inspiration.

Thanks
Osier




More information about the libvir-list mailing list