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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

Signed-off-by: Yufang Zhang <yuzhang@xxxxxxxxxx>
---
 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;
+    virConnectPtr conn = dev->conn;
+    xenUnifiedPrivatePtr priv = conn->privateData;
+
+    /* Get active domains */
+    numdomains = xenUnifiedNumOfDomains(conn);
+    if (numdomains < 0) {
+        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);
+}
+
+static int
 xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev)
 {
     pciDevice *pci;
     unsigned domain, bus, slot, function;
     int ret = -1;
+    int dom;
 
     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;
 
-- 
1.7.3.4

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


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]