* 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 e9e7543..10fc09a 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);
- 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;
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index ca84fc6..290dcce 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 0e1b27b..342e71e 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 */
--
1.6.2.5