From a7c6e3fb24f8335005a6ff8e0eb668faa257c941 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 7 Apr 2009 17:34:38 +1000 Subject: [PATCH] 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 --- 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 99f35991..172bc53e 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 52fc0ca0..358f8e6f 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 9f52b41d..36df10dd 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 99fc1bfc..b1cee23f 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 6770d6c8..83a7944b 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 07738d07..02fc4633 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); } -- 2.39.2