diff --git a/ChangeLog b/ChangeLog index 41932d415f..c9e64c1d30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Thu Dec 4 21:46:41 GMT 2008 Daniel P. Berrange + + * src/libvirt.c, src/datatypes.h, src/datatypes.c: Cache + device parent string to workaround need to keep public + virNodeDeviceGetParent API returning a const string + * src/node_device.c: Merge all return paths from node + device driver APIs + Thu Dec 4 21:43:41 GMT 2008 Daniel P. Berrange * src/openvz_conf.h: Add driver lock diff --git a/src/datatypes.c b/src/datatypes.c index 3911a2dfda..82acd080df 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -861,6 +861,7 @@ virReleaseNodeDevice(virNodeDevicePtr dev) { dev->magic = -1; VIR_FREE(dev->name); + VIR_FREE(dev->parent); VIR_FREE(dev); DEBUG("unref connection %p %d", conn, conn->refs); diff --git a/src/datatypes.h b/src/datatypes.h index e61b178f3a..6512537896 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -199,6 +199,7 @@ struct _virNodeDevice { int refs; /* reference count */ virConnectPtr conn; /* pointer back to the connection */ char *name; /* device name (unique on node) */ + char *parent; /* parent device name */ }; diff --git a/src/libvirt.c b/src/libvirt.c index a279024eb7..a4a0df59e4 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -5689,11 +5689,15 @@ const char *virNodeDeviceGetParent(virNodeDevicePtr dev) return NULL; } - if (dev->conn->deviceMonitor && dev->conn->deviceMonitor->deviceGetParent) - return dev->conn->deviceMonitor->deviceGetParent (dev); - - virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); - return NULL; + if (!dev->parent) { + if (dev->conn->deviceMonitor && dev->conn->deviceMonitor->deviceGetParent) { + dev->parent = dev->conn->deviceMonitor->deviceGetParent (dev); + } else { + virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return NULL; + } + } + return dev->parent; } /** diff --git a/src/node_device.c b/src/node_device.c index 8818f834bf..f2bdaec003 100644 --- a/src/node_device.c +++ b/src/node_device.c @@ -91,66 +91,86 @@ static virNodeDevicePtr nodeDeviceLookupByName(virConnectPtr conn, const char *name) { virDeviceMonitorStatePtr driver = conn->devMonPrivateData; - virNodeDeviceObjPtr obj = virNodeDeviceFindByName(&driver->devs, name); + virNodeDeviceObjPtr obj; + virNodeDevicePtr ret = NULL; + obj = virNodeDeviceFindByName(&driver->devs, name); if (!obj) { virNodeDeviceReportError(conn, VIR_ERR_INVALID_NODE_DEVICE, "%s", _("no node device with matching name")); - return NULL; + goto cleanup; } - return virGetNodeDevice(conn, name); + ret = virGetNodeDevice(conn, name); +cleanup: + return ret; } static char *nodeDeviceDumpXML(virNodeDevicePtr dev, unsigned int flags ATTRIBUTE_UNUSED) { virDeviceMonitorStatePtr driver = dev->conn->devMonPrivateData; - virNodeDeviceObjPtr obj = virNodeDeviceFindByName(&driver->devs, dev->name); + virNodeDeviceObjPtr obj; + char *ret = NULL; + obj = virNodeDeviceFindByName(&driver->devs, dev->name); if (!obj) { virNodeDeviceReportError(dev->conn, VIR_ERR_INVALID_NODE_DEVICE, "%s", _("no node device with matching name")); - return NULL; + goto cleanup; } - return virNodeDeviceDefFormat(dev->conn, obj->def); + ret = virNodeDeviceDefFormat(dev->conn, obj->def); + +cleanup: + return ret; } static char *nodeDeviceGetParent(virNodeDevicePtr dev) { virDeviceMonitorStatePtr driver = dev->conn->devMonPrivateData; - virNodeDeviceObjPtr obj = virNodeDeviceFindByName(&driver->devs, dev->name); + virNodeDeviceObjPtr obj; + char *ret = NULL; + obj = virNodeDeviceFindByName(&driver->devs, dev->name); if (!obj) { virNodeDeviceReportError(dev->conn, VIR_ERR_INVALID_NODE_DEVICE, "%s", _("no node device with matching name")); - return NULL; + goto cleanup; } - return obj->def->parent; + ret = strdup(obj->def->parent); + if (!ret) + virNodeDeviceReportError(dev->conn, VIR_ERR_NO_MEMORY, NULL); + +cleanup: + return ret; } static int nodeDeviceNumOfCaps(virNodeDevicePtr dev) { virDeviceMonitorStatePtr driver = dev->conn->devMonPrivateData; - virNodeDeviceObjPtr obj = virNodeDeviceFindByName(&driver->devs, dev->name); + virNodeDeviceObjPtr obj; virNodeDevCapsDefPtr caps; int ncaps = 0; + int ret = -1; + obj = virNodeDeviceFindByName(&driver->devs, dev->name); if (!obj) { virNodeDeviceReportError(dev->conn, VIR_ERR_INVALID_NODE_DEVICE, "%s", _("no node device with matching name")); - return -1; + goto cleanup; } for (caps = obj->def->caps; caps; caps = caps->next) ++ncaps; + ret = ncaps; - return ncaps; +cleanup: + return ret; } @@ -158,29 +178,32 @@ static int nodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames) { virDeviceMonitorStatePtr driver = dev->conn->devMonPrivateData; - virNodeDeviceObjPtr obj = virNodeDeviceFindByName(&driver->devs, dev->name); + virNodeDeviceObjPtr obj; virNodeDevCapsDefPtr caps; int ncaps = 0; + int ret = -1; + obj = virNodeDeviceFindByName(&driver->devs, dev->name); if (!obj) { virNodeDeviceReportError(dev->conn, VIR_ERR_INVALID_NODE_DEVICE, "%s", _("no node device with matching name")); - return -1; + goto cleanup; } for (caps = obj->def->caps; caps && ncaps < maxnames; caps = caps->next) { names[ncaps] = strdup(virNodeDevCapTypeToString(caps->type)); if (names[ncaps++] == NULL) - goto failure; + goto cleanup; } + ret = ncaps; - return ncaps; - - failure: - --ncaps; - while (--ncaps >= 0) - VIR_FREE(names[ncaps]); - return -1; +cleanup: + if (ret == -1) { + --ncaps; + while (--ncaps >= 0) + VIR_FREE(names[ncaps]); + } + return ret; }