[libvirt] [PATCH 19/27] Add API for issuing 'pci_del' monitor command

Daniel P. Berrange berrange at redhat.com
Thu Sep 24 15:00:21 UTC 2009


* 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




More information about the libvir-list mailing list