mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
xen: check if device is assigned to guest before reattaching
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=664059 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. The patch only works for Xen, for it just checks xenstore to get pci device information. Signed-off-by: Yufang Zhang <yuzhang@redhat.com>
This commit is contained in:
parent
f7bd72fa26
commit
a88916665d
1
AUTHORS
1
AUTHORS
@ -168,6 +168,7 @@ Patches have also been contributed by:
|
||||
Alexander Todorov <atodorov@otb.bg>
|
||||
Richard Laager <rlaager@wiktel.com>
|
||||
Mark Wu <dwu@redhat.com>
|
||||
Yufang Zhang <yuzhang@redhat.com>
|
||||
|
||||
[....send patches to get your name here....]
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user