File 0087-Manage-stop-don-t-stop-during-initial-critical-secti.patch of Package mdadm.5365

From e3e0d0a8436f3dc79b7c80d02724467de6c2f7ab Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Mon, 6 Jul 2015 13:45:39 +1000
Subject: [PATCH 121/359] Manage/stop: don't stop during initial critical
 section.
References: bsc#1081910

If the array is reshaping to more devices, then stopping
during that initial critical section is a bad idea.
So check for it and wait a bit.

Should probably handle final critical section of a reduction
too.
same-size reshape should be handled correctly already.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Coly Li <colyli@suse.de>

---
 Manage.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/Manage.c b/Manage.c
index 3930f4f..47faeed 100644
--- a/Manage.c
+++ b/Manage.c
@@ -344,9 +344,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
 	    sysfs_attribute_available(mdi, NULL, "reshape_direction") &&
 	    sysfs_get_str(mdi, NULL, "sync_action", buf, 20) > 0 &&
 	    strcmp(buf, "reshape\n") == 0 &&
-	    sysfs_get_two(mdi, NULL, "raid_disks", &rd1, &rd2) == 2 &&
-	    sysfs_set_str(mdi, NULL, "sync_action", "frozen") == 0) {
-		/* Array is frozen */
+	    sysfs_get_two(mdi, NULL, "raid_disks", &rd1, &rd2) == 2) {
 		unsigned long long position, curr;
 		unsigned long long chunk1, chunk2;
 		unsigned long long rddiv, chunkdiv;
@@ -357,12 +355,28 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
 		int delay;
 		int scfd;
 
+		delay = 40;
+		while (rd1 > rd2 && delay > 0 &&
+		       sysfs_get_ll(mdi, NULL, "sync_max", &old_sync_max) == 0) {
+			/* must be in the critical section - wait a bit */
+			delay -= 1;
+			usleep(100000);
+		}
+
+		if (sysfs_set_str(mdi, NULL, "sync_action", "frozen") != 0)
+			goto done;
+		/* Array is frozen */
+
 		rd1 -= mdi->array.level == 6 ? 2 : 1;
 		rd2 -= mdi->array.level == 6 ? 2 : 1;
 		sysfs_get_str(mdi, NULL, "reshape_direction", buf, sizeof(buf));
 		if (strncmp(buf, "back", 4) == 0)
 			backwards = 1;
-		sysfs_get_ll(mdi, NULL, "reshape_position", &position);
+		if (sysfs_get_ll(mdi, NULL, "reshape_position", &position) != 0) {
+			/* reshape must have finished now */
+			sysfs_set_str(mdi, NULL, "sync_action", "idle");
+			goto done;
+		}
 		sysfs_get_two(mdi, NULL, "chunk_size", &chunk1, &chunk2);
 		chunk1 /= 512;
 		chunk2 /= 512;
@@ -456,6 +470,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
 			close(scfd);
 
 	}
+done:
 
 	/* As we have an O_EXCL open, any use of the device
 	 * which blocks STOP_ARRAY is probably a transient use,
-- 
2.16.1

openSUSE Build Service is sponsored by