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@suse.de>
fprintf(stderr, "\n");
}
sysfs_uevent(content, "change");
fprintf(stderr, "\n");
}
sysfs_uevent(content, "change");
+ wait_for(chosen_name, mdfd);
(4 * content->array.chunk_size / 4096) + 1);
}
}
(4 * content->array.chunk_size / 4096) + 1);
}
}
if (auto_assem) {
int usecs = 1;
/* There is a nasty race with 'mdadm --monitor'.
if (auto_assem) {
int usecs = 1;
/* There is a nasty race with 'mdadm --monitor'.
fprintf(stderr, "\n");
}
if (!err)
fprintf(stderr, "\n");
}
if (!err)
+ wait_for(chosen_name, mdfd);
close(mdfd);
return 0;
/* FIXME should have an O_EXCL and wait for read-auto */
close(mdfd);
return 0;
/* FIXME should have an O_EXCL and wait for read-auto */
if (verbose >= 0)
fprintf(stderr, Name ": array %s built and started.\n",
mddev);
if (verbose >= 0)
fprintf(stderr, Name ": array %s built and started.\n",
mddev);
sysfs_uevent(&info, "change");
if (verbose >= 0)
fprintf(stderr, Name ": container %s prepared.\n", mddev);
sysfs_uevent(&info, "change");
if (verbose >= 0)
fprintf(stderr, Name ": container %s prepared.\n", mddev);
+ wait_for(chosen_name, mdfd);
} else if (runstop == 1 || subdevs >= raiddisks) {
if (st->ss->external) {
switch(level) {
} else if (runstop == 1 || subdevs >= raiddisks) {
if (st->ss->external) {
switch(level) {
ping_monitor(devnum2devname(st->container_dev));
close(container_fd);
}
ping_monitor(devnum2devname(st->container_dev));
close(container_fd);
}
+ wait_for(chosen_name, mdfd);
} else {
fprintf(stderr, Name ": not starting array - not enough devices.\n");
}
} else {
fprintf(stderr, Name ": not starting array - not enough devices.\n");
}
/* 7a/ if not, finish with success. */
if (info.array.level == LEVEL_CONTAINER) {
/* Try to assemble within the container */
/* 7a/ if not, finish with success. */
if (info.array.level == LEVEL_CONTAINER) {
/* Try to assemble within the container */
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);
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, mdfd);
+ close(mdfd);
if (runstop < 0)
return 0; /* don't try to assemble */
return Incremental(chosen_name, verbose, runstop,
if (runstop < 0)
return 0; /* don't try to assemble */
return Incremental(chosen_name, verbose, runstop,
": %s attached to %s, which has been started.\n",
devname, chosen_name);
rv = 0;
": %s attached to %s, which has been started.\n",
devname, chosen_name);
rv = 0;
+ wait_for(chosen_name, mdfd);
} else {
fprintf(stderr, Name
": %s attached to %s, but failed to start: %s.\n",
} else {
fprintf(stderr, Name
": %s attached to %s, but failed to start: %s.\n",
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);
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;
#if __GNUC__ < 3
struct stat64;
return st1.st_rdev == st2.st_rdev;
}
return st1.st_rdev == st2.st_rdev;
}
-void wait_for(char *dev)
+void wait_for(char *dev, int fd)
+ 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;
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);
}
return;
usleep(200000);
}