[libvirt] [PATCH 12/14] Re-factor pci_add reply parsing and parse domain/bus numbers

Mark McLoughlin markmc at redhat.com
Mon Jul 20 11:51:22 UTC 2009


The current code for parsing pci_add replies ignores the the domain and
bus numbers. Re-write the code to rectify that.

Also, since pci_add is used for NIC hotplug as well ask disk hotplug,
re-factor the code into a separate function.

* src/qemu_driver.c: add qemudParsePciAddReply() function which can
  handle parsing domain and bus numbers
---
 src/qemu_driver.c |  111 +++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 82 insertions(+), 29 deletions(-)

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 4cc78f5..27bda12 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -4340,15 +4340,83 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn,
     return 0;
 }
 
+static int
+qemudParsePciAddReply(virDomainObjPtr vm,
+                      const char *reply,
+                      int *domain,
+                      int *bus,
+                      int *slot)
+{
+    char *s, *e;
+
+    DEBUG("%s: pci_add reply: %s", vm->def->name, reply);
+
+    /* If the command succeeds qemu prints:
+     * OK bus 0, slot XXX...
+     * or
+     * OK domain 0, bus 0, slot XXX
+     */
+    if (!(s = strstr(reply, "OK ")))
+        return -1;
+
+    s += 3;
+
+    if (STRPREFIX(s, "domain ")) {
+        s += strlen("domain ");
+
+        if (virStrToLong_i(s, &e, 10, domain) == -1) {
+            VIR_WARN(_("Unable to parse domain number '%s'\n"), s);
+            return -1;
+        }
+
+        if (!STRPREFIX(e, ", ")) {
+            VIR_WARN(_("Expected ', ' parsing pci_add reply '%s'\n"), s);
+            return -1;
+        }
+        s = e + 2;
+    }
+
+    if (!STRPREFIX(s, "bus ")) {
+        VIR_WARN(_("Expected 'bus ' parsing pci_add reply '%s'\n"), s);
+        return -1;
+    }
+    s += strlen("bus ");
+
+    if (virStrToLong_i(s, &e, 10, bus) == -1) {
+        VIR_WARN(_("Unable to parse bus number '%s'\n"), s);
+        return -1;
+    }
+
+    if (!STRPREFIX(e, ", ")) {
+        VIR_WARN(_("Expected ', ' parsing pci_add reply '%s'\n"), s);
+        return -1;
+    }
+    s = e + 2;
+
+    if (!STRPREFIX(s, "slot ")) {
+        VIR_WARN(_("Expected 'slot ' parsing pci_add reply '%s'\n"), s);
+        return -1;
+    }
+    s += strlen("slot ");
+
+    if (virStrToLong_i(s, &e, 10, slot) == -1) {
+        VIR_WARN(_("Unable to parse slot number '%s'\n"), s);
+        return -1;
+    }
+
+    return 0;
+}
+
 static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
                                           virDomainObjPtr vm,
                                           virDomainDeviceDefPtr dev)
 {
     int ret, i;
-    char *cmd, *reply, *s;
+    char *cmd, *reply;
     char *safe_path;
     const char* type = virDomainDiskBusTypeToString(dev->data.disk->bus);
     int tryOldSyntax = 0;
+    int domain, bus, slot;
 
     for (i = 0 ; i < vm->def->ndisks ; i++) {
         if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
@@ -4387,46 +4455,31 @@ try_command:
 
     VIR_FREE(cmd);
 
-    DEBUG ("%s: pci_add reply: %s", vm->def->name, reply);
-    /* If the command succeeds qemu prints:
-     * OK bus 0, slot XXX...
-     * or
-     * OK domain 0, bus 0, slot XXX
-     */
-    if ((s = strstr(reply, "OK ")) &&
-        (s = strstr(s, "slot "))) {
-        char *dummy = s;
-        int domain, bus, slot;
-
-        s += strlen("slot ");
-
-        /* XXX not neccessarily always going to end up in domain 0 / bus 0 :-( */
-        domain = bus = 0;
-        if (virStrToLong_i ((const char*)s, &dummy, 10, &slot) == -1)
-            VIR_WARN("%s", _("Unable to parse slot number\n"));
-        else if (virAsprintf(&dev->data.disk->pci_addr, "%.4x:%.2x:%.2x",
-                             domain, bus, slot) < 0) {
-            virReportOOMError(conn);
+    if (qemudParsePciAddReply(vm, reply, &domain, &bus, &slot) < 0) {
+        if (!tryOldSyntax && strstr(reply, "invalid char in expression")) {
             VIR_FREE(reply);
-            return -1;
+            tryOldSyntax = 1;
+            goto try_command;
         }
-    } else if (!tryOldSyntax && strstr(reply, "invalid char in expression")) {
-        VIR_FREE(reply);
-        tryOldSyntax = 1;
-        goto try_command;
-    } else {
+
         qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
                           _("adding %s disk failed: %s"), type, reply);
         VIR_FREE(reply);
         return -1;
     }
 
+    VIR_FREE(reply);
+
+    if (virAsprintf(&dev->data.disk->pci_addr, "%.4x:%.2x:%.2x",
+                    domain, bus, slot) < 0) {
+        virReportOOMError(conn);
+        return -1;
+    }
+
     vm->def->disks[vm->def->ndisks++] = dev->data.disk;
     qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
           virDomainDiskQSort);
 
-    VIR_FREE(reply);
-
     return 0;
 }
 
-- 
1.6.2.5




More information about the libvir-list mailing list