diff --git a/AUTHORS b/AUTHORS index 10124ee5cf8dc550957d939b12101ccb6f5ee637..877fb03ac716dbd0595aadf6a3750ac1dd036f51 100644 --- a/AUTHORS +++ b/AUTHORS @@ -168,6 +168,7 @@ Patches have also been contributed by: Alexander Todorov Richard Laager Mark Wu + Yufang Zhang [....send patches to get your name here....] diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 2a07b7bd049f9bfcd5bd53ef9cf96d1e05bc2cc2..dd94fbc12cd6769b021fe6124465bed372b91dc3 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1926,12 +1926,71 @@ out: return ret; } +static int +xenUnifiedNodeDeviceAssignedDomainId (virNodeDevicePtr dev) +{ + int numdomains; + int ret = -1, i; + int *ids = NULL; + char *bdf = NULL; + char *xref = NULL; + unsigned int 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; + } + + xenUnifiedLock(priv); + /* Check if bdf is assigned to one of active domains */ + for (i = 0; i < numdomains; i++ ) { + xref = xenStoreDomainGetPCIID(conn, ids[i], bdf); + if (xref == NULL) { + continue; + } else { + ret = ids[i]; + break; + } + } + xenUnifiedUnlock(priv); + + 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 domid; if (xenUnifiedNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0) return -1; @@ -1940,6 +1999,14 @@ xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev) if (!pci) return -1; + /* Check if device is assigned to an active guest */ + if ((domid = xenUnifiedNodeDeviceAssignedDomainId(dev)) >= 0) { + xenUnifiedError(VIR_ERR_INTERNAL_ERROR, + _("Device %s has been assigned to guest %d"), + dev->name, domid); + goto out; + } + if (pciReAttachDevice(pci, NULL) < 0) goto out;