summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormananth <mananth>2003-12-10 08:53:21 +0000
committermananth <mananth>2003-12-10 08:53:21 +0000
commit786fe571f1d3470150d5f3c57a751c0954d40198 (patch)
tree53406215b7cf553eab9708dc38e089705de7039b
parentfcaccb01f807270bf8ef8a1b8ca436288148e4db (diff)
downloadsysfsutils-786fe571f1d3470150d5f3c57a751c0954d40198.tar.gz
Changes to dynamically read/refresh attributes
-rw-r--r--ChangeLog4
-rw-r--r--include/libsysfs.h2
-rw-r--r--lib/sysfs_bus.c5
-rw-r--r--lib/sysfs_class.c13
-rw-r--r--lib/sysfs_device.c18
-rw-r--r--lib/sysfs_dir.c39
-rw-r--r--lib/sysfs_driver.c5
-rw-r--r--lib/sysfs_utils.c23
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 <ananth@in.ibm.com>
+ * Added more optimization changes
+ * Added code to add and refresh attributes dynamically
+
12/08/2003 - Daniel Stekloff <dsteklof@us.ibm.com>
* 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;
+}