[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