[PATCH 5/5] imsm: verify maximum supported active volumes in assembly

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

 



Subject: [PATCH 5/5] imsm: verify maximum supported active volumes in assembly

Block assemblation of volumes when the total number of supported
volumes is exceeded.

Signed-off-by: Marcin Labun <marcin.labun@xxxxxxxxx>
---
 Assemble.c    |    3 +-
 Grow.c        |    6 +++-
 Incremental.c |    3 +-
 mdadm.h       |    1 +
 super-intel.c |   73 +++++++++++++++++++++++++++++++++++++++++++-------------
 util.c        |    1 +
 6 files changed, 66 insertions(+), 21 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index fd94461..1d2604f 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -438,7 +438,7 @@ int Assemble(struct supertype *st, char *mddev,
 			if (verbose > 0)
 				fprintf(stderr, Name ": looking in container %s\n",
 					devname);
-
+			tst->check_volumes_number = 1;
 			for (content = tst->ss->container_content(tst, NULL);
 			     content;
 			     content = content->next) {
@@ -460,6 +460,7 @@ int Assemble(struct supertype *st, char *mddev,
 				} else
 					break;
 			}
+			tst->check_volumes_number = 0;
 			if (!content) {
 				tmpdev->used = 2;
 				goto loop; /* empty container */
diff --git a/Grow.c b/Grow.c
index 5dab37c..3a8b5c3 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1493,8 +1493,9 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
 		if (st->ss->container_content) {
 			struct mdinfo *cc = NULL;
 			struct mdinfo *content = NULL;
-
+			st->check_volumes_number = 1;
 			cc = st->ss->container_content(st, subarray);
+			st->check_volumes_number = 0;
 			for (content = cc; content ; content = content->next) {
 				int allow_reshape = 1;
 
@@ -3813,8 +3814,9 @@ int Grow_continue_command(char *devname, int fd,
 			ret_val = 1;
 			goto Grow_continue_command_exit;
 		}
-
+		st->check_volumes_number = 1;
 		cc = st->ss->container_content(st, subarray);
+		st->check_volumes_number = 0;
 		for (content = cc; content ; content = content->next) {
 			char *array;
 			int allow_reshape = 1;
diff --git a/Incremental.c b/Incremental.c
index 60175af..0e37f98 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1407,8 +1407,9 @@ static int Incremental_container(struct supertype *st, char *devname,
 		trustworthy = LOCAL;
 	else
 		trustworthy = FOREIGN;
-
+	st->check_volumes_number = 1;
 	list = st->ss->container_content(st, NULL);
+	st->check_volumes_number = 0;
 	/* when nothing to activate - quit */
 	if (list == NULL)
 		return 0;
diff --git a/mdadm.h b/mdadm.h
index f274ae7..ac96bc4 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -849,6 +849,7 @@ struct supertype {
 	int minor_version;
 	int max_devs;
 	int container_dev;    /* devnum of container */
+	int check_volumes_number;
 	void *sb;
 	void *info;
 	int ignore_hw_compat; /* used to inform metadata handlers that it should ignore
diff --git a/super-intel.c b/super-intel.c
index 51826bc..7fc1841 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -497,6 +497,9 @@ static const char *_sys_dev_type[] = {
 	[SYS_DEV_SAS] = "SAS",
 	[SYS_DEV_SATA] = "SATA"
 };
+#ifndef MDASSEMBLE
+static int imsm_find_array_minor_by_subdev(int subdev, int container, int *minor);
+#endif
 
 const char *get_sys_dev_type(enum sys_dev_type type)
 {
@@ -616,6 +619,7 @@ static struct supertype *match_metadata_desc_imsm(char *arg)
 	st->ss = &super_imsm;
 	st->max_devs = IMSM_MAX_DEVICES;
 	st->minor_version = 0;
+	st->check_volumes_number = 0;
 	st->sb = NULL;
 	return st;
 }
@@ -5658,6 +5662,7 @@ count_volumes_list(struct md_list *devlist, char *homehost,
 	}
 	if (*found != 0) {
 		int err;
+		st->check_volumes_number = 0;
 		if ((err = load_super_imsm_all(st, -1, &st->sb, NULL, devlist, 0)) == 0) {
 			struct mdinfo *iter, *head = st->ss->container_content(st, NULL);
 			for (iter = head; iter; iter = iter->next) {
@@ -5701,7 +5706,7 @@ count_volumes_list(struct md_list *devlist, char *homehost,
 
 
 static int
-count_volumes(char *hba, int dpa, int verbose)
+count_volumes(char *hba, int dpa, int active_only, int verbose)
 {
 	struct md_list *devlist = NULL;
 	int count = 0;
@@ -5712,10 +5717,14 @@ count_volumes(char *hba, int dpa, int verbose)
 	if (devlist == NULL)
 		return 0;
 	  
-	count = active_arrays_by_format("imsm", hba, &devlist, dpa, verbose);
+	count = active_arrays_by_format("imsm", hba, &devlist, /*subarray,*/
+					dpa, verbose);
 	dprintf(" path: %s active arrays: %d\n", hba, count);
 	if (devlist == NULL)
 		return 0;
+	if (active_only)
+		goto release;
+
 	do  {
 		found = 0;
 		count += count_volumes_list(devlist,
@@ -5726,7 +5735,8 @@ count_volumes(char *hba, int dpa, int verbose)
 	} while (found);
 	
 	dprintf("path: %s total number of volumes: %d\n", hba, count);
-	
+
+ release:	
 	while(devlist) {
 		struct md_list *dv = devlist;
 		devlist = devlist->next;
@@ -5815,6 +5825,17 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
 			"Cannot proceed with the action(s).\n");
 		return 0;
 	}
+	if (super->orom) {
+		int count = count_volumes(super->hba->path,
+					  super->orom->dpa,
+					  0, /* count all volumes */
+					  verbose);
+		if (super->orom->vphba <= count) {
+			pr_vrb(": platform does not support more then %d raid volumes.\n",
+			       super->orom->vphba);
+			return 0;
+		}
+	}
 	if (!dev) {
 		/* General test:  make sure there is space for
 		 * 'raiddisks' device extents of size 'size' at a given
@@ -5956,15 +5977,6 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
 
 	*freesize = maxsize;
 	
-	if (super->orom) {
-		int count = count_volumes(super->hba->path,
-				      super->orom->dpa, verbose);
-		if (super->orom->vphba <= count) {
-			pr_vrb(": platform does not support more then %d raid volumes.\n",
-			       super->orom->vphba);
-			return 0;
-		}
-	}
 	return 1;
 }
 
@@ -6091,7 +6103,9 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
 			if (super->orom && freesize) {
 				int count;
 				count = count_volumes(super->hba->path,
-						      super->orom->dpa, verbose);
+						      super->orom->dpa,
+						      0, /* count all volumes */
+						      verbose);
 				if (super->orom->vphba <= count) {
 					pr_vrb(": platform does not support more"
 					       "then %d raid volumes.\n",
@@ -6414,7 +6428,9 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
 	int sb_errors = 0;
 	struct dl *d;
 	int spare_disks = 0;
-
+#ifndef MDASSEMBLE
+	int count = -1;
+#endif
 	/* do not assemble arrays when not all attributes are supported */
 	if (imsm_check_attributes(mpb->attributes) == 0) {
 		sb_errors = 1;
@@ -6428,8 +6444,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
 			"Arrays activation is blocked.\n");
 		sb_errors = 1;
 	}
-
-
 	/* count spare devices, not used in maps
 	 */
 	for (d = super->disks; d; d = d->next)
@@ -6444,6 +6458,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
 		int slot;
 #ifndef MDASSEMBLE
 		int chunk;
+		int devnum;
 #endif
 		char *ep;
 
@@ -6502,7 +6517,31 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
 			this->array.state |=
 			  (1<<MD_SB_BLOCK_CONTAINER_RESHAPE) |
 			  (1<<MD_SB_BLOCK_VOLUME);
-
+#ifndef MDASSEMBLE
+		/* for inactive arrays check blocking condition */
+		if ((super->orom) &&
+		    (st->check_volumes_number) &&
+		    (imsm_find_array_minor_by_subdev(i,
+						     st->container_dev,
+						     &devnum) != 0)) {
+			/* get volumes number */
+			if (count == -1)
+				count = count_volumes(super->hba->path,
+						      super->orom->dpa,
+						      1, /* active only */
+						      0);
+			count++;
+			if (super->orom->vphba < count) {
+				this->array.state |=
+				  (1<<MD_SB_BLOCK_CONTAINER_RESHAPE) |
+				  (1<<MD_SB_BLOCK_VOLUME);
+				fprintf(stderr, Name ": platform does not support more then %d raid volumes.\n"
+					"Array %s activation is blocked.\n\n",
+					super->orom->vphba,
+					dev->volume);
+			}
+		  }
+#endif			
 		for (slot = 0 ; slot <  map->num_members; slot++) {
 			unsigned long long recovery_start;
 			struct mdinfo *info_d;
diff --git a/util.c b/util.c
index e95a366..ea18915 100644
--- a/util.c
+++ b/util.c
@@ -1020,6 +1020,7 @@ struct supertype *dup_super(struct supertype *orig)
 	st->ss = orig->ss;
 	st->max_devs = orig->max_devs;
 	st->minor_version = orig->minor_version;
+	st->check_volumes_number = orig->check_volumes_number;
 	st->sb = NULL;
 	st->info = NULL;
 	return st;
-- 
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