]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - sysfs.c
test: return correct error status for mdadm
[thirdparty/mdadm.git] / sysfs.c
diff --git a/sysfs.c b/sysfs.c
index 7f94d5567d95ce2ae036a8595f3104d5b3eb867c..d4a1e495d5256a0abeef19d1256bb83d069dd922 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -81,6 +81,7 @@ int sysfs_open(int devnum, char *devname, char *attr)
 
 void sysfs_init(struct mdinfo *mdi, int fd, int devnum)
 {
+       mdi->sys_name[0] = 0;
        if (fd >= 0) {
                mdu_version_t vers;
                if (ioctl(fd, RAID_VERSION, &vers) != 0)
@@ -118,6 +119,10 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                return sra;
        memset(sra, 0, sizeof(*sra));
        sysfs_init(sra, fd, devnum);
+       if (sra->sys_name[0] == 0) {
+               free(sra);
+               return NULL;
+       }
 
        sprintf(fname, "/sys/block/%s/md/", sra->sys_name);
        base = fname + strlen(fname);
@@ -267,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))
@@ -445,6 +466,25 @@ int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
        return 0;
 }
 
+int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
+                      char *name, char *val, int size)
+{
+       char fname[50];
+       int n;
+       int fd;
+       sprintf(fname, "/sys/block/%s/md/%s/%s",
+               sra->sys_name, dev?dev->sys_name:"", name);
+       fd = open(fname, O_RDONLY);
+       if (fd < 0)
+               return -1;
+       n = read(fd, val, size);
+       close(fd);
+       if (n <= 0)
+               return -1;
+       val[n] = 0;
+       return n;
+}
+
 int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms)
 {
        unsigned long sec;