"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "sysfs.c" between
mdadm-4.1.tar.gz and mdadm-4.2.tar.gz

About: mdadm is a tool for creating, managing and monitoring device arrays using the "md" driver in Linux, also known as Software RAID arrays.

sysfs.c  (mdadm-4.1):sysfs.c  (mdadm-4.2)
skipping to change at line 29 skipping to change at line 29
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Author: Neil Brown * Author: Neil Brown
* Email: <neilb@suse.de> * Email: <neilb@suse.de>
*/ */
#include "mdadm.h" #include "mdadm.h"
#include <dirent.h> #include <dirent.h>
#include <ctype.h> #include <ctype.h>
#include "dlink.h"
#define MAX_SYSFS_PATH_LEN 120 #define MAX_SYSFS_PATH_LEN 120
struct dev_sysfs_rule {
struct dev_sysfs_rule *next;
char *devname;
int uuid[4];
int uuid_set;
struct sysfs_entry {
struct sysfs_entry *next;
char *name;
char *value;
} *entry;
};
int load_sys(char *path, char *buf, int len) int load_sys(char *path, char *buf, int len)
{ {
int fd = open(path, O_RDONLY); int fd = open(path, O_RDONLY);
int n; int n;
if (fd < 0) if (fd < 0)
return -1; return -1;
n = read(fd, buf, len); n = read(fd, buf, len);
close(fd); close(fd);
if (n <0 || n >= len) if (n <0 || n >= len)
return -1; return -1;
skipping to change at line 316 skipping to change at line 329
strcpy(dev->sys_name, de->d_name); strcpy(dev->sys_name, de->d_name);
dev->disk.raid_disk = strtoul(buf, &ep, 10); dev->disk.raid_disk = strtoul(buf, &ep, 10);
if (*ep) dev->disk.raid_disk = -1; if (*ep) dev->disk.raid_disk = -1;
sra->array.nr_disks++; sra->array.nr_disks++;
strcpy(dbase, "block/dev"); strcpy(dbase, "block/dev");
if (load_sys(fname, buf, sizeof(buf))) { if (load_sys(fname, buf, sizeof(buf))) {
/* assume this is a stale reference to a hot /* assume this is a stale reference to a hot
* removed device * removed device
*/ */
free(dev); if (!(options & GET_DEVS_ALL)) {
continue; free(dev);
continue;
}
} else {
sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor);
} }
sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor);
/* special case check for block devices that can go 'offline' */ if (!(options & GET_DEVS_ALL)) {
strcpy(dbase, "block/device/state"); /* special case check for block devices that can go 'offl
if (load_sys(fname, buf, sizeof(buf)) == 0 && ine' */
strncmp(buf, "offline", 7) == 0) { strcpy(dbase, "block/device/state");
free(dev); if (load_sys(fname, buf, sizeof(buf)) == 0 &&
continue; strncmp(buf, "offline", 7) == 0) {
free(dev);
continue;
}
} }
/* finally add this disk to the array */ /* finally add this disk to the array */
*devp = dev; *devp = dev;
devp = & dev->next; devp = & dev->next;
dev->next = NULL; dev->next = NULL;
if (options & GET_OFFSET) { if (options & GET_OFFSET) {
strcpy(dbase, "offset"); strcpy(dbase, "offset");
if (load_sys(fname, buf, sizeof(buf))) if (load_sys(fname, buf, sizeof(buf)))
skipping to change at line 997 skipping to change at line 1015
tv.tv_usec = 0; tv.tv_usec = 0;
} }
n = select(fd+1, NULL, NULL, &fds, &tv); n = select(fd+1, NULL, NULL, &fds, &tv);
gettimeofday(&end, NULL); gettimeofday(&end, NULL);
end.tv_sec -= start.tv_sec; end.tv_sec -= start.tv_sec;
*msec -= (end.tv_sec * 1000 + end.tv_usec/1000 *msec -= (end.tv_sec * 1000 + end.tv_usec/1000
- start.tv_usec/1000) + 1; - start.tv_usec/1000) + 1;
} }
return n; return n;
} }
int sysfs_rules_apply_check(const struct mdinfo *sra,
const struct sysfs_entry *ent)
{
/* Check whether parameter is regular file,
* exists and is under specified directory.
*/
char fname[MAX_SYSFS_PATH_LEN];
char dname[MAX_SYSFS_PATH_LEN];
char resolved_path[PATH_MAX];
char resolved_dir[PATH_MAX];
int result;
if (sra == NULL || ent == NULL)
return -1;
result = snprintf(dname, MAX_SYSFS_PATH_LEN,
"/sys/block/%s/md/", sra->sys_name);
if (result < 0 || result >= MAX_SYSFS_PATH_LEN)
return -1;
result = snprintf(fname, MAX_SYSFS_PATH_LEN,
"%s/%s", dname, ent->name);
if (result < 0 || result >= MAX_SYSFS_PATH_LEN)
return -1;
if (realpath(fname, resolved_path) == NULL ||
realpath(dname, resolved_dir) == NULL)
return -1;
if (strncmp(resolved_dir, resolved_path,
strnlen(resolved_dir, PATH_MAX)) != 0)
return -1;
return 0;
}
static struct dev_sysfs_rule *sysfs_rules;
void sysfs_rules_apply(char *devnm, struct mdinfo *dev)
{
struct dev_sysfs_rule *rules = sysfs_rules;
while (rules) {
struct sysfs_entry *ent = rules->entry;
int match = 0;
if (!rules->uuid_set) {
if (rules->devname)
match = strcmp(devnm, rules->devname) == 0;
} else {
match = memcmp(dev->uuid, rules->uuid,
sizeof(int[4])) == 0;
}
while (match && ent) {
if (sysfs_rules_apply_check(dev, ent) < 0)
pr_err("SYSFS: failed to write '%s' to '%s'\n",
ent->value, ent->name);
else
sysfs_set_str(dev, NULL, ent->name, ent->value);
ent = ent->next;
}
rules = rules->next;
}
}
static void sysfs_rule_free(struct dev_sysfs_rule *rule)
{
struct sysfs_entry *entry;
while (rule) {
struct dev_sysfs_rule *tmp = rule->next;
entry = rule->entry;
while (entry) {
struct sysfs_entry *tmp = entry->next;
free(entry->name);
free(entry->value);
free(entry);
entry = tmp;
}
if (rule->devname)
free(rule->devname);
free(rule);
rule = tmp;
}
}
void sysfsline(char *line)
{
struct dev_sysfs_rule *sr;
char *w;
sr = xcalloc(1, sizeof(*sr));
for (w = dl_next(line); w != line ; w = dl_next(w)) {
if (strncasecmp(w, "name=", 5) == 0) {
char *devname = w + 5;
if (strncmp(devname, "/dev/md/", 8) == 0) {
if (sr->devname)
pr_err("Only give one device per SYSFS li
ne: %s\n",
devname);
else
sr->devname = xstrdup(devname);
} else {
pr_err("%s is an invalid name for an md device -
ignored.\n",
devname);
}
} else if (strncasecmp(w, "uuid=", 5) == 0) {
char *uuid = w + 5;
if (sr->uuid_set) {
pr_err("Only give one uuid per SYSFS line: %s\n",
uuid);
} else {
if (parse_uuid(w + 5, sr->uuid) &&
memcmp(sr->uuid, uuid_zero,
sizeof(int[4])) != 0)
sr->uuid_set = 1;
else
pr_err("Invalid uuid: %s\n", uuid);
}
} else {
struct sysfs_entry *prop;
char *sep = strchr(w, '=');
if (sep == NULL || *(sep + 1) == 0) {
pr_err("Cannot parse \"%s\" - ignoring.\n", w);
continue;
}
prop = xmalloc(sizeof(*prop));
prop->value = xstrdup(sep + 1);
*sep = 0;
prop->name = xstrdup(w);
prop->next = sr->entry;
sr->entry = prop;
}
}
if (!sr->devname && !sr->uuid_set) {
pr_err("Device name not found in sysfs config entry - ignoring.\n
");
sysfs_rule_free(sr);
return;
}
sr->next = sysfs_rules;
sysfs_rules = sr;
}
 End of changes. 6 change blocks. 
9 lines changed or deleted 28 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)