Include OS driver name (if any) in device XML for nodedev driver

This commit is contained in:
Daniel P. Berrange 2009-06-12 13:12:55 +00:00
parent d2c9fe850b
commit a8b12e4f27
5 changed files with 84 additions and 2 deletions

View File

@ -1,6 +1,16 @@
Thu Jun 12 13:06:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Improve error reporting for virConnecOpen URIs
Include OS driver name (if any) in device XML
* src/node_device.c: Refresh OS driver when generating XML,
and include impl for Linux sysfs
* src/noe_device_conf.c, src/node_device_conf.h: Add field
for OS driver name to config
* src/node_device_hal.c: Record sysfs path to be used for
driver name fetching later.
Thu Jun 12 13:06:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Improve error reporting for virConnectOpen URIs
* src/lxc_driver.c, src/openvz_driver.c, src/qemu_driver.c,
src/uml_driver.c, src/xen_unified.c: Always return ACCEPT
or ERROR for URIs without hostname set, but with the driver's

View File

@ -48,6 +48,60 @@ static int dev_has_cap(const virNodeDeviceObjPtr dev, const char *cap)
return 0;
}
#ifdef __linux__
static int update_driver_name(virConnectPtr conn,
virNodeDeviceObjPtr dev)
{
char *driver_link = NULL;
char devpath[PATH_MAX];
char *p;
int ret = -1;
int n;
VIR_FREE(dev->def->driver);
if (virAsprintf(&driver_link, "%s/driver", dev->devicePath) < 0) {
virReportOOMError(conn);
goto cleanup;
}
/* Some devices don't have an explicit driver, so just return
without a name */
if (access(driver_link, R_OK) < 0) {
ret = 0;
goto cleanup;
}
if ((n = readlink(driver_link, devpath, sizeof devpath)) < 0) {
virReportSystemError(conn, errno,
_("cannot resolve driver link %s"), driver_link);
goto cleanup;
}
devpath[n] = '\0';
p = strrchr(devpath, '/');
if (p) {
dev->def->driver = strdup(p+1);
if (!dev->def->driver) {
virReportOOMError(conn);
goto cleanup;
}
}
ret = 0;
cleanup:
VIR_FREE(driver_link);
return ret;
}
#else
/* XXX: Implement me for non-linux */
static int update_driver_name(virConnectPtr conn ATTRIBUTE_UNUSED,
virNodeDeviceObjPtr dev ATTRIBUTE_UNUSED)
{
return 0;
}
#endif
void nodeDeviceLock(virDeviceMonitorStatePtr driver)
{
@ -197,6 +251,7 @@ static char *nodeDeviceDumpXML(virNodeDevicePtr dev,
goto cleanup;
}
update_driver_name(dev->conn, obj);
ret = virNodeDeviceDefFormat(dev->conn, obj->def);
cleanup:

View File

@ -106,6 +106,7 @@ void virNodeDeviceDefFree(virNodeDeviceDefPtr def)
VIR_FREE(def->name);
VIR_FREE(def->parent);
VIR_FREE(def->driver);
caps = def->caps;
while (caps) {
@ -122,6 +123,7 @@ void virNodeDeviceObjFree(virNodeDeviceObjPtr dev)
if (!dev)
return;
VIR_FREE(dev->devicePath);
virNodeDeviceDefFree(dev->def);
if (dev->privateFree)
(*dev->privateFree)(dev->privateData);
@ -219,6 +221,11 @@ char *virNodeDeviceDefFormat(virConnectPtr conn,
if (def->parent)
virBufferEscapeString(&buf, " <parent>%s</parent>\n", def->parent);
if (def->driver) {
virBufferAddLit(&buf, " <driver>\n");
virBufferEscapeString(&buf, " <name>%s</name>\n", def->driver);
virBufferAddLit(&buf, " </driver>\n");
}
for (caps = def->caps; caps; caps = caps->next) {
char uuidstr[VIR_UUID_STRING_BUFLEN];

View File

@ -156,6 +156,7 @@ typedef virNodeDeviceDef *virNodeDeviceDefPtr;
struct _virNodeDeviceDef {
char *name; /* device name (unique on node) */
char *parent; /* optional parent device name */
char *driver; /* optional driver name */
virNodeDevCapsDefPtr caps; /* optional device capabilities */
};
@ -165,6 +166,7 @@ typedef virNodeDeviceObj *virNodeDeviceObjPtr;
struct _virNodeDeviceObj {
virMutex lock;
char *devicePath; /* OS specific path to device metadat, eg sysfs */
virNodeDeviceDefPtr def; /* device definition */
void *privateData; /* driver-specific private data */
void (*privateFree)(void *data); /* destructor for private data */

View File

@ -429,6 +429,7 @@ static void dev_create(const char *udi)
const char *name = hal_name(udi);
int rv;
char *privData = strdup(udi);
char *devicePath = NULL;
if (!privData)
return;
@ -455,15 +456,22 @@ static void dev_create(const char *udi)
if (def->caps == NULL)
goto cleanup;
/* Some devices don't have a path in sysfs, so ignore failure */
get_str_prop(ctx, udi, "linux.sysfs_path", &devicePath);
dev = virNodeDeviceAssignDef(NULL,
&driverState->devs,
def);
if (!dev)
if (!dev) {
VIR_FREE(devicePath);
goto failure;
}
dev->privateData = privData;
dev->privateFree = free_udi;
dev->devicePath = devicePath;
virNodeDeviceObjUnlock(dev);
nodeDeviceUnlock(driverState);