Dan Williams: Detail: fix for an imsm container with a spare

Martin F. Krafft madduck at alioth.debian.org
Tue Oct 27 19:45:24 UTC 2009


Module: mdadm
Branch: build
Commit: 436305c6905f81735eb04e9ef6577c21358836e8
URL:    http://git.debian.org/?p=pkg-mdadm/mdadm.git;a=commit;h=436305c6905f81735eb04e9ef6577c21358836e8

Author: Dan Williams <dan.j.williams at intel.com>
Date:   Tue Sep 15 11:34:20 2009 -0700

Detail: fix for an imsm container with a spare

Spares for imsm arrays do not have any info about the container in their
metadata records.  If Detail() inadvertantly picks such a device for
->get_array_info() it will end up with less than useful info for the
container.  So, continue to read from the disks until a non-spare device
is found.

This bug was found by timeouts waiting for udev to create the
user-friendly container name.  To detect future UUID reporting problems
and a debug print to the timeout case in wait_for().

Signed-off-by: Dan Williams <dan.j.williams at intel.com>

---

 Detail.c |   15 ++++++++++++++-
 util.c   |    2 ++
 2 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/Detail.c b/Detail.c
index ab01cfb..001012a 100644
--- a/Detail.c
+++ b/Detail.c
@@ -122,12 +122,25 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
 		    disk.minor == 0)
 			continue;
 		if ((dv=map_dev(disk.major, disk.minor, 1))) {
-			if ((!st || !st->sb) &&
+			/* some formats (imsm) have free-floating-spares
+			 * with a uuid of uuid_match_any, they don't
+			 * have very good info about the rest of the
+			 * container, so keep searching when
+			 * encountering such a device.  Otherwise, stop
+			 * after the first successful call to
+			 * ->load_super.
+			 */
+			int free_spare = memcmp(uuid_match_any,
+						info.uuid,
+						sizeof(uuid_match_any)) == 0;
+			if ((!st || !st->sb || free_spare) &&
 			    (array.raid_disks == 0 || 
 			     (disk.state & (1<<MD_DISK_ACTIVE)))) {
 				/* try to read the superblock from this device
 				 * to get more info
 				 */
+				if (free_spare)
+					st->ss->free_super(st);
 				int fd2 = dev_open(dv, O_RDONLY);
 				if (fd2 >=0 && st &&
 				    st->ss->load_super(st, fd2, NULL) == 0) {
diff --git a/util.c b/util.c
index 2543971..4ccb1bb 100644
--- a/util.c
+++ b/util.c
@@ -863,6 +863,8 @@ void wait_for(char *dev, int fd)
 			return;
 		usleep(200000);
 	}
+	if (i == 25)
+		dprintf("%s: timeout waiting for %s\n", __func__, dev);
 }
 
 struct superswitch *superlist[] = { &super0, &super1, &super_ddf, &super_imsm, NULL };




More information about the pkg-mdadm-commits mailing list