diff --git a/src/datatypes.c b/src/datatypes.c --- a/src/datatypes.c +++ b/src/datatypes.c @@ -861,6 +861,7 @@ virReleaseNodeDevice(virNodeDevicePtr de 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 --- 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 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -5689,11 +5689,15 @@ const char *virNodeDeviceGetParent(virNo 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 --- a/src/node_device.c +++ b/src/node_device.c @@ -91,66 +91,84 @@ static virNodeDevicePtr nodeDeviceLookup 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); + +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 +176,32 @@ nodeDeviceListCaps(virNodeDevicePtr dev, 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; }