From 786fe571f1d3470150d5f3c57a751c0954d40198 Mon Sep 17 00:00:00 2001 From: mananth Date: Wed, 10 Dec 2003 08:53:21 +0000 Subject: Changes to dynamically read/refresh attributes --- ChangeLog | 4 ++++ include/libsysfs.h | 2 ++ lib/sysfs_bus.c | 5 +++++ lib/sysfs_class.c | 13 ++++++++----- lib/sysfs_device.c | 18 +++++++++--------- lib/sysfs_dir.c | 39 ++++++++++++++++++++++++++++++++------- lib/sysfs_driver.c | 5 +++++ lib/sysfs_utils.c | 23 +++++++++++++++++++++++ 8 files changed, 88 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7969c4f..5b2b373 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ +12/10/2003 - Ananth Mavinakayanahalli + * Added more optimization changes + * Added code to add and refresh attributes dynamically + 12/08/2003 - Daniel Stekloff * Patched code for directory/attribute read optimization diff --git a/include/libsysfs.h b/include/libsysfs.h index 1a12d65..0939102 100644 --- a/include/libsysfs.h +++ b/include/libsysfs.h @@ -142,6 +142,8 @@ extern int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len); extern int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, size_t len); extern int sysfs_path_is_dir(const unsigned char *path); +extern int sysfs_path_is_link(const unsigned char *path); +extern int sysfs_path_is_file(const unsigned char *path); extern int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len); extern struct dlist *sysfs_open_subsystem_list(unsigned char *name); diff --git a/lib/sysfs_bus.c b/lib/sysfs_bus.c index 615407e..0a7b171 100644 --- a/lib/sysfs_bus.c +++ b/lib/sysfs_bus.c @@ -335,6 +335,7 @@ struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) { if (bus == NULL) return NULL; + if (bus->directory == NULL) { bus->directory = sysfs_open_directory(bus->path); if (bus->directory == NULL) @@ -344,6 +345,10 @@ struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) if ((sysfs_read_dir_attributes(bus->directory)) != 0) return NULL; } else { + if ((sysfs_path_is_dir(bus->path)) != 0) { + dprintf("Bus at %s no longer exists\n", bus->path); + return NULL; + } if ((sysfs_refresh_attributes (bus->directory->attributes)) != 0) { dprintf("Error refreshing bus attributes\n"); diff --git a/lib/sysfs_class.c b/lib/sysfs_class.c index 5d4da33..7d85f8f 100644 --- a/lib/sysfs_class.c +++ b/lib/sysfs_class.c @@ -538,6 +538,11 @@ struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev) return NULL; } } else { + if ((sysfs_path_is_dir(cdev->path)) != 0) { + dprintf("Class device at %s no longer exists\n", + cdev->path); + return NULL; + } if ((sysfs_refresh_attributes (cdev->directory->attributes)) != 0) { dprintf("Error refreshing classdev attributes\n"); @@ -565,15 +570,13 @@ struct sysfs_attribute *sysfs_get_classdev_attr return NULL; } - if (clsdev->directory == NULL) { - clsdev->directory = sysfs_open_directory(clsdev->path); - if (clsdev->directory == NULL) - return NULL; - } /* * First, see if it's in the current directory. Then look at * subdirs since class devices can have subdirs of attributes. */ + attrlist = sysfs_get_classdev_attributes(clsdev); + if (attrlist == NULL) + return NULL; cur = sysfs_get_directory_attribute(clsdev->directory, (unsigned char *)name); if (cur != NULL) diff --git a/lib/sysfs_device.c b/lib/sysfs_device.c index e5540dd..46e72ec 100644 --- a/lib/sysfs_device.c +++ b/lib/sysfs_device.c @@ -378,6 +378,10 @@ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) if ((sysfs_read_dir_attributes(device->directory)) != 0) return NULL; } else { + if ((sysfs_path_is_dir(device->path)) != 0) { + dprintf("Device at %s no longer exists", device->path); + return NULL; + } if ((sysfs_refresh_attributes (device->directory->attributes)) != 0) { dprintf("Error refreshing device attributes\n"); @@ -397,19 +401,15 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, const unsigned char *name) { struct sysfs_attribute *cur = NULL; + struct dlist *attrlist = NULL; if (dev == NULL || name == NULL) { errno = EINVAL; return NULL; } - if (dev->directory == NULL) { - dev->directory = sysfs_open_directory(dev->path); - if (dev->directory == NULL) - return NULL; - } - dev->directory->attributes = sysfs_get_device_attributes(dev); - if (dev->directory->attributes == NULL) + attrlist = sysfs_get_device_attributes(dev); + if (attrlist == NULL) return NULL; cur = sysfs_get_directory_attribute(dev->directory, @@ -431,14 +431,14 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, static int get_device_absolute_path(const unsigned char *device, const unsigned char *bus, unsigned char *path, size_t psize) { - unsigned char bus_path[SYSFS_NAME_LEN]; + unsigned char bus_path[SYSFS_PATH_MAX]; if (device == NULL || path == NULL) { errno = EINVAL; return -1; } - memset(bus_path, 0, SYSFS_NAME_LEN); + memset(bus_path, 0, SYSFS_PATH_MAX); if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX) != 0) { dprintf ("Sysfs not supported on this system\n"); return -1; diff --git a/lib/sysfs_dir.c b/lib/sysfs_dir.c index 7046d20..33fe4ec 100644 --- a/lib/sysfs_dir.c +++ b/lib/sysfs_dir.c @@ -524,10 +524,24 @@ int sysfs_refresh_attributes(struct dlist *attrlist) if (attr->method & SYSFS_METHOD_SHOW) { if ((sysfs_read_attribute(attr)) != 0) { dprintf("Error reading attribute %s\n", path); - return 1; + if ((sysfs_path_is_file(attr->path)) != 0) { + dprintf("Attr %s no longer exists\n", + attr->name); + } + } + } else { + if ((sysfs_path_is_file(attr->path)) != 0) { + dprintf("Attr %s no longer exists\n", + attr->name); } } } + if (attrlist->count == 0) { + dprintf("No attributes in the list, destroying list now\n"); + dlist_destroy(attrlist); + attrlist = NULL; + return 1; + } return 0; } @@ -798,6 +812,7 @@ struct sysfs_attribute *sysfs_get_directory_attribute (struct sysfs_directory *dir, unsigned char *attrname) { struct sysfs_attribute *attr = NULL; + unsigned char new_path[SYSFS_PATH_MAX]; if (dir == NULL || attrname == NULL) { errno = EINVAL; @@ -812,14 +827,24 @@ struct sysfs_attribute *sysfs_get_directory_attribute attr = (struct sysfs_attribute *)dlist_find_custom (dir->attributes, attrname, dir_attribute_name_equal); if (attr != NULL) { - if ((sysfs_read_attribute(attr)) != 0) { - dprintf("Attribute at %s no longer exists?\n", - attr->path); - return NULL; - } else + /* + * don't read here since we would have read the attribute in + * in the routine that called this routine + */ + return attr; + } else { + memset(new_path, 0, SYSFS_PATH_MAX); + strcpy(new_path, dir->path); + strcat(new_path, "/"); + strcat(new_path, attrname); + if ((sysfs_path_is_file(new_path)) == 0) { + if ((add_attribute(dir, new_path)) == 0) { + attr = (struct sysfs_attribute *)dlist_find_custom + (dir->attributes, attrname, dir_attribute_name_equal); + } return attr; + } } - return NULL; } diff --git a/lib/sysfs_driver.c b/lib/sysfs_driver.c index b243fc7..f2145e0 100644 --- a/lib/sysfs_driver.c +++ b/lib/sysfs_driver.c @@ -154,6 +154,11 @@ struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) return NULL; } } else { + if ((sysfs_path_is_dir(driver->path)) != 0) { + dprintf("Driver at %s no longer exists\n", + driver->path); + return NULL; + } if ((sysfs_refresh_attributes (driver->directory->attributes)) != 0) { dprintf("Error refreshing driver attributes\n"); diff --git a/lib/sysfs_utils.c b/lib/sysfs_utils.c index 7b71639..dd424f1 100644 --- a/lib/sysfs_utils.c +++ b/lib/sysfs_utils.c @@ -377,3 +377,26 @@ int sysfs_path_is_link(const unsigned char *path) return 1; } + +/** + * sysfs_path_is_file: Check if the path supplied points to a file + * @path: path to validate + * Returns 0 if path points to file, 1 otherwise + */ +int sysfs_path_is_file(const unsigned char *path) +{ + struct stat astats; + + if (path == NULL) { + errno = EINVAL; + return 1; + } + if ((lstat(path, &astats)) != 0) { + dprintf("stat() failed\n"); + return 1; + } + if (S_ISREG(astats.st_mode)) + return 0; + + return 1; +} -- cgit v1.2.1