X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=sysfs.c;h=d28e21a251eba7851a27c6ba96a97f9795e10259;hp=13558c5fd0516e1c4a19f355a77f5df62b57e924;hb=36138e4e4b6c3f9db21e65ac8962bf22d4b2c274;hpb=4bffc964b9e4c91877d1a863b06cab4748732b15 diff --git a/sysfs.c b/sysfs.c index 13558c5f..d28e21a2 100644 --- a/sysfs.c +++ b/sysfs.c @@ -27,15 +27,15 @@ #include #include -int load_sys(char *path, char *buf) +int load_sys(char *path, char *buf, int len) { int fd = open(path, O_RDONLY); int n; if (fd < 0) return -1; - n = read(fd, buf, 1024); + n = read(fd, buf, len); close(fd); - if (n <0 || n >= 1024) + if (n <0 || n >= len) return -1; buf[n] = 0; if (n && buf[n-1] == '\n') @@ -74,6 +74,12 @@ int sysfs_open(char *devnm, char *devname, char *attr) return fd; } +void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid) +{ + snprintf(mdi->sys_name, + sizeof(mdi->sys_name), "dev-%s", devid2kname(devid)); +} + void sysfs_init(struct mdinfo *mdi, int fd, char *devnm) { mdi->sys_name[0] = 0; @@ -112,7 +118,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) sra->devs = NULL; if (options & GET_VERSION) { strcpy(base, "metadata_version"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; if (strncmp(buf, "none", 4) == 0) { sra->array.major_version = @@ -131,31 +137,31 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) } if (options & GET_LEVEL) { strcpy(base, "level"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; sra->array.level = map_name(pers, buf); } if (options & GET_LAYOUT) { strcpy(base, "layout"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; sra->array.layout = strtoul(buf, NULL, 0); } if (options & GET_DISKS) { strcpy(base, "raid_disks"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; sra->array.raid_disks = strtoul(buf, NULL, 0); } if (options & GET_DEGRADED) { strcpy(base, "degraded"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; sra->array.failed_disks = strtoul(buf, NULL, 0); } if (options & GET_COMPONENT) { strcpy(base, "component_size"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; sra->component_size = strtoull(buf, NULL, 0); /* sysfs reports "K", but we want sectors */ @@ -163,13 +169,13 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) } if (options & GET_CHUNK) { strcpy(base, "chunk_size"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; sra->array.chunk_size = strtoul(buf, NULL, 0); } if (options & GET_CACHE) { strcpy(base, "stripe_cache_size"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) /* Probably level doesn't support it */ sra->cache_size = 0; else @@ -177,7 +183,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) } if (options & GET_MISMATCH) { strcpy(base, "mismatch_cnt"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; sra->mismatch_cnt = strtoul(buf, NULL, 0); } @@ -189,7 +195,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) size_t len; strcpy(base, "safe_mode_delay"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; /* remove a period, and count digits after it */ @@ -212,7 +218,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) } if (options & GET_BITMAP_LOCATION) { strcpy(base, "bitmap/location"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; if (strncmp(buf, "file", 4) == 0) sra->bitmap_offset = 1; @@ -224,6 +230,14 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) goto abort; } + if (options & GET_ARRAY_STATE) { + strcpy(base, "array_state"); + if (load_sys(fname, sra->sysfs_array_state, + sizeof(sra->sysfs_array_state))) + goto abort; + } else + sra->sysfs_array_state[0] = 0; + if (! (options & GET_DEVS)) return sra; @@ -249,7 +263,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) /* Always get slot, major, minor */ strcpy(dbase, "slot"); - if (load_sys(fname, buf)) { + if (load_sys(fname, buf, sizeof(buf))) { /* hmm... unable to read 'slot' maybe the device * is going away? */ @@ -274,7 +288,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) if (*ep) dev->disk.raid_disk = -1; strcpy(dbase, "block/dev"); - if (load_sys(fname, buf)) { + if (load_sys(fname, buf, sizeof(buf))) { /* assume this is a stale reference to a hot * removed device */ @@ -286,7 +300,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) /* special case check for block devices that can go 'offline' */ strcpy(dbase, "block/device/state"); - if (load_sys(fname, buf) == 0 && + if (load_sys(fname, buf, sizeof(buf)) == 0 && strncmp(buf, "offline", 7) == 0) { free(dev); continue; @@ -299,25 +313,25 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) if (options & GET_OFFSET) { strcpy(dbase, "offset"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; dev->data_offset = strtoull(buf, NULL, 0); strcpy(dbase, "new_offset"); - if (load_sys(fname, buf) == 0) + if (load_sys(fname, buf, sizeof(buf)) == 0) dev->new_data_offset = strtoull(buf, NULL, 0); else dev->new_data_offset = dev->data_offset; } if (options & GET_SIZE) { strcpy(dbase, "size"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; dev->component_size = strtoull(buf, NULL, 0) * 2; } if (options & GET_STATE) { dev->disk.state = 0; strcpy(dbase, "state"); - if (load_sys(fname, buf)) + if (load_sys(fname, buf, sizeof(buf))) goto abort; if (strstr(buf, "in_sync")) dev->disk.state |= (1<errors = strtoul(buf, NULL, 0); } @@ -380,7 +394,8 @@ unsigned long long get_component_size(int fd) struct stat stb; char fname[50]; int n; - if (fstat(fd, &stb)) return 0; + if (fstat(fd, &stb)) + return 0; if (major(stb.st_rdev) != (unsigned)get_mdp_major()) sprintf(fname, "/sys/block/md%d/md/component_size", (int)minor(stb.st_rdev)); @@ -413,7 +428,7 @@ int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev, n = write(fd, val, strlen(val)); close(fd); if (n != strlen(val)) { - dprintf(Name ": failed to write '%s' to '%s' (%s)\n", + dprintf("failed to write '%s' to '%s' (%s)\n", val, fname, strerror(errno)); return -1; } @@ -450,7 +465,7 @@ int sysfs_uevent(struct mdinfo *sra, char *event) n = write(fd, event, strlen(event)); close(fd); if (n != (int)strlen(event)) { - dprintf(Name ": failed to write '%s' to '%s' (%s)\n", + dprintf("failed to write '%s' to '%s' (%s)\n", event, fname, strerror(errno)); return -1; } @@ -490,7 +505,7 @@ int sysfs_fd_get_ll(int fd, unsigned long long *val) lseek(fd, 0, 0); n = read(fd, buf, sizeof(buf)); - if (n <= 0) + if (n <= 0 || n == sizeof(buf)) return -2; buf[n] = 0; *val = strtoull(buf, &ep, 0); @@ -526,7 +541,7 @@ int sysfs_fd_get_two(int fd, unsigned long long *v1, unsigned long long *v2) lseek(fd, 0, 0); n = read(fd, buf, sizeof(buf)); - if (n <= 0) + if (n <= 0 || n == sizeof(buf)) return -2; buf[n] = 0; *v1 = strtoull(buf, &ep, 0); @@ -562,7 +577,7 @@ int sysfs_fd_get_str(int fd, char *val, int size) lseek(fd, 0, 0); n = read(fd, val, size); - if (n <= 0) + if (n <= 0 || n == size) return -1; val[n] = 0; return n; @@ -623,8 +638,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) if ((vers % 100) < 2 || sysfs_set_str(info, NULL, "metadata_version", ver) < 0) { - pr_err("This kernel does not " - "support external metadata.\n"); + pr_err("This kernel does not support external metadata.\n"); return 1; } } @@ -644,9 +658,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) rc = sysfs_set_num(info, NULL, "array_size", info->custom_array_size/2); if (rc && errno == ENOENT) { - pr_err("This kernel does not " - "have the md/array_size attribute, " - "the array may be larger than expected\n"); + pr_err("This kernel does not have the md/array_size attribute, the array may be larger than expected\n"); rc = 0; } rv |= rc; @@ -682,7 +694,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume) return rv; memset(nm, 0, sizeof(nm)); - dname = devid2devnm(makedev(sd->disk.major, sd->disk.minor)); + dname = devid2kname(makedev(sd->disk.major, sd->disk.minor)); strcpy(sd->sys_name, "dev-"); strcpy(sd->sys_name+4, dname); @@ -718,7 +730,7 @@ int sysfs_disk_to_sg(int fd) struct stat st; char path[256]; char sg_path[256]; - char sg_major_minor[8]; + char sg_major_minor[10]; char *c; DIR *dir; struct dirent *de; @@ -753,7 +765,7 @@ int sysfs_disk_to_sg(int fd) rv = read(fd, sg_major_minor, sizeof(sg_major_minor)); close(fd); - if (rv < 0) + if (rv < 0 || rv == sizeof(sg_major_minor)) return -1; else sg_major_minor[rv - 1] = '\0';