]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - sysfs.c
Grow: set component size prior to array size
[thirdparty/mdadm.git] / sysfs.c
diff --git a/sysfs.c b/sysfs.c
index 2a91ba0a90cff185f8b29a36d721c974ea40052e..e47f5e483cdd9423a9e8dc899270985778958f81 100644 (file)
--- 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<<MD_DISK_SYNC);
-                       if (strstr(buf, "faulty"))
+                       if (strstr(buf, "faulty")) {
                                dev->disk.state |= (1<<MD_DISK_FAULTY);
-                       if (dev->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<<MD_DISK_SYNC);
+                                       sra->array.active_disks++;
+                               }
+                               if (dev->disk.state == 0)
+                                       sra->array.spare_disks++;
+                       }
                }
                if (options & GET_ERROR) {
                        strcpy(buf, "errors");