#include <dirent.h>
#include <ctype.h>
-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')
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;
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 =
}
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 */
}
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
}
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);
}
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 */
}
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;
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;
/* 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?
*/
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
*/
/* 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;
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<<MD_DISK_SYNC);
}
if (options & GET_ERROR) {
strcpy(buf, "errors");
- if (load_sys(fname, buf))
+ if (load_sys(fname, buf, sizeof(buf)))
goto abort;
dev->errors = strtoul(buf, NULL, 0);
}
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));
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;
}
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;
}
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);
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);
lseek(fd, 0, 0);
n = read(fd, val, size);
- if (n <= 0)
+ if (n <= 0 || n == size)
return -1;
val[n] = 0;
return n;
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;
}
}
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;
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);
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;
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';