提交 a8891666 编写于 作者: Y Yufang Zhang 提交者: Eric Blake

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: NYufang Zhang <yuzhang@redhat.com>
上级 f7bd72fa
...@@ -168,6 +168,7 @@ Patches have also been contributed by: ...@@ -168,6 +168,7 @@ Patches have also been contributed by:
Alexander Todorov <atodorov@otb.bg> Alexander Todorov <atodorov@otb.bg>
Richard Laager <rlaager@wiktel.com> Richard Laager <rlaager@wiktel.com>
Mark Wu <dwu@redhat.com> Mark Wu <dwu@redhat.com>
Yufang Zhang <yuzhang@redhat.com>
[....send patches to get your name here....] [....send patches to get your name here....]
......
...@@ -1926,12 +1926,71 @@ out: ...@@ -1926,12 +1926,71 @@ out:
return ret; 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 static int
xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev) xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev)
{ {
pciDevice *pci; pciDevice *pci;
unsigned domain, bus, slot, function; unsigned domain, bus, slot, function;
int ret = -1; int ret = -1;
int domid;
if (xenUnifiedNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0) if (xenUnifiedNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
return -1; return -1;
...@@ -1940,6 +1999,14 @@ xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev) ...@@ -1940,6 +1999,14 @@ xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev)
if (!pci) if (!pci)
return -1; 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) if (pciReAttachDevice(pci, NULL) < 0)
goto out; goto out;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册