[libvirt] [PATCH 0/5] test: Add node device driver

The following patches implement a basic node device driver for the test hypervisor driver. This is useful for unit tests in libvirt users (particularly virtinst). Cole Robinson (5): nodedev: Add locking in nodeNumOfDevices nodedev: Break out virNodeDeviceHasCap to node_conf test: Implement node device driver. node conf: Make parsing routines consistent with other drivers test: Support loading node device info from file/XML examples/xml/test/testdev.xml | 16 ++ examples/xml/test/testnode.xml | 1 + examples/xml/test/testnodeinline.xml | 19 +++ src/conf/node_device_conf.c | 57 ++++++- src/conf/node_device_conf.h | 11 ++ src/libvirt_private.syms | 1 + src/node_device/node_device_driver.c | 22 +-- src/test/test_driver.c | 291 +++++++++++++++++++++++++++++++++- 8 files changed, 396 insertions(+), 22 deletions(-) create mode 100644 examples/xml/test/testdev.xml

Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/node_device/node_device_driver.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 93ca28c..c902e7d 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -153,10 +153,15 @@ static int nodeNumOfDevices(virConnectPtr conn, int ndevs = 0; unsigned int i; - for (i = 0; i < driver->devs.count; i++) + nodeDeviceLock(driver); + for (i = 0; i < driver->devs.count; i++) { + virNodeDeviceObjLock(driver->devs.objs[i]); if ((cap == NULL) || dev_has_cap(driver->devs.objs[i], cap)) ++ndevs; + virNodeDeviceObjUnlock(driver->devs.objs[i]); + } + nodeDeviceUnlock(driver); return ndevs; } -- 1.6.5.rc2

On Fri, Oct 02, 2009 at 12:05:01PM -0400, Cole Robinson wrote:
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/node_device/node_device_driver.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 93ca28c..c902e7d 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -153,10 +153,15 @@ static int nodeNumOfDevices(virConnectPtr conn, int ndevs = 0; unsigned int i;
- for (i = 0; i < driver->devs.count; i++) + nodeDeviceLock(driver); + for (i = 0; i < driver->devs.count; i++) { + virNodeDeviceObjLock(driver->devs.objs[i]); if ((cap == NULL) || dev_has_cap(driver->devs.objs[i], cap)) ++ndevs; + virNodeDeviceObjUnlock(driver->devs.objs[i]); + } + nodeDeviceUnlock(driver);
return ndevs;
Opps ! I'll have to look into why this bug wasn't detected by the locking test suite AC Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Will be used by test driver node device implementation. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/conf/node_device_conf.c | 10 ++++++++++ src/conf/node_device_conf.h | 2 ++ src/libvirt_private.syms | 1 + src/node_device/node_device_driver.c | 15 ++------------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 5b25bb7..a810940 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -80,6 +80,16 @@ virNodeDevCapsDefParseString(virConnectPtr conn, return 0; } +int virNodeDeviceHasCap(const virNodeDeviceObjPtr dev, const char *cap) +{ + virNodeDevCapsDefPtr caps = dev->def->caps; + while (caps) { + if (STREQ(cap, virNodeDevCapTypeToString(caps->type))) + return 1; + caps = caps->next; + } + return 0; +} virNodeDeviceObjPtr virNodeDeviceFindByName(const virNodeDeviceObjListPtr devs, const char *name) diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index c33cc73..9fa9127 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -193,6 +193,8 @@ struct _virDeviceMonitorState { virReportErrorHelper(conn, VIR_FROM_NODEDEV, code, __FILE__, \ __FUNCTION__, __LINE__, fmt) +int virNodeDeviceHasCap(const virNodeDeviceObjPtr dev, const char *cap); + virNodeDeviceObjPtr virNodeDeviceFindByName(const virNodeDeviceObjListPtr devs, const char *name); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 49bbf96..952ed29 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -302,6 +302,7 @@ nodeGetFreeMemory; # node_device_conf.h +virNodeDeviceHasCap; virNodeDeviceObjRemove; virNodeDevCapTypeToString; virNodeDeviceFindByName; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index c902e7d..14b3098 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -39,17 +39,6 @@ #define VIR_FROM_THIS VIR_FROM_NODEDEV -static int dev_has_cap(const virNodeDeviceObjPtr dev, const char *cap) -{ - virNodeDevCapsDefPtr caps = dev->def->caps; - while (caps) { - if (STREQ(cap, virNodeDevCapTypeToString(caps->type))) - return 1; - caps = caps->next; - } - return 0; -} - static int update_caps(virNodeDeviceObjPtr dev) { @@ -157,7 +146,7 @@ static int nodeNumOfDevices(virConnectPtr conn, for (i = 0; i < driver->devs.count; i++) { virNodeDeviceObjLock(driver->devs.objs[i]); if ((cap == NULL) || - dev_has_cap(driver->devs.objs[i], cap)) + virNodeDeviceHasCap(driver->devs.objs[i], cap)) ++ndevs; virNodeDeviceObjUnlock(driver->devs.objs[i]); } @@ -180,7 +169,7 @@ nodeListDevices(virConnectPtr conn, for (i = 0; i < driver->devs.count && ndevs < maxnames; i++) { virNodeDeviceObjLock(driver->devs.objs[i]); if (cap == NULL || - dev_has_cap(driver->devs.objs[i], cap)) { + virNodeDeviceHasCap(driver->devs.objs[i], cap)) { if ((names[ndevs++] = strdup(driver->devs.objs[i]->def->name)) == NULL) { virNodeDeviceObjUnlock(driver->devs.objs[i]); goto failure; -- 1.6.5.rc2

On Fri, Oct 02, 2009 at 12:05:02PM -0400, Cole Robinson wrote:
Will be used by test driver node device implementation.
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/conf/node_device_conf.c | 10 ++++++++++ src/conf/node_device_conf.h | 2 ++ src/libvirt_private.syms | 1 + src/node_device/node_device_driver.c | 15 ++------------- 4 files changed, 15 insertions(+), 13 deletions(-)
ACK. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Add a simple 'computer' device for the default driver. Only implement the basic calls, no creation or destroy happening. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 253 insertions(+), 0 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index f57c92a..2a413ee 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -46,6 +46,7 @@ #include "domain_event.h" #include "event.h" #include "storage_conf.h" +#include "node_device_conf.h" #include "xml.h" #include "threads.h" #include "logging.h" @@ -75,6 +76,7 @@ struct _testConn { virNetworkObjList networks; virInterfaceObjList ifaces; virStoragePoolObjList pools; + virNodeDeviceObjList devs; int numCells; testCell cells[MAX_CELLS]; @@ -223,6 +225,24 @@ static const char *defaultPoolXML = " </target>" "</pool>"; +static const char *defaultNodeXML = +"<device>" +" <name>computer</name>" +" <capability type='system'>" +" <hardware>" +" <vendor>Libvirt</vendor>" +" <version>Test driver</version>" +" <serial>123456</serial>" +" <uuid>11111111-2222-3333-4444-555555555555</uuid>" +" </hardware>" +" <firmware>" +" <vendor>Libvirt</vendor>" +" <version>Test Driver</version>" +" <release_date>01/22/2007</release_date>" +" </firmware>" +" </capability>" +"</device>"; + static const unsigned long long defaultPoolCap = (100 * 1024 * 1024 * 1024ull); static const unsigned long long defaultPoolAlloc = 0; @@ -295,6 +315,8 @@ static int testOpenDefault(virConnectPtr conn) { virInterfaceObjPtr interfaceobj = NULL; virStoragePoolDefPtr pooldef = NULL; virStoragePoolObjPtr poolobj = NULL; + virNodeDeviceDefPtr nodedef = NULL; + virNodeDeviceObjPtr nodeobj = NULL; if (VIR_ALLOC(privconn) < 0) { virReportOOMError(conn); @@ -382,6 +404,16 @@ static int testOpenDefault(virConnectPtr conn) { poolobj->active = 1; virStoragePoolObjUnlock(poolobj); + /* Init default node device */ + if (!(nodedef = virNodeDeviceDefParseString(conn, defaultNodeXML, 0))) + goto error; + if (!(nodeobj = virNodeDeviceAssignDef(conn, &privconn->devs, + nodedef))) { + virNodeDeviceDefFree(nodedef); + goto error; + } + virNodeDeviceObjUnlock(nodeobj); + testDriverUnlock(privconn); return VIR_DRV_OPEN_SUCCESS; @@ -391,6 +423,7 @@ error: virNetworkObjListFree(&privconn->networks); virInterfaceObjListFree(&privconn->ifaces); virStoragePoolObjListFree(&privconn->pools); + virNodeDeviceObjListFree(&privconn->devs); virCapabilitiesFree(privconn->caps); testDriverUnlock(privconn); conn->privateData = NULL; @@ -4072,6 +4105,7 @@ cleanup: } +/* Node device implementations */ static virDrvOpenStatus testDevMonOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED) { @@ -4087,8 +4121,217 @@ static int testDevMonClose(virConnectPtr conn) { return 0; } +static int +testNodeNumOfDevices(virConnectPtr conn, + const char *cap, + unsigned int flags ATTRIBUTE_UNUSED) +{ + testConnPtr driver = conn->privateData; + int ndevs = 0; + unsigned int i; + + testDriverLock(driver); + for (i = 0; i < driver->devs.count; i++) + if ((cap == NULL) || + virNodeDeviceHasCap(driver->devs.objs[i], cap)) + ++ndevs; + testDriverUnlock(driver); + + return ndevs; +} + +static int +testNodeListDevices(virConnectPtr conn, + const char *cap, + char **const names, + int maxnames, + unsigned int flags ATTRIBUTE_UNUSED) +{ + testConnPtr driver = conn->privateData; + int ndevs = 0; + unsigned int i; + + testDriverLock(driver); + for (i = 0; i < driver->devs.count && ndevs < maxnames; i++) { + virNodeDeviceObjLock(driver->devs.objs[i]); + if (cap == NULL || + virNodeDeviceHasCap(driver->devs.objs[i], cap)) { + if ((names[ndevs++] = strdup(driver->devs.objs[i]->def->name)) == NULL) { + virNodeDeviceObjUnlock(driver->devs.objs[i]); + goto failure; + } + } + virNodeDeviceObjUnlock(driver->devs.objs[i]); + } + testDriverUnlock(driver); + + return ndevs; + + failure: + testDriverUnlock(driver); + --ndevs; + while (--ndevs >= 0) + VIR_FREE(names[ndevs]); + return -1; +} + +static virNodeDevicePtr +testNodeDeviceLookupByName(virConnectPtr conn, const char *name) +{ + testConnPtr driver = conn->privateData; + virNodeDeviceObjPtr obj; + virNodeDevicePtr ret = NULL; + + testDriverLock(driver); + obj = virNodeDeviceFindByName(&driver->devs, name); + testDriverUnlock(driver); + + if (!obj) { + virNodeDeviceReportError(conn, VIR_ERR_NO_NODE_DEVICE, NULL); + goto cleanup; + } + + ret = virGetNodeDevice(conn, name); + +cleanup: + if (obj) + virNodeDeviceObjUnlock(obj); + return ret; +} + +static char * +testNodeDeviceDumpXML(virNodeDevicePtr dev, + unsigned int flags ATTRIBUTE_UNUSED) +{ + testConnPtr driver = dev->conn->privateData; + virNodeDeviceObjPtr obj; + char *ret = NULL; + + testDriverLock(driver); + obj = virNodeDeviceFindByName(&driver->devs, dev->name); + testDriverUnlock(driver); + + if (!obj) { + virNodeDeviceReportError(dev->conn, VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + dev->name); + goto cleanup; + } + + ret = virNodeDeviceDefFormat(dev->conn, obj->def); + +cleanup: + if (obj) + virNodeDeviceObjUnlock(obj); + return ret; +} + +static char * +testNodeDeviceGetParent(virNodeDevicePtr dev) +{ + testConnPtr driver = dev->conn->privateData; + virNodeDeviceObjPtr obj; + char *ret = NULL; + + testDriverLock(driver); + obj = virNodeDeviceFindByName(&driver->devs, dev->name); + testDriverUnlock(driver); + + if (!obj) { + virNodeDeviceReportError(dev->conn, VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + dev->name); + goto cleanup; + } + + if (obj->def->parent) { + ret = strdup(obj->def->parent); + if (!ret) + virReportOOMError(dev->conn); + } else { + virNodeDeviceReportError(dev->conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("no parent for this device")); + } + +cleanup: + if (obj) + virNodeDeviceObjUnlock(obj); + return ret; +} + static int +testNodeDeviceNumOfCaps(virNodeDevicePtr dev) +{ + testConnPtr driver = dev->conn->privateData; + virNodeDeviceObjPtr obj; + virNodeDevCapsDefPtr caps; + int ncaps = 0; + int ret = -1; + + testDriverLock(driver); + obj = virNodeDeviceFindByName(&driver->devs, dev->name); + testDriverUnlock(driver); + + if (!obj) { + virNodeDeviceReportError(dev->conn, VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + dev->name); + goto cleanup; + } + + for (caps = obj->def->caps; caps; caps = caps->next) + ++ncaps; + ret = ncaps; + +cleanup: + if (obj) + virNodeDeviceObjUnlock(obj); + return ret; +} + + +static int +testNodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames) +{ + testConnPtr driver = dev->conn->privateData; + virNodeDeviceObjPtr obj; + virNodeDevCapsDefPtr caps; + int ncaps = 0; + int ret = -1; + + testDriverLock(driver); + obj = virNodeDeviceFindByName(&driver->devs, dev->name); + testDriverUnlock(driver); + + if (!obj) { + virNodeDeviceReportError(dev->conn, VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + dev->name); + goto cleanup; + } + + for (caps = obj->def->caps; caps && ncaps < maxnames; caps = caps->next) { + names[ncaps] = strdup(virNodeDevCapTypeToString(caps->type)); + if (names[ncaps++] == NULL) + goto cleanup; + } + ret = ncaps; + +cleanup: + if (obj) + virNodeDeviceObjUnlock(obj); + if (ret == -1) { + --ncaps; + while (--ncaps >= 0) + VIR_FREE(names[ncaps]); + } + return ret; +} + + +/* Domain event implementations */ +static int testDomainEventRegister (virConnectPtr conn, virConnectDomainEventCallback callback, void *opaque, @@ -4352,6 +4595,16 @@ static virDeviceMonitor testDevMonitor = { .name = "Test", .open = testDevMonOpen, .close = testDevMonClose, + + .numOfDevices = testNodeNumOfDevices, + .listDevices = testNodeListDevices, + .deviceLookupByName = testNodeDeviceLookupByName, + .deviceDumpXML = testNodeDeviceDumpXML, + .deviceGetParent = testNodeDeviceGetParent, + .deviceNumOfCaps = testNodeDeviceNumOfCaps, + .deviceListCaps = testNodeDeviceListCaps, + //.deviceCreateXML = nodeDeviceCreateXML; + //.deviceDestroy = nodeDeviceDestroy; }; static virSecretDriver testSecretDriver = { -- 1.6.5.rc2

On Fri, Oct 02, 2009 at 12:05:03PM -0400, Cole Robinson wrote:
Add a simple 'computer' device for the default driver. Only implement the basic calls, no creation or destroy happening.
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/test/test_driver.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 253 insertions(+), 0 deletions(-)
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Add virNodeDeviceParseFile, and make virNodeDeviceParseNode non-static. These will be used by the test driver. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/conf/node_device_conf.c | 47 ++++++++++++++++++++++++++++++++++++------ src/conf/node_device_conf.h | 9 ++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index a810940..f09f814 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1097,8 +1097,11 @@ virNodeDeviceDefParseXML(virConnectPtr conn, xmlXPathContextPtr ctxt, int create return NULL; } -static virNodeDeviceDefPtr -virNodeDeviceDefParseNode(virConnectPtr conn, xmlDocPtr xml, xmlNodePtr root, int create) +virNodeDeviceDefPtr +virNodeDeviceDefParseNode(virConnectPtr conn, + xmlDocPtr xml, + xmlNodePtr root, + int create) { xmlXPathContextPtr ctxt = NULL; virNodeDeviceDefPtr def = NULL; @@ -1143,8 +1146,13 @@ catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) } } -virNodeDeviceDefPtr -virNodeDeviceDefParseString(virConnectPtr conn, const char *str, int create) + + +static virNodeDeviceDefPtr +virNodeDeviceDefParse(virConnectPtr conn, + const char *str, + const char *filename, + int create) { xmlParserCtxtPtr pctxt; xmlDocPtr xml = NULL; @@ -1159,9 +1167,17 @@ virNodeDeviceDefParseString(virConnectPtr conn, const char *str, int create) pctxt->_private = conn; if (conn) virResetError (&conn->err); - xml = xmlCtxtReadDoc(pctxt, BAD_CAST str, "device.xml", NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOWARNING); + if (filename) { + xml = xmlCtxtReadFile (pctxt, filename, NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + } else { + xml = xmlCtxtReadDoc (pctxt, BAD_CAST str, + "device.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + } + if (!xml) { if (conn && conn->err.code == VIR_ERR_NONE) virNodeDeviceReportError(conn, VIR_ERR_XML_ERROR, @@ -1183,6 +1199,23 @@ cleanup: return def; } +virNodeDeviceDefPtr +virNodeDeviceDefParseString(virConnectPtr conn, + const char *str, + int create) +{ + return virNodeDeviceDefParse(conn, str, NULL, create); +} + +virNodeDeviceDefPtr +virNodeDeviceDefParseFile(virConnectPtr conn, + const char *filename, + int create) +{ + return virNodeDeviceDefParse(conn, NULL, filename, create); +} + + void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) { union _virNodeDevCapData *data = &caps->data; diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 9fa9127..29a4d43 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -28,6 +28,8 @@ #include "util.h" #include "threads.h" +#include <libxml/tree.h> + #define CREATE_DEVICE 1 #define EXISTING_DEVICE 0 @@ -211,6 +213,13 @@ char *virNodeDeviceDefFormat(virConnectPtr conn, virNodeDeviceDefPtr virNodeDeviceDefParseString(virConnectPtr conn, const char *str, int create); +virNodeDeviceDefPtr virNodeDeviceDefParseFile(virConnectPtr conn, + const char *filename, + int create); +virNodeDeviceDefPtr virNodeDeviceDefParseNode(virConnectPtr conn, + xmlDocPtr xml, + xmlNodePtr root, + int create); void virNodeDeviceDefFree(virNodeDeviceDefPtr def); -- 1.6.5.rc2

On Fri, Oct 02, 2009 at 12:05:04PM -0400, Cole Robinson wrote:
Add virNodeDeviceParseFile, and make virNodeDeviceParseNode non-static. These will be used by the test driver.
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/conf/node_device_conf.c | 47 ++++++++++++++++++++++++++++++++++++------ src/conf/node_device_conf.h | 9 ++++++++ 2 files changed, 49 insertions(+), 7 deletions(-)
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Also add some XML examples. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- examples/xml/test/testdev.xml | 16 +++++++++++++ examples/xml/test/testnode.xml | 1 + examples/xml/test/testnodeinline.xml | 19 ++++++++++++++++ src/test/test_driver.c | 40 +++++++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 1 deletions(-) create mode 100644 examples/xml/test/testdev.xml diff --git a/examples/xml/test/testdev.xml b/examples/xml/test/testdev.xml new file mode 100644 index 0000000..c49caa7 --- /dev/null +++ b/examples/xml/test/testdev.xml @@ -0,0 +1,16 @@ +<device> + <name>File_test_device</name> + <capability type='system'> + <hardware> + <vendor>Libvirt</vendor> + <version>Test driver</version> + <serial>123456</serial> + <uuid>11111111-2222-3333-4444-555555555555</uuid> + </hardware> + <firmware> + <vendor>Libvirt</vendor> + <version>Test Driver</version> + <release_date>01/22/2007</release_date> + </firmware> + </capability> +</device> diff --git a/examples/xml/test/testnode.xml b/examples/xml/test/testnode.xml index 1ad7a10..adc5440 100644 --- a/examples/xml/test/testnode.xml +++ b/examples/xml/test/testnode.xml @@ -14,6 +14,7 @@ <pool file="testpool.xml"> <volume file="testvol.xml"/> </pool> + <device file="testdev.xml"/> <cpu> <mhz>6000</mhz> diff --git a/examples/xml/test/testnodeinline.xml b/examples/xml/test/testnodeinline.xml index 1810d4d..b353f39 100644 --- a/examples/xml/test/testnodeinline.xml +++ b/examples/xml/test/testnodeinline.xml @@ -97,6 +97,25 @@ </dhcp> </ip> </network> + +<device> + <name>File_test_device</name> + <capability type='system'> + <hardware> + <vendor>Libvirt</vendor> + <version>Test driver</version> + <serial>123456</serial> + <uuid>11111111-2222-3333-4444-555555555555</uuid> + </hardware> + <firmware> + <vendor>Libvirt</vendor> + <version>Test Driver</version> + <release_date>01/22/2007</release_date> + </firmware> + </capability> +</device> + + <cpu> <mhz>6000</mhz> <model>i986</model> diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 2a413ee..764faf2 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -547,7 +547,8 @@ static int testOpenFromFile(virConnectPtr conn, char *str; xmlDocPtr xml = NULL; xmlNodePtr root = NULL; - xmlNodePtr *domains = NULL, *networks = NULL, *ifaces = NULL, *pools = NULL; + xmlNodePtr *domains = NULL, *networks = NULL, *ifaces = NULL, + *pools = NULL, *devs = NULL; xmlXPathContextPtr ctxt = NULL; virNodeInfoPtr nodeInfo; virNetworkObjPtr net; @@ -841,6 +842,43 @@ static int testOpenFromFile(virConnectPtr conn, } VIR_FREE(pools); + ret = virXPathNodeSet(conn, "/node/device", ctxt, &devs); + if (ret < 0) { + testError(NULL, VIR_ERR_XML_ERROR, "%s", _("node device list")); + goto error; + } + for (i = 0 ; i < ret ; i++) { + virNodeDeviceDefPtr def; + virNodeDeviceObjPtr dev; + char *relFile = virXMLPropString(devs[i], "file"); + + if (relFile != NULL) { + char *absFile = testBuildFilename(file, relFile); + VIR_FREE(relFile); + + if (!absFile) { + testError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("resolving device filename")); + goto error; + } + + def = virNodeDeviceDefParseFile(conn, absFile, 0); + VIR_FREE(absFile); + if (!def) + goto error; + } else { + if ((def = virNodeDeviceDefParseNode(conn, xml, devs[i], 0)) == NULL) + goto error; + } + if (!(dev = virNodeDeviceAssignDef(conn, &privconn->devs, def))) { + virNodeDeviceDefFree(def); + goto error; + } + virNodeDeviceObjUnlock(dev); + } + VIR_FREE(devs); + + xmlXPathFreeContext(ctxt); xmlFreeDoc(xml); testDriverUnlock(privconn); -- 1.6.5.rc2

On Fri, Oct 02, 2009 at 12:05:05PM -0400, Cole Robinson wrote:
Also add some XML examples.
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- examples/xml/test/testdev.xml | 16 +++++++++++++ examples/xml/test/testnode.xml | 1 + examples/xml/test/testnodeinline.xml | 19 ++++++++++++++++ src/test/test_driver.c | 40 +++++++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 1 deletions(-) create mode 100644 examples/xml/test/testdev.xml
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On 10/05/2009 08:36 AM, Daniel P. Berrange wrote:
On Fri, Oct 02, 2009 at 12:05:05PM -0400, Cole Robinson wrote:
Also add some XML examples.
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- examples/xml/test/testdev.xml | 16 +++++++++++++ examples/xml/test/testnode.xml | 1 + examples/xml/test/testnodeinline.xml | 19 ++++++++++++++++ src/test/test_driver.c | 40 +++++++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 1 deletions(-) create mode 100644 examples/xml/test/testdev.xml
ACK
Daniel
Thanks, I've pushed this series. - Cole
participants (2)
-
Cole Robinson
-
Daniel P. Berrange