dcavalca / rpms / mdadm

Forked from rpms/mdadm 3 years ago
Clone

Blame SOURCES/0076-Assemble.c-respect-force-flag.patch

8e8941
From 7b99edab2834d5d08ef774b4cff784caaa1a186f Mon Sep 17 00:00:00 2001
8e8941
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
8e8941
Date: Tue, 5 May 2020 12:17:17 +0200
8e8941
Subject: [RHEL7.9 PATCH 76/77] Assemble.c: respect force flag.
8e8941
8e8941
If the array is dirty handler will set resync_start to 0 to inform kernel
8e8941
that resync is needed. RWH affects only raid456 module, for other
8e8941
levels array will be started even array is degraded and resync cannot be
8e8941
performed.
8e8941
8e8941
Force is really meaningful for raid456. If array is degraded and resync
8e8941
is requested, kernel will reject an attempt to start the array. To
8e8941
respect force, it has to be marked as clean (this will be done for each
8e8941
array without PPL) and remove the resync request (only for raid 456).
8e8941
Data corruption may occur so proper warning is added.
8e8941
8e8941
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
8e8941
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
8e8941
---
8e8941
 Assemble.c | 51 ++++++++++++++++++++++++++++++++++++++-------------
8e8941
 1 file changed, 38 insertions(+), 13 deletions(-)
8e8941
8e8941
diff --git a/Assemble.c b/Assemble.c
8e8941
index 2ed5884..3e5d4e6 100644
8e8941
--- a/Assemble.c
8e8941
+++ b/Assemble.c
8e8941
@@ -2030,6 +2030,15 @@ int assemble_container_content(struct supertype *st, int mdfd,
8e8941
 			free(avail);
8e8941
 			return err;
8e8941
 		}
8e8941
+	} else if (c->force) {
8e8941
+		/* Set the array as 'clean' so that we can proceed with starting
8e8941
+		 * it even if we don't have all devices. Mdmon doesn't care
8e8941
+		 * if the dirty flag is set in metadata, it will start managing
8e8941
+		 * it anyway.
8e8941
+		 * This is really important for raid456 (RWH case), other levels
8e8941
+		 * are started anyway.
8e8941
+		 */
8e8941
+		content->array.state |= 1;
8e8941
 	}
8e8941
 
8e8941
 	if (enough(content->array.level, content->array.raid_disks,
8e8941
@@ -2049,20 +2058,36 @@ int assemble_container_content(struct supertype *st, int mdfd,
8e8941
 	}
8e8941
 	free(avail);
8e8941
 
8e8941
-	if (c->runstop <= 0 &&
8e8941
-	    (working + preexist + expansion) <
8e8941
-	    content->array.working_disks) {
8e8941
-		if (c->export && result)
8e8941
-			*result |= INCR_UNSAFE;
8e8941
-		else if (c->verbose >= 0) {
8e8941
-			pr_err("%s assembled with %d device%s",
8e8941
-			       chosen_name, preexist + working,
8e8941
-			       preexist + working == 1 ? "":"s");
8e8941
-			if (preexist)
8e8941
-				fprintf(stderr, " (%d new)", working);
8e8941
-			fprintf(stderr, " but not safe to start\n");
8e8941
+	if ((working + preexist + expansion) < content->array.working_disks) {
8e8941
+		if (c->runstop <= 0) {
8e8941
+			if (c->export && result)
8e8941
+				*result |= INCR_UNSAFE;
8e8941
+			else if (c->verbose >= 0) {
8e8941
+				pr_err("%s assembled with %d device%s",
8e8941
+					chosen_name, preexist + working,
8e8941
+					preexist + working == 1 ? "":"s");
8e8941
+				if (preexist)
8e8941
+					fprintf(stderr, " (%d new)", working);
8e8941
+				fprintf(stderr, " but not safe to start\n");
8e8941
+				if (c->force)
8e8941
+					pr_err("Consider --run to start array as degraded.\n");
8e8941
+			}
8e8941
+			return 1;
8e8941
+		} else if (content->array.level >= 4 &&
8e8941
+			   content->array.level <= 6 &&
8e8941
+			   content->resync_start != MaxSector &&
8e8941
+			   c->force) {
8e8941
+			/* Don't inform the kernel that the array is not
8e8941
+			 * clean and requires resync.
8e8941
+			 */
8e8941
+			content->resync_start = MaxSector;
8e8941
+			err = sysfs_set_num(content, NULL, "resync_start",
8e8941
+					    MaxSector);
8e8941
+			if (err)
8e8941
+				return 1;
8e8941
+			pr_err("%s array state forced to clean. It may cause data corruption.\n",
8e8941
+				chosen_name);
8e8941
 		}
8e8941
-		return 1;
8e8941
 	}
8e8941
 
8e8941
 
8e8941
-- 
8e8941
2.7.5
8e8941