NeilBrown: wait_for improvement.

Martin F. Krafft madduck at alioth.debian.org
Thu May 7 12:11:35 UTC 2009


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

Author: NeilBrown <neilb at suse.de>
Date:   Tue Apr  7 17:34:38 2009 +1000

wait_for improvement.

wait not only for the name to appear, but for it to refer to the
correct device.
Sometimes old symlinks left lying around can be confusing.

Signed-off-by: NeilBrown <neilb at suse.de>

---

 Assemble.c    |    6 +++---
 Build.c       |    2 +-
 Create.c      |    4 ++--
 Incremental.c |    6 +++---
 mdadm.h       |    2 +-
 util.c        |   11 +++++++++--
 6 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index 99f3599..172bc53 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1069,7 +1069,7 @@ int Assemble(struct supertype *st, char *mddev,
 				fprintf(stderr, "\n");
 			}
 			sysfs_uevent(content, "change");
-			wait_for(chosen_name);
+			wait_for(chosen_name, mdfd);
 			close(mdfd);
 			return 0;
 		}
@@ -1104,8 +1104,8 @@ int Assemble(struct supertype *st, char *mddev,
 								      (4 * content->array.chunk_size / 4096) + 1);
 					}
 				}
+				wait_for(mddev, mdfd);
 				close(mdfd);
-				wait_for(mddev);
 				if (auto_assem) {
 					int usecs = 1;
 					/* There is a nasty race with 'mdadm --monitor'.
@@ -1276,7 +1276,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
 			fprintf(stderr, "\n");
 		}
 		if (!err)
-			wait_for(chosen_name);
+			wait_for(chosen_name, mdfd);
 		close(mdfd);
 		return 0;
 		/* FIXME should have an O_EXCL and wait for read-auto */
diff --git a/Build.c b/Build.c
index 52fc0ca..358f8e6 100644
--- a/Build.c
+++ b/Build.c
@@ -281,8 +281,8 @@ int Build(char *mddev, int chunk, int level, int layout,
 	if (verbose >= 0)
 		fprintf(stderr, Name ": array %s built and started.\n",
 			mddev);
+	wait_for(mddev, mdfd);
 	close(mdfd);
-	wait_for(mddev);
 	return 0;
 
  abort:
diff --git a/Create.c b/Create.c
index 9f52b41..36df10d 100644
--- a/Create.c
+++ b/Create.c
@@ -810,7 +810,7 @@ int Create(struct supertype *st, char *mddev,
 		sysfs_uevent(&info, "change");
 		if (verbose >= 0)
 			fprintf(stderr, Name ": container %s prepared.\n", mddev);
-		wait_for(chosen_name);
+		wait_for(chosen_name, mdfd);
 	} else if (runstop == 1 || subdevs >= raiddisks) {
 		if (st->ss->external) {
 			switch(level) {
@@ -846,7 +846,7 @@ int Create(struct supertype *st, char *mddev,
 			ping_monitor(devnum2devname(st->container_dev));
 			close(container_fd);
 		}
-		wait_for(chosen_name);
+		wait_for(chosen_name, mdfd);
 	} else {
 		fprintf(stderr, Name ": not starting array - not enough devices.\n");
 	}
diff --git a/Incremental.c b/Incremental.c
index 99fc1bf..b1cee23 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -392,14 +392,14 @@ int Incremental(char *devname, int verbose, int runstop,
 	/* 7a/ if not, finish with success. */
 	if (info.array.level == LEVEL_CONTAINER) {
 		/* Try to assemble within the container */
-		close(mdfd);
 		map_unlock(&map);
 		sysfs_uevent(&info, "change");
 		if (verbose >= 0)
 			fprintf(stderr, Name
 				": container %s now has %d devices\n",
 				chosen_name, info.array.working_disks);
-		wait_for(chosen_name);
+		wait_for(chosen_name, mdfd);
+		close(mdfd);
 		if (runstop < 0)
 			return 0; /* don't try to assemble */
 		return Incremental(chosen_name, verbose, runstop,
@@ -474,7 +474,7 @@ int Incremental(char *devname, int verbose, int runstop,
 			   ": %s attached to %s, which has been started.\n",
 					devname, chosen_name);
 			rv = 0;
-			wait_for(chosen_name);
+			wait_for(chosen_name, mdfd);
 		} else {
 			fprintf(stderr, Name
                              ": %s attached to %s, but failed to start: %s.\n",
diff --git a/mdadm.h b/mdadm.h
index 6770d6c..83a7944 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -657,7 +657,7 @@ extern struct supertype *dup_super(struct supertype *st);
 extern int get_dev_size(int fd, char *dname, unsigned long long *sizep);
 extern void get_one_disk(int mdfd, mdu_array_info_t *ainf,
 			 mdu_disk_info_t *disk);
-void wait_for(char *dev);
+void wait_for(char *dev, int fd);
 
 #if __GNUC__ < 3
 struct stat64;
diff --git a/util.c b/util.c
index 07738d0..02fc463 100644
--- a/util.c
+++ b/util.c
@@ -852,13 +852,20 @@ int same_dev(char *one, char *two)
 	return st1.st_rdev == st2.st_rdev;
 }
 
-void wait_for(char *dev)
+void wait_for(char *dev, int fd)
 {
 	int i;
+	struct stat stb_want;
+
+	if (fstat(fd, &stb_want) != 0 ||
+	    (stb_want.st_mode & S_IFMT) != S_IFBLK)
+		return;
 
 	for (i=0 ; i<25 ; i++) {
 		struct stat stb;
-		if (stat(dev, &stb) == 0)
+		if (stat(dev, &stb) == 0 &&
+		    (stb.st_mode & S_IFMT) == S_IFBLK &&
+		    (stb.st_rdev == stb_want.st_rdev))
 			return;
 		usleep(200000);
 	}




More information about the pkg-mdadm-commits mailing list