[Libvir] PATCH: 2/4 Refactor QEMU device parsing code

Daniel P. Berrange berrange at redhat.com
Tue Oct 16 20:50:16 UTC 2007


This patch refactors the code for parsing devices to allow a single device
to be parsed. This is preperation for the attach/detach device APIs which
take an XML doc containing a single device definition.

Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
diff -r cb9c6005432e src/qemu_conf.c
--- a/src/qemu_conf.c	Tue Oct 16 15:22:47 2007 -0400
+++ b/src/qemu_conf.c	Tue Oct 16 15:23:51 2007 -0400
@@ -499,22 +499,20 @@ int qemudExtractVersion(virConnectPtr co
 }
 
 
-/* Parse the XML definition for a disk */
-static struct qemud_vm_disk_def *qemudParseDiskXML(virConnectPtr conn,
-                                                   struct qemud_driver *driver ATTRIBUTE_UNUSED,
-                                                   xmlNodePtr node) {
-    struct qemud_vm_disk_def *disk = calloc(1, sizeof(struct qemud_vm_disk_def));
+/* Parse the XML definition for a disk
+ * @param disk pre-allocated & zero'd disk record
+ * @param node XML nodeset to parse for disk definition
+ * @return 0 on success, -1 on failure
+ */
+static int qemudParseDiskXML(virConnectPtr conn,
+                             struct qemud_vm_disk_def *disk,
+                             xmlNodePtr node) {
     xmlNodePtr cur;
     xmlChar *device = NULL;
     xmlChar *source = NULL;
     xmlChar *target = NULL;
     xmlChar *type = NULL;
     int typ = 0;
-
-    if (!disk) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "disk");
-        return NULL;
-    }
 
     type = xmlGetProp(node, BAD_CAST "type");
     if (type != NULL) {
@@ -612,7 +610,7 @@ static struct qemud_vm_disk_def *qemudPa
     xmlFree(target);
     xmlFree(source);
 
-    return disk;
+    return 0;
 
  error:
     if (type)
@@ -623,8 +621,7 @@ static struct qemud_vm_disk_def *qemudPa
         xmlFree(source);
     if (device)
         xmlFree(device);
-    free(disk);
-    return NULL;
+    return -1;
 }
 
 static void qemudRandomMAC(struct qemud_vm_net_def *net) {
@@ -637,11 +634,14 @@ static void qemudRandomMAC(struct qemud_
 }
 
 
-/* Parse the XML definition for a network interface */
-static struct qemud_vm_net_def *qemudParseInterfaceXML(virConnectPtr conn,
-                                                       struct qemud_driver *driver ATTRIBUTE_UNUSED,
-                                                       xmlNodePtr node) {
-    struct qemud_vm_net_def *net = calloc(1, sizeof(struct qemud_vm_net_def));
+/* Parse the XML definition for a network interface
+ * @param net pre-allocated & zero'd net record
+ * @param node XML nodeset to parse for net definition
+ * @return 0 on success, -1 on failure
+ */
+static int qemudParseInterfaceXML(virConnectPtr conn,
+                                  struct qemud_vm_net_def *net,
+                                  xmlNodePtr node) {
     xmlNodePtr cur;
     xmlChar *macaddr = NULL;
     xmlChar *type = NULL;
@@ -651,11 +651,6 @@ static struct qemud_vm_net_def *qemudPar
     xmlChar *script = NULL;
     xmlChar *address = NULL;
     xmlChar *port = NULL;
-
-    if (!net) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "net");
-        return NULL;
-    }
 
     net->type = QEMUD_NET_USER;
 
@@ -869,7 +864,7 @@ static struct qemud_vm_net_def *qemudPar
         xmlFree(address);
     }
 
-    return net;
+    return 0;
 
  error:
     if (network)
@@ -884,23 +879,16 @@ static struct qemud_vm_net_def *qemudPar
         xmlFree(script);
     if (bridge)
         xmlFree(bridge);
-    free(net);
-    return NULL;
+    return -1;
 }
 
 
 /* Parse the XML definition for a network interface */
-static struct qemud_vm_input_def *qemudParseInputXML(virConnectPtr conn,
-                                                   struct qemud_driver *driver ATTRIBUTE_UNUSED,
-                                                   xmlNodePtr node) {
-    struct qemud_vm_input_def *input = calloc(1, sizeof(struct qemud_vm_input_def));
+static int qemudParseInputXML(virConnectPtr conn,
+                              struct qemud_vm_input_def *input,
+                              xmlNodePtr node) {
     xmlChar *type = NULL;
     xmlChar *bus = NULL;
-
-    if (!input) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "input");
-        return NULL;
-    }
 
     type = xmlGetProp(node, BAD_CAST "type");
     bus = xmlGetProp(node, BAD_CAST "bus");
@@ -944,7 +932,7 @@ static struct qemud_vm_input_def *qemudP
     if (bus)
         xmlFree(bus);
 
-    return input;
+    return 0;
 
  error:
     if (type)
@@ -952,8 +940,7 @@ static struct qemud_vm_input_def *qemudP
     if (bus)
         xmlFree(bus);
 
-    free(input);
-    return NULL;
+    return -1;
 }
 
 
@@ -1318,8 +1305,13 @@ static struct qemud_vm_def *qemudParseXM
         (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
         struct qemud_vm_disk_def *prev = NULL;
         for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-            struct qemud_vm_disk_def *disk;
-            if (!(disk = qemudParseDiskXML(conn, driver, obj->nodesetval->nodeTab[i]))) {
+            struct qemud_vm_disk_def *disk = calloc(1, sizeof(struct qemud_vm_disk_def));
+            if (!disk) {
+                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "disk");
+                goto error;
+            }
+            if (qemudParseDiskXML(conn, disk, obj->nodesetval->nodeTab[i]) < 0) {
+                free(disk);
                 goto error;
             }
             def->ndisks++;
@@ -1341,8 +1333,13 @@ static struct qemud_vm_def *qemudParseXM
         (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
         struct qemud_vm_net_def *prev = NULL;
         for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-            struct qemud_vm_net_def *net;
-            if (!(net = qemudParseInterfaceXML(conn, driver, obj->nodesetval->nodeTab[i]))) {
+            struct qemud_vm_net_def *net = calloc(1, sizeof(struct qemud_vm_net_def));
+            if (!net) {
+                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "net");
+                goto error;
+            }
+            if (qemudParseInterfaceXML(conn, net, obj->nodesetval->nodeTab[i]) < 0) {
+                free(net);
                 goto error;
             }
             def->nnets++;
@@ -1363,8 +1360,13 @@ static struct qemud_vm_def *qemudParseXM
         (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
         struct qemud_vm_input_def *prev = NULL;
         for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-            struct qemud_vm_input_def *input;
-            if (!(input = qemudParseInputXML(conn, driver, obj->nodesetval->nodeTab[i]))) {
+            struct qemud_vm_input_def *input = calloc(1, sizeof(struct qemud_vm_input_def));
+            if (!input) {
+                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "input");
+                goto error;
+            }
+            if (qemudParseInputXML(conn, input, obj->nodesetval->nodeTab[i]) < 0) {
+                free(input);
                 goto error;
             }
             /* Mouse + PS/2 is implicit with graphics, so don't store it */
@@ -1929,6 +1931,51 @@ static int qemudSaveConfig(virConnectPtr
     return ret;
 }
 
+struct qemud_vm_device_def *
+qemudParseVMDeviceDef(virConnectPtr conn,
+                      struct qemud_driver *driver ATTRIBUTE_UNUSED,
+                      const char *xmlStr)
+{
+    xmlDocPtr xml;
+    xmlNodePtr node;
+    struct qemud_vm_device_def *dev = calloc(1, sizeof(struct qemud_vm_device_def));
+
+    if (!(xml = xmlReadDoc(BAD_CAST xmlStr, "device.xml", NULL,
+                           XML_PARSE_NOENT | XML_PARSE_NONET |
+                           XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR, NULL);
+        return NULL;
+    }
+
+    node = xmlDocGetRootElement(xml);
+    if (node == NULL) {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR, "missing root element");
+        goto error;
+    }
+    if (xmlStrEqual(node->name, BAD_CAST "disk")) {
+        dev->type = QEMUD_DEVICE_DISK;
+        qemudParseDiskXML(conn, &(dev->data.disk), node);
+    } else if (xmlStrEqual(node->name, BAD_CAST "net")) {
+        dev->type = QEMUD_DEVICE_NET;
+        qemudParseInterfaceXML(conn, &(dev->data.net), node);
+    } else if (xmlStrEqual(node->name, BAD_CAST "input")) {
+        dev->type = QEMUD_DEVICE_DISK;
+        qemudParseInputXML(conn, &(dev->data.input), node);
+    } else {
+        qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR, "unknown device type");
+        goto error;
+    }
+
+    xmlFreeDoc(xml);
+
+    return dev;
+
+  error:
+    if (xml) xmlFreeDoc(xml);
+    if (dev) free(dev);
+    return NULL;
+}
+
 struct qemud_vm_def *
 qemudParseVMDef(virConnectPtr conn,
                 struct qemud_driver *driver,
diff -r cb9c6005432e src/qemu_conf.h
--- a/src/qemu_conf.h	Tue Oct 16 15:22:47 2007 -0400
+++ b/src/qemu_conf.h	Tue Oct 16 15:23:51 2007 -0400
@@ -125,6 +125,22 @@ struct qemud_vm_input_def {
     struct qemud_vm_input_def *next;
 };
 
+/* Flags for the 'type' field in next struct */
+enum qemud_vm_device_type {
+    QEMUD_DEVICE_DISK,
+    QEMUD_DEVICE_NET,
+    QEMUD_DEVICE_INPUT,
+};
+
+struct qemud_vm_device_def {
+    int type;
+    union {
+        struct qemud_vm_disk_def disk;
+        struct qemud_vm_net_def net;
+        struct qemud_vm_input_def input;
+    } data;
+};
+
 #define QEMUD_MAX_BOOT_DEVS 4
 
 /* 3 possible boot devices */
@@ -354,6 +370,11 @@ void        qemudRemoveInactiveVM       
 void        qemudRemoveInactiveVM       (struct qemud_driver *driver,
                                          struct qemud_vm *vm);
 
+struct qemud_vm_device_def *
+            qemudParseVMDeviceDef       (virConnectPtr conn,
+                                         struct qemud_driver *driver,
+                                         const char *xmlStr);
+
 struct qemud_vm_def *
             qemudParseVMDef             (virConnectPtr conn,
                                          struct qemud_driver *driver,


More information about the libvir-list mailing list