Retry --stop --scan until all stoppable devices have been stopped

This is needed to reliably stop stacked arrays

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
This commit is contained in:
Neil Brown 2005-06-14 06:32:18 +00:00
parent b8f72a621b
commit 91f068bf5c
5 changed files with 50 additions and 32 deletions

View File

@ -2,6 +2,8 @@ Changes Prior to this release
- Don't use 'lstat' to check for blockdevices, use stat. - Don't use 'lstat' to check for blockdevices, use stat.
- Document --size=max option for --grow - Document --size=max option for --grow
- Document SparesMissing event and DeviceDisappeared/WrongLevel - Document SparesMissing event and DeviceDisappeared/WrongLevel
- --stop --scan repeatly cycles until no more progress can be made
so that stack devices are stopped properly
Changes Prior to 1.11.0 release Changes Prior to 1.11.0 release
- Fix embarassing bug which causes --add to always fail. - Fix embarassing bug which causes --add to always fail.

View File

@ -464,7 +464,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
if (ioctl(mdfd, RUN_ARRAY, &param)) { if (ioctl(mdfd, RUN_ARRAY, &param)) {
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n", fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
strerror(errno)); strerror(errno));
Manage_runstop(mddev, mdfd, -1); Manage_runstop(mddev, mdfd, -1, 0);
return 1; return 1;
} }
fprintf(stderr, Name ": array %s started.\n", mddev); fprintf(stderr, Name ": array %s started.\n", mddev);

View File

@ -72,7 +72,7 @@ int Manage_ro(char *devname, int fd, int readonly)
return 0; return 0;
} }
int Manage_runstop(char *devname, int fd, int runstop) int Manage_runstop(char *devname, int fd, int runstop, int quiet)
{ {
/* Run or stop the array. array must already be configured /* Run or stop the array. array must already be configured
* required >= 0.90.0 * required >= 0.90.0
@ -81,8 +81,8 @@ int Manage_runstop(char *devname, int fd, int runstop)
if (runstop == -1 && md_get_version(fd) < 9000) { if (runstop == -1 && md_get_version(fd) < 9000) {
if (ioctl(fd, STOP_MD, 0)) { if (ioctl(fd, STOP_MD, 0)) {
fprintf(stderr, Name ": stopping device %s failed: %s\n", if (!quiet) fprintf(stderr, Name ": stopping device %s failed: %s\n",
devname, strerror(errno)); devname, strerror(errno));
return 1; return 1;
} }
} }
@ -106,8 +106,9 @@ int Manage_runstop(char *devname, int fd, int runstop)
} }
} else if (runstop < 0){ } else if (runstop < 0){
if (ioctl(fd, STOP_ARRAY, NULL)) { if (ioctl(fd, STOP_ARRAY, NULL)) {
fprintf(stderr, Name ": fail to stop array %s: %s\n", if (!quiet)
devname, strerror(errno)); fprintf(stderr, Name ": fail to stop array %s: %s\n",
devname, strerror(errno));
return 1; return 1;
} }
} }

65
mdadm.c
View File

@ -809,7 +809,7 @@ int main(int argc, char *argv[])
if (!rv && readonly < 0) if (!rv && readonly < 0)
rv = Manage_ro(devlist->devname, mdfd, readonly); rv = Manage_ro(devlist->devname, mdfd, readonly);
if (!rv && runstop) if (!rv && runstop)
rv = Manage_runstop(devlist->devname, mdfd, runstop); rv = Manage_runstop(devlist->devname, mdfd, runstop, 0);
break; break;
case ASSEMBLE: case ASSEMBLE:
if (devs_found == 1 && ident.uuid_set == 0 && if (devs_found == 1 && ident.uuid_set == 0 &&
@ -939,20 +939,10 @@ int main(int argc, char *argv[])
rv = Examine(devlist, scan?!verbose:brief, scan, SparcAdjust, ss); rv = Examine(devlist, scan?!verbose:brief, scan, SparcAdjust, ss);
} else { } else {
if (devlist == NULL) { if (devlist == NULL) {
if ((devmode == 'S' ||devmode=='D') && scan) { if (devmode=='D' && scan) {
/* apply to all devices in /proc/mdstat */ /* apply --detail to all devices in /proc/mdstat */
struct mdstat_ent *ms = mdstat_read(0); struct mdstat_ent *ms = mdstat_read(0);
struct mdstat_ent *e; struct mdstat_ent *e;
if (devmode == 'S') {
/* reverse order so that arrays made of arrays are stopped properly */
struct mdstat_ent *sm = NULL;
while ((e=ms) != NULL) {
ms = e->next;
e->next = sm;
sm = e;
}
ms = sm;
}
for (e=ms ; e ; e=e->next) { for (e=ms ; e ; e=e->next) {
char *name = get_md_name(e->devnum); char *name = get_md_name(e->devnum);
@ -961,18 +951,43 @@ int main(int argc, char *argv[])
e->dev); e->dev);
continue; continue;
} }
if (devmode == 'D') rv |= Detail(name, !verbose, test);
rv |= Detail(name, !verbose, test);
else if (devmode=='S') {
mdfd = open_mddev(name, 0);
if (mdfd >= 0) {
rv |= Manage_runstop(name, mdfd, -1);
close(mdfd);
}
}
put_md_name(name); put_md_name(name);
} }
} else { } else if (devmode == 'S' && scan) {
/* apply --stop to all devices in /proc/mdstat */
/* Due to possible stacking of devices, repeat until
* nothing more can be stopped
*/
int progress=1, err;
int last = 0;
do {
struct mdstat_ent *ms = mdstat_read(0);
struct mdstat_ent *e;
if (!progress) last = 1;
progress = 0; err = 0;
for (e=ms ; e ; e=e->next) {
char *name = get_md_name(e->devnum);
if (!name) {
fprintf(stderr, Name ": cannot find device file for %s\n",
e->dev);
continue;
}
mdfd = open_mddev(name, 0);
if (mdfd >= 0) {
if (Manage_runstop(name, mdfd, -1, !last))
err = 1;
else
progress = 1;
close(mdfd);
}
put_md_name(name);
}
} while (!last && err);
} else {
fprintf(stderr, Name ": No devices given.\n"); fprintf(stderr, Name ": No devices given.\n");
exit(2); exit(2);
} }
@ -992,9 +1007,9 @@ int main(int argc, char *argv[])
if (mdfd>=0) { if (mdfd>=0) {
switch(dv->disposition) { switch(dv->disposition) {
case 'R': case 'R':
rv |= Manage_runstop(dv->devname, mdfd, 1); break; rv |= Manage_runstop(dv->devname, mdfd, 1, 0); break;
case 'S': case 'S':
rv |= Manage_runstop(dv->devname, mdfd, -1); break; rv |= Manage_runstop(dv->devname, mdfd, -1, 0); break;
case 'o': case 'o':
rv |= Manage_ro(dv->devname, mdfd, 1); break; rv |= Manage_ro(dv->devname, mdfd, 1); break;
case 'w': case 'w':

View File

@ -202,7 +202,7 @@ extern struct supertype *guess_super(int fd);
extern int Manage_ro(char *devname, int fd, int readonly); extern int Manage_ro(char *devname, int fd, int readonly);
extern int Manage_runstop(char *devname, int fd, int runstop); extern int Manage_runstop(char *devname, int fd, int runstop, int quiet);
extern int Manage_resize(char *devname, int fd, long long size, int raid_disks); extern int Manage_resize(char *devname, int fd, long long size, int raid_disks);
extern int Manage_reconfig(char *devname, int fd, int layout); extern int Manage_reconfig(char *devname, int fd, int layout);
extern int Manage_subdevs(char *devname, int fd, extern int Manage_subdevs(char *devname, int fd,