From 3e11f9ff90ed5203516e0074e07ce7676e6c1440 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 23 Sep 2009 16:25:05 +0100 Subject: [PATCH] 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 --- src/qemu/qemu_driver.c | 120 ++++------------------------------- src/qemu/qemu_monitor_text.c | 60 ++++++++++++++++++ src/qemu/qemu_monitor_text.h | 6 ++ 3 files changed, 78 insertions(+), 108 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 713dfa09d5..5f17bfb819 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -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); + if (qemuMonitorRemovePCIDevice(vm, + detach->pci_addr.domain, + detach->pci_addr.bus, + detach->pci_addr.slot) < 0) 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); - 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; diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 783b564ee1..030faf84ea 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -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; +} diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 1d6b093758..41f57b08e0 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -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 */