提交 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,
virDomainObjPtr vm, virDomainDeviceDefPtr dev)
{
int i, ret = -1;
char *cmd = NULL;
char *reply = NULL;
virDomainDiskDefPtr detach = NULL;
int tryOldSyntax = 0;
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
......@@ -5163,48 +5160,11 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
goto cleanup;
}
try_command:
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.bus,
detach->pci_addr.slot) < 0) {
virReportOOMError(conn);
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);
if (qemuMonitorRemovePCIDevice(vm,
detach->pci_addr.domain,
detach->pci_addr.bus,
detach->pci_addr.slot) < 0)
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) {
memmove(vm->def->disks + i,
......@@ -5224,8 +5184,6 @@ try_command:
ret = 0;
cleanup:
VIR_FREE(reply);
VIR_FREE(cmd);
return ret;
}
......@@ -5263,36 +5221,11 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
goto cleanup;
}
if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x",
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.bus,
detach->pci_addr.slot,
reply);
if (qemuMonitorRemovePCIDevice(vm,
detach->pci_addr.domain,
detach->pci_addr.bus,
detach->pci_addr.slot) < 0)
goto cleanup;
}
VIR_FREE(reply);
VIR_FREE(cmd);
if (virAsprintf(&cmd, "host_net_remove %d %s",
detach->vlan, detach->hostnet_name) < 0) {
......@@ -5337,7 +5270,6 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
virDomainDeviceDefPtr dev)
{
virDomainHostdevDefPtr detach = NULL;
char *cmd, *reply;
int i, ret;
pciDevice *pci;
......@@ -5372,39 +5304,11 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
return -1;
}
if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x",
detach->source.subsys.u.pci.guest_addr.domain,
detach->source.subsys.u.pci.guest_addr.bus,
detach->source.subsys.u.pci.guest_addr.slot) < 0) {
virReportOOMError(conn);
if (qemuMonitorRemovePCIDevice(vm,
detach->source.subsys.u.pci.guest_addr.domain,
detach->source.subsys.u.pci.guest_addr.bus,
detach->source.subsys.u.pci.guest_addr.slot) < 0)
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;
......
......@@ -1436,3 +1436,63 @@ cleanup:
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,
unsigned *guestBus,
unsigned *guestSlot);
int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm,
unsigned guestDomain,
unsigned guestBus,
unsigned guestSlot);
#endif /* QEMU_MONITOR_TEXT_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册