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.
- Document --size=max option for --grow
- 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
- 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)) {
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
strerror(errno));
Manage_runstop(mddev, mdfd, -1);
Manage_runstop(mddev, mdfd, -1, 0);
return 1;
}
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;
}
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
* 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 (ioctl(fd, STOP_MD, 0)) {
fprintf(stderr, Name ": stopping device %s failed: %s\n",
devname, strerror(errno));
if (!quiet) fprintf(stderr, Name ": stopping device %s failed: %s\n",
devname, strerror(errno));
return 1;
}
}
@ -106,8 +106,9 @@ int Manage_runstop(char *devname, int fd, int runstop)
}
} else if (runstop < 0){
if (ioctl(fd, STOP_ARRAY, NULL)) {
fprintf(stderr, Name ": fail to stop array %s: %s\n",
devname, strerror(errno));
if (!quiet)
fprintf(stderr, Name ": fail to stop array %s: %s\n",
devname, strerror(errno));
return 1;
}
}

65
mdadm.c
View File

@ -809,7 +809,7 @@ int main(int argc, char *argv[])
if (!rv && readonly < 0)
rv = Manage_ro(devlist->devname, mdfd, readonly);
if (!rv && runstop)
rv = Manage_runstop(devlist->devname, mdfd, runstop);
rv = Manage_runstop(devlist->devname, mdfd, runstop, 0);
break;
case ASSEMBLE:
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);
} else {
if (devlist == NULL) {
if ((devmode == 'S' ||devmode=='D') && scan) {
/* apply to all devices in /proc/mdstat */
if (devmode=='D' && scan) {
/* apply --detail to all devices in /proc/mdstat */
struct mdstat_ent *ms = mdstat_read(0);
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) {
char *name = get_md_name(e->devnum);
@ -961,18 +951,43 @@ int main(int argc, char *argv[])
e->dev);
continue;
}
if (devmode == 'D')
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);
}
}
rv |= Detail(name, !verbose, test);
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");
exit(2);
}
@ -992,9 +1007,9 @@ int main(int argc, char *argv[])
if (mdfd>=0) {
switch(dv->disposition) {
case 'R':
rv |= Manage_runstop(dv->devname, mdfd, 1); break;
rv |= Manage_runstop(dv->devname, mdfd, 1, 0); break;
case 'S':
rv |= Manage_runstop(dv->devname, mdfd, -1); break;
rv |= Manage_runstop(dv->devname, mdfd, -1, 0); break;
case 'o':
rv |= Manage_ro(dv->devname, mdfd, 1); break;
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_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_reconfig(char *devname, int fd, int layout);
extern int Manage_subdevs(char *devname, int fd,