]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - sysfs.c
Remember to close directories when we are finished with them.
[thirdparty/mdadm.git] / sysfs.c
diff --git a/sysfs.c b/sysfs.c
index 8b5a6ff507c8b4165107b2ac5520fa7c1c9d1003..ea7d52f6c025be17a47a1774e3bd5bec843fe261 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -56,6 +56,29 @@ void sysfs_free(struct mdinfo *sra)
        }
 }
 
+int sysfs_open(int devnum, char *devname, char *attr)
+{
+       char fname[50];
+       char sys_name[16];
+       int fd;
+       if (devnum >= 0)
+               sprintf(sys_name, "md%d", devnum);
+       else
+               sprintf(sys_name, "md_d%d",
+                       -1-devnum);
+
+       sprintf(fname, "/sys/block/%s/md/", sys_name);
+       if (devname) {
+               strcat(fname, devname);
+               strcat(fname, "/");
+       }
+       strcat(fname, attr);
+       fd = open(fname, O_RDWR);
+       if (fd < 0 && errno == -EACCES)
+               fd = open(fname, O_RDONLY);
+       return fd;
+}
+
 struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
 {
        /* Longest possible name in sysfs, mounted at /sys, is
@@ -69,7 +92,7 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
        char *dbase;
        struct mdinfo *sra;
        struct mdinfo *dev;
-       DIR *dir;
+       DIR *dir = NULL;
        struct dirent *de;
 
        sra = malloc(sizeof(*sra));
@@ -128,6 +151,12 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                        goto abort;
                sra->array.layout = strtoul(buf, NULL, 0);
        }
+       if (options & GET_DISKS) {
+               strcpy(base, "raid_disks");
+               if (load_sys(fname, buf))
+                       goto abort;
+               sra->array.raid_disks = strtoul(buf, NULL, 0);
+       }
        if (options & GET_COMPONENT) {
                strcpy(base, "component_size");
                if (load_sys(fname, buf))
@@ -224,9 +253,12 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                        dev->errors = strtoul(buf, NULL, 0);
                }
        }
+       closedir(dir);
        return sra;
 
  abort:
+       if (dir)
+               closedir(dir);
        sysfs_free(sra);
        return NULL;
 }
@@ -325,11 +357,12 @@ int sysfs_set_array(struct mdinfo *sra,
        rv |= sysfs_set_num(sra, NULL, "chunk_size", info->array.chunk_size);
        rv |= sysfs_set_num(sra, NULL, "layout", info->array.layout);
        rv |= sysfs_set_num(sra, NULL, "component_size", info->component_size);
+       rv |= sysfs_set_num(sra, NULL, "resync_start", info->resync_start);
        sra->array = info->array;
        return rv;
 }
 
-int sysfs_add_disk(struct mdinfo *sra, int fd, struct mdinfo *sd)
+int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd)
 {
        char dv[100];
        char nm[100];