From a8b12e4f2784e41b0f08bd9d654af0bc6860ba96 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 12 Jun 2009 13:12:55 +0000 Subject: [PATCH] Include OS driver name (if any) in device XML for nodedev driver --- ChangeLog | 12 ++++++++- src/node_device.c | 55 ++++++++++++++++++++++++++++++++++++++++++ src/node_device_conf.c | 7 ++++++ src/node_device_conf.h | 2 ++ src/node_device_hal.c | 10 +++++++- 5 files changed, 84 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4ef02d263f..842bbfefb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,16 @@ Thu Jun 12 13:06:42 BST 2009 Daniel P. Berrange - 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 + + 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 diff --git a/src/node_device.c b/src/node_device.c index cd9fb6e65f..de51bc85f4 100644 --- a/src/node_device.c +++ b/src/node_device.c @@ -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: diff --git a/src/node_device_conf.c b/src/node_device_conf.c index be198438e0..1fbf9dc891 100644 --- a/src/node_device_conf.c +++ b/src/node_device_conf.c @@ -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, " %s\n", def->parent); + if (def->driver) { + virBufferAddLit(&buf, " \n"); + virBufferEscapeString(&buf, " %s\n", def->driver); + virBufferAddLit(&buf, " \n"); + } for (caps = def->caps; caps; caps = caps->next) { char uuidstr[VIR_UUID_STRING_BUFLEN]; diff --git a/src/node_device_conf.h b/src/node_device_conf.h index 522dfde484..c33cc738c2 100644 --- a/src/node_device_conf.h +++ b/src/node_device_conf.h @@ -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 */ diff --git a/src/node_device_hal.c b/src/node_device_hal.c index b2af7a0520..ea519466c5 100644 --- a/src/node_device_hal.c +++ b/src/node_device_hal.c @@ -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);