]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - sysfs.c
Merge branch 'master' into devel-3.2
[thirdparty/mdadm.git] / sysfs.c
diff --git a/sysfs.c b/sysfs.c
index 6e1d77b313daf28189cfa38e753c022f92bdfd71..7a0403d635b7f2067fa48ecb50e9ba326f5a8037 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -435,6 +435,17 @@ int sysfs_uevent(struct mdinfo *sra, char *event)
        return 0;
 }      
 
+int sysfs_attribute_available(struct mdinfo *sra, struct mdinfo *dev, char *name)
+{
+       char fname[50];
+       struct stat st;
+
+       sprintf(fname, "/sys/block/%s/md/%s/%s",
+               sra->sys_name, dev?dev->sys_name:"", name);
+
+       return stat(fname, &st) == 0;
+}
+
 int sysfs_get_fd(struct mdinfo *sra, struct mdinfo *dev,
                       char *name)
 {
@@ -603,7 +614,8 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume)
                         * yet, so just ignore status for now.
                         */
                        sysfs_set_str(sra, sd, "state", "insync");
-               rv |= sysfs_set_num(sra, sd, "slot", sd->disk.raid_disk);
+               if (sd->disk.raid_disk >= 0)
+                       rv |= sysfs_set_num(sra, sd, "slot", sd->disk.raid_disk);
                if (resume)
                        sysfs_set_num(sra, sd, "recovery_start", sd->recovery_start);
        }
@@ -789,6 +801,28 @@ int sysfs_unique_holder(int devnum, long rdev)
                return found;
 }
 
+int sysfs_freeze_array(struct mdinfo *sra)
+{
+       /* Try to freeze resync/rebuild on this array/container.
+        * Return -1 if the array is busy,
+        * return -2 container cannot be frozen,
+        * return 0 if this kernel doesn't support 'frozen'
+        * return 1 if it worked.
+        */
+       char buf[20];
+
+       if (!sysfs_attribute_available(sra, NULL, "sync_action"))
+               return 1; /* no sync_action == frozen */
+       if (sysfs_get_str(sra, NULL, "sync_action", buf, 20) <= 0)
+               return 0;
+       if (strcmp(buf, "idle\n") != 0 &&
+           strcmp(buf, "frozen\n") != 0)
+               return -1;
+       if (sysfs_set_str(sra, NULL, "sync_action", "frozen") < 0)
+               return 0;
+       return 1;
+}
+
 #ifndef MDASSEMBLE
 
 static char *clean_states[] = {