X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=sysfs.c;h=e47f5e483cdd9423a9e8dc899270985778958f81;hb=07c45a1871df0a70beb8da80d11601d33c7a5de2;hp=2a91ba0a90cff185f8b29a36d721c974ea40052e;hpb=2432ce9b3235f34d00ef6c28ef6b624a32b85530;p=thirdparty%2Fmdadm.git diff --git a/sysfs.c b/sysfs.c index 2a91ba0a..e47f5e48 100644 --- a/sysfs.c +++ b/sysfs.c @@ -84,18 +84,30 @@ void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid) sizeof(mdi->sys_name), "dev-%s", devid2kname(devid)); } -void sysfs_init(struct mdinfo *mdi, int fd, char *devnm) +int sysfs_init(struct mdinfo *mdi, int fd, char *devnm) { + struct stat stb; + char fname[MAX_SYSFS_PATH_LEN]; + int retval = -ENODEV; + mdi->sys_name[0] = 0; - if (fd >= 0) { - mdu_version_t vers; - if (ioctl(fd, RAID_VERSION, &vers) != 0) - return; + if (fd >= 0) devnm = fd2devnm(fd); - } + if (devnm == NULL) - return; + goto out; + + snprintf(fname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md", devnm); + + if (stat(fname, &stb)) + goto out; + if (!S_ISDIR(stb.st_mode)) + goto out; strcpy(mdi->sys_name, devnm); + + retval = 0; +out: + return retval; } struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) @@ -110,8 +122,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) struct dirent *de; sra = xcalloc(1, sizeof(*sra)); - sysfs_init(sra, fd, devnm); - if (sra->sys_name[0] == 0) { + if (sysfs_init(sra, fd, devnm)) { free(sra); return NULL; } @@ -236,21 +247,18 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) if (options & GET_ARRAY_STATE) { strcpy(base, "array_state"); - if (load_sys(fname, sra->sysfs_array_state, - sizeof(sra->sysfs_array_state))) + if (load_sys(fname, buf, sizeof(buf))) goto abort; - } else - sra->sysfs_array_state[0] = 0; + sra->array_state = map_name(sysfs_array_states, buf); + } if (options & GET_CONSISTENCY_POLICY) { strcpy(base, "consistency_policy"); - if (load_sys(fname, buf, sizeof(buf))) { + if (load_sys(fname, buf, sizeof(buf))) sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN; - } else { - sra->consistency_policy = map_name(consistency_policies, buf); - if (sra->consistency_policy == UnSet) - sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN; - } + else + sra->consistency_policy = map_name(consistency_policies, + buf); } if (! (options & GET_DEVS)) @@ -262,6 +270,9 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) if (!dir) goto abort; sra->array.spare_disks = 0; + sra->array.active_disks = 0; + sra->array.failed_disks = 0; + sra->array.working_disks = 0; devp = &sra->devs; sra->devs = NULL; @@ -348,12 +359,18 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) strcpy(dbase, "state"); if (load_sys(fname, buf, sizeof(buf))) goto abort; - if (strstr(buf, "in_sync")) - dev->disk.state |= (1<disk.state |= (1<disk.state == 0) - sra->array.spare_disks++; + sra->array.failed_disks++; + } else { + sra->array.working_disks++; + if (strstr(buf, "in_sync")) { + dev->disk.state |= (1<array.active_disks++; + } + if (dev->disk.state == 0) + sra->array.spare_disks++; + } } if (options & GET_ERROR) { strcpy(buf, "errors");