]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - sysfs.c
RebuildMap: handle missing disks
[thirdparty/mdadm.git] / sysfs.c
diff --git a/sysfs.c b/sysfs.c
index b9fd3da95d37a80bb303583cf4bf0eb78ebf34e2..48d1f54264818097c22ba8322d03e4703e2c19dd 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -272,18 +272,34 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                        }
                        
                }
-               dev->next = sra->devs;
-               sra->devs = dev;
-
                strcpy(dev->sys_name, de->d_name);
                dev->disk.raid_disk = strtoul(buf, &ep, 10);
                if (*ep) dev->disk.raid_disk = -1;
 
                strcpy(dbase, "block/dev");
-               if (load_sys(fname, buf))
-                       goto abort;
+               if (load_sys(fname, buf)) {
+                       free(dev);
+                       if (options & SKIP_GONE_DEVS)
+                               continue;
+                       else
+                               goto abort;
+               }
                sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor);
 
+               /* special case check for block devices that can go 'offline' */
+               if (options & SKIP_GONE_DEVS) {
+                       strcpy(dbase, "block/device/state");
+                       if (load_sys(fname, buf) == 0 &&
+                           strncmp(buf, "offline", 7) == 0) {
+                               free(dev);
+                               continue;
+                       }
+               }
+
+               /* finally add this disk to the array */
+               dev->next = sra->devs;
+               sra->devs = dev;
+
                if (options & GET_OFFSET) {
                        strcpy(dbase, "offset");
                        if (load_sys(fname, buf))
@@ -490,6 +506,20 @@ int sysfs_set_array(struct mdinfo *info, int vers)
        rv |= sysfs_set_num(info, NULL, "chunk_size", info->array.chunk_size);
        rv |= sysfs_set_num(info, NULL, "layout", info->array.layout);
        rv |= sysfs_set_num(info, NULL, "component_size", info->component_size/2);
+       if (info->custom_array_size) {
+               int rc;
+
+               rc = sysfs_set_num(info, NULL, "array_size",
+                                  info->custom_array_size/2);
+               if (rc && errno == ENOENT) {
+                       fprintf(stderr, Name ": This kernel does not "
+                               "have the md/array_size attribute, "
+                               "the array may be larger than expected\n");
+                       rc = 0;
+               }
+               rv |= rc;
+       }
+
        if (info->array.level > 0)
                rv |= sysfs_set_num(info, NULL, "resync_start", info->resync_start);
        return rv;