[PATCH 2/3] Assemble imsm spares in matching domain only

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 9aa8c183c10c121d663bcf0f715cf9c17daa048d Mon Sep 17 00:00:00 2001
From: Anna Czarnowska <anna.czarnowska@xxxxxxxxx>
Date: Thu, 23 Dec 2010 12:12:19 +0100
Subject: [PATCH 2/3] Assemble imsm spares in matching domain only
Cc: linux-raid@xxxxxxxxxxxxxxx, Williams, Dan J <dan.j.williams@xxxxxxxxx>, Ciechanowski, Ed <ed.ciechanowski@xxxxxxxxx>

Imsm spare will only be taken if it matches domain of
identified members of currently assembled array.

This implies that:
- spare with null domain will match first array assembled.
- if array has null domain then no spare will match

If we allow spares to set st they may block assembly of subarrays.
This is because in autossembly tmpdev->used=0 for a spare not matching
any array. If we find such spare before container and set st, the content
will not get assembled.

We allow uuid_zero match any uuid in assembly as unsuitable spares will
be rejected on domain check.

Signed-off-by: Anna Czarnowska <anna.czarnowska@xxxxxxxxx>
---
 Assemble.c |   44 +++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index ac489e8..4b8ab5c 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -78,7 +78,8 @@ static int ident_matches(struct mddev_ident *ident,
 {
 
 	if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) &&
-	    same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0) {
+	    same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0 &&
+	    memcmp(content->uuid, uuid_zero, sizeof(int[4]))) {
 		if (devname)
 			fprintf(stderr, Name ": %s has wrong uuid.\n",
 				devname);
@@ -231,7 +232,8 @@ int Assemble(struct supertype *st, char *mddev,
 	char *name = NULL;
 	int trustworthy;
 	char chosen_name[1024];
-
+	struct domainlist *domains = NULL;
+	
 	if (get_linux_version() < 2004000)
 		old_linux = 1;
 
@@ -350,6 +352,7 @@ int Assemble(struct supertype *st, char *mddev,
 			} else
 				found_container = 1;
 		} else {
+			pol = devnum_policy(stb.st_rdev);
 			if (!tst && (tst = guess_super(dfd)) == NULL) {
 				if (report_missmatch)
 					fprintf(stderr, Name ": no recogniseable superblock on %s\n",
@@ -366,7 +369,7 @@ int Assemble(struct supertype *st, char *mddev,
 						tst->ss->name, devname);
 				tmpdev->used = 2;
 			} else if (auto_assem && st == NULL &&
-				   !conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
+				   !conf_test_metadata(tst->ss->name, pol,
 						       tst->ss->match_home(tst, homehost) == 1)) {
 				if (report_missmatch)
 					fprintf(stderr, Name ": %s has metadata type %s for which "
@@ -392,6 +395,7 @@ int Assemble(struct supertype *st, char *mddev,
 			if (st)
 				st->ss->free_super(st);
 			dev_policy_free(pol);
+			domain_free(domains);
 			return 1;
 		}
 
@@ -459,6 +463,7 @@ int Assemble(struct supertype *st, char *mddev,
 					devname);
 				st->ss->free_super(st);
 				dev_policy_free(pol);
+				domain_free(domains);
 				return 1;
 			}
 			if (verbose > 0)
@@ -479,6 +484,12 @@ int Assemble(struct supertype *st, char *mddev,
 					   report_missmatch ? devname : NULL))
 				goto loop;
 
+			if (!memcmp(content->uuid, uuid_zero, sizeof(int[4]))) {
+				/* this is imsm_spare - do not set st */
+				tmpdev->used = 3;
+				goto loop;
+			}
+				
 			if (st == NULL)
 				st = dup_super(tst);
 			if (st->minor_version == -1)
@@ -522,17 +533,44 @@ int Assemble(struct supertype *st, char *mddev,
 				tst->ss->free_super(tst);
 				st->ss->free_super(st);
 				dev_policy_free(pol);
+				domain_free(domains);
 				return 1;
 			}
 			tmpdev->used = 1;
 		}
 	loop:
+		/* Collect domain information from members only */
+		if (tmpdev && tmpdev->used == 1)
+			domain_merge(&domains, pol, tst?tst->ss->name:NULL);
 		dev_policy_free(pol);
 		pol = NULL;
 		if (tst)
 			tst->ss->free_super(tst);
 	}
 
+	/* Now reject spares that don't match domains of identified members */
+	for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
+		struct stat stb;
+		if (tmpdev->used != 3)
+			continue;
+		if (stat(tmpdev->devname, &stb)< 0) {
+			fprintf(stderr, Name ": fstat failed for %s: %s\n",
+				tmpdev->devname, strerror(errno));
+			tmpdev->used = 2;
+		} else {
+			struct dev_policy *pol = NULL;
+			pol = devnum_policy(stb.st_rdev);
+			if (domain_test(domains, pol, NULL))
+				/* take this spare if domains match */
+				tmpdev->used = 1;
+			else
+				/* if domains don't match mark as unused */
+				tmpdev->used = 0;
+			dev_policy_free(pol);
+		}
+	}
+	domain_free(domains);
+	
 	if (!st || !st->sb || !content)
 		return 2;
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux