Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
multipath-tools
multipath-tools-implement-sysfs-attr-set-value
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File multipath-tools-implement-sysfs-attr-set-value of Package multipath-tools
From e3354354518377b34fa3b501c11a62b61a54b0d4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke <hare@suse.de> Date: Tue, 13 Jan 2009 15:34:55 +0100 Subject: [PATCH] Implement sysfs_attr_set_value() Complement to sysfs_attr_get_value(). We might want to modify some sysfs values from multipathing. References: bnc#464155 Signed-off-by: Hannes Reinecke <hare@suse.de> --- libmultipath/sysfs.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ libmultipath/sysfs.h | 2 + 2 files changed, 102 insertions(+), 0 deletions(-) diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c index e00a101..4a472ae 100644 --- a/libmultipath/sysfs.c +++ b/libmultipath/sysfs.c @@ -461,6 +461,106 @@ out: return attr && attr->value && strlen(attr->value) ? attr->value : NULL; } +int sysfs_attr_set_value(const char *devpath, const char *attr_name, + char *value, int value_len) +{ + char path_full[PATH_SIZE]; + const char *path; + struct sysfs_attr *attr_loop; + struct sysfs_attr *attr = NULL; + struct stat statbuf; + int fd; + ssize_t size = 0; + size_t sysfs_len; + + dbg("open '%s'/'%s'", devpath, attr_name); + sysfs_len = strlcpy(path_full, sysfs_path, sizeof(path_full)); + if(sysfs_len >= sizeof(path_full)) + sysfs_len = sizeof(path_full) - 1; + path = &path_full[sysfs_len]; + strlcat(path_full, devpath, sizeof(path_full)); + strlcat(path_full, "/", sizeof(path_full)); + strlcat(path_full, attr_name, sizeof(path_full)); + + /* look for attribute in cache */ + list_for_each_entry(attr_loop, &attr_list, node) { + if (strcmp(attr_loop->path, path) == 0) { + dbg("found in cache '%s'", attr_loop->path); + attr = attr_loop; + } + } + if (!attr) { + /* store attribute in cache */ + dbg("new uncached attribute '%s'", path_full); + attr = malloc(sizeof(struct sysfs_attr)); + if (attr == NULL) + return -1; + memset(attr, 0x00, sizeof(struct sysfs_attr)); + strlcpy(attr->path, path, sizeof(attr->path)); + dbg("add to cache '%s'", path_full); + list_add(&attr->node, &attr_list); + } else { + /* clear old value */ + if(attr->value) + memset(attr->value, 0x00, sizeof(attr->value)); + } + + if (lstat(path_full, &statbuf) != 0) { + dbg("stat '%s' failed: %s", path_full, strerror(errno)); + goto out; + } + + if (S_ISLNK(statbuf.st_mode)) { + /* links return the last element of the target path */ + char link_target[PATH_SIZE]; + int len; + const char *pos; + + len = readlink(path_full, link_target, sizeof(link_target)); + if (len > 0) { + link_target[len] = '\0'; + pos = strrchr(link_target, '/'); + if (pos != NULL) { + dbg("cache '%s' with link value '%s'", + path_full, value); + strlcpy(attr->value_local, &pos[1], + sizeof(attr->value_local)); + attr->value = attr->value_local; + } + } + goto out; + } + + /* skip directories */ + if (S_ISDIR(statbuf.st_mode)) + goto out; + + /* skip non-readable files */ + if ((statbuf.st_mode & S_IRUSR) == 0) + goto out; + + /* write attribute value */ + fd = open(path_full, O_WRONLY); + if (fd < 0) { + dbg("attribute '%s' can not be opened: %s", + path_full, strerror(errno)); + goto out; + } + size = write(fd, value, value_len); + close(fd); + if (size < 0) + goto out; + + /* successfully wrote new value, store it */ + remove_trailing_chars(value, '\n'); + dbg("cache '%s' with attribute value '%s'", path_full, value); + strlcpy(attr->value_local, value, sizeof(attr->value_local)); + attr->value = attr->value_local; + +out: + return size; +} + int sysfs_lookup_devpath_by_subsys_id(char *devpath_full, size_t len, const char *subsystem, const char *id) { diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h index 620962c..ac76acf 100644 --- a/libmultipath/sysfs.h +++ b/libmultipath/sysfs.h @@ -20,6 +20,8 @@ struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev); struct sysfs_device *sysfs_device_get_parent_with_subsystem(struct sysfs_device *dev, const char *subsystem); void sysfs_device_put(struct sysfs_device *dev); char *sysfs_attr_get_value(const char *devpath, const char *attr_name); +int sysfs_attr_set_value(const char *devpath, const char *attr_name, + char *value, int value_len); int sysfs_resolve_link(char *path, size_t size); int sysfs_get_size (struct sysfs_device * dev, unsigned long long * size); -- 1.5.3.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor