提交 3e11f9ff 编写于 作者: D Daniel P. Berrange

Add API for issuing 'pci_del' monitor command

* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new API
  qemuMonitorRemovePCIDevice() for removing PCI device
* src/qemu/qemu_driver.c: Convert all places removing PCI devices
  over to new qemuMonitorRemovePCIDevice() API
上级 e7f38d96
...@@ -5138,10 +5138,7 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn, ...@@ -5138,10 +5138,7 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
virDomainObjPtr vm, virDomainDeviceDefPtr dev) virDomainObjPtr vm, virDomainDeviceDefPtr dev)
{ {
int i, ret = -1; int i, ret = -1;
char *cmd = NULL;
char *reply = NULL;
virDomainDiskDefPtr detach = NULL; virDomainDiskDefPtr detach = NULL;
int tryOldSyntax = 0;
for (i = 0 ; i < vm->def->ndisks ; i++) { for (i = 0 ; i < vm->def->ndisks ; i++) {
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) { if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
...@@ -5163,48 +5160,11 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn, ...@@ -5163,48 +5160,11 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
try_command: if (qemuMonitorRemovePCIDevice(vm,
if (tryOldSyntax) {
if (virAsprintf(&cmd, "pci_del 0 %.2x", detach->pci_addr.slot) < 0) {
virReportOOMError(conn);
goto cleanup;
}
} else {
if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x",
detach->pci_addr.domain, detach->pci_addr.domain,
detach->pci_addr.bus, detach->pci_addr.bus,
detach->pci_addr.slot) < 0) { detach->pci_addr.slot) < 0)
virReportOOMError(conn);
goto cleanup; goto cleanup;
}
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to execute detach disk %s command"), detach->dst);
goto cleanup;
}
DEBUG ("%s: pci_del reply: %s",vm->def->name, reply);
if (!tryOldSyntax &&
strstr(reply, "extraneous characters")) {
tryOldSyntax = 1;
goto try_command;
}
/* If the command fails due to a wrong slot qemu prints: invalid slot,
* nothing is printed on success */
if (strstr(reply, "invalid slot") ||
strstr(reply, "Invalid pci address")) {
qemudReportError (conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to detach disk %s: invalid PCI address %.4x:%.2x:%.2x: %s"),
detach->dst,
detach->pci_addr.domain,
detach->pci_addr.bus,
detach->pci_addr.slot,
reply);
goto cleanup;
}
if (vm->def->ndisks > 1) { if (vm->def->ndisks > 1) {
memmove(vm->def->disks + i, memmove(vm->def->disks + i,
...@@ -5224,8 +5184,6 @@ try_command: ...@@ -5224,8 +5184,6 @@ try_command:
ret = 0; ret = 0;
cleanup: cleanup:
VIR_FREE(reply);
VIR_FREE(cmd);
return ret; return ret;
} }
...@@ -5263,36 +5221,11 @@ qemudDomainDetachNetDevice(virConnectPtr conn, ...@@ -5263,36 +5221,11 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x", if (qemuMonitorRemovePCIDevice(vm,
detach->pci_addr.domain,
detach->pci_addr.bus,
detach->pci_addr.slot) < 0) {
virReportOOMError(conn);
goto cleanup;
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("network device dettach command '%s' failed"), cmd);
goto cleanup;
}
DEBUG("%s: pci_del reply: %s", vm->def->name, reply);
/* If the command fails due to a wrong PCI address qemu prints
* 'invalid pci address'; nothing is printed on success */
if (strstr(reply, "Invalid pci address")) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to detach network device: invalid PCI address %.4x:%.2x:%.2x: %s"),
detach->pci_addr.domain, detach->pci_addr.domain,
detach->pci_addr.bus, detach->pci_addr.bus,
detach->pci_addr.slot, detach->pci_addr.slot) < 0)
reply);
goto cleanup; goto cleanup;
}
VIR_FREE(reply);
VIR_FREE(cmd);
if (virAsprintf(&cmd, "host_net_remove %d %s", if (virAsprintf(&cmd, "host_net_remove %d %s",
detach->vlan, detach->hostnet_name) < 0) { detach->vlan, detach->hostnet_name) < 0) {
...@@ -5337,7 +5270,6 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn, ...@@ -5337,7 +5270,6 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
virDomainDeviceDefPtr dev) virDomainDeviceDefPtr dev)
{ {
virDomainHostdevDefPtr detach = NULL; virDomainHostdevDefPtr detach = NULL;
char *cmd, *reply;
int i, ret; int i, ret;
pciDevice *pci; pciDevice *pci;
...@@ -5372,39 +5304,11 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn, ...@@ -5372,39 +5304,11 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
return -1; return -1;
} }
if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x", if (qemuMonitorRemovePCIDevice(vm,
detach->source.subsys.u.pci.guest_addr.domain, detach->source.subsys.u.pci.guest_addr.domain,
detach->source.subsys.u.pci.guest_addr.bus, detach->source.subsys.u.pci.guest_addr.bus,
detach->source.subsys.u.pci.guest_addr.slot) < 0) { detach->source.subsys.u.pci.guest_addr.slot) < 0)
virReportOOMError(conn);
return -1; return -1;
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("cannot detach host pci device"));
VIR_FREE(cmd);
return -1;
}
DEBUG("%s: pci_del reply: %s", vm->def->name, reply);
/* If the command fails due to a wrong PCI address qemu prints
* 'invalid pci address'; nothing is printed on success */
if (strstr(reply, "Invalid pci address")) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to detach host pci device: invalid PCI address %.4x:%.2x:%.2x: %s"),
detach->source.subsys.u.pci.guest_addr.domain,
detach->source.subsys.u.pci.guest_addr.bus,
detach->source.subsys.u.pci.guest_addr.slot,
reply);
VIR_FREE(reply);
VIR_FREE(cmd);
return -1;
}
VIR_FREE(reply);
VIR_FREE(cmd);
ret = 0; ret = 0;
......
...@@ -1436,3 +1436,63 @@ cleanup: ...@@ -1436,3 +1436,63 @@ cleanup:
return ret; return ret;
} }
int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm,
unsigned guestDomain,
unsigned guestBus,
unsigned guestSlot)
{
char *cmd = NULL;
char *reply = NULL;
int tryOldSyntax = 0;
int ret = -1;
try_command:
if (tryOldSyntax) {
if (virAsprintf(&cmd, "pci_del 0 %.2x", guestSlot) < 0) {
virReportOOMError(NULL);
goto cleanup;
}
} else {
if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x",
guestDomain, guestBus, guestSlot) < 0) {
virReportOOMError(NULL);
goto cleanup;
}
}
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
"%s", _("failed to remove PCI device"));
goto cleanup;
}
DEBUG ("%s: pci_del reply: %s",vm->def->name, reply);
/* Syntax changed when KVM merged PCI hotplug upstream to QEMU,
* so check for an error message from old KVM indicating the
* need to try the old syntax */
if (!tryOldSyntax &&
strstr(reply, "extraneous characters")) {
tryOldSyntax = 1;
VIR_FREE(reply);
VIR_FREE(cmd);
goto try_command;
}
/* If the command fails due to a wrong slot qemu prints: invalid slot,
* nothing is printed on success */
if (strstr(reply, "invalid slot") ||
strstr(reply, "Invalid pci address")) {
qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to detach PCI device, invalid address %.4x:%.2x:%.2x: %s"),
guestDomain, guestBus, guestSlot, reply);
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(cmd);
VIR_FREE(reply);
return ret;
}
...@@ -157,5 +157,11 @@ int qemuMonitorAddPCIHostDevice(const virDomainObjPtr vm, ...@@ -157,5 +157,11 @@ int qemuMonitorAddPCIHostDevice(const virDomainObjPtr vm,
unsigned *guestBus, unsigned *guestBus,
unsigned *guestSlot); unsigned *guestSlot);
int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm,
unsigned guestDomain,
unsigned guestBus,
unsigned guestSlot);
#endif /* QEMU_MONITOR_TEXT_H */ #endif /* QEMU_MONITOR_TEXT_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册