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:
parent
b8f72a621b
commit
91f068bf5c
|
@ -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.
|
||||
|
|
2
Create.c
2
Create.c
|
@ -464,7 +464,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
if (ioctl(mdfd, RUN_ARRAY, ¶m)) {
|
||||
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);
|
||||
|
|
11
Manage.c
11
Manage.c
|
@ -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
65
mdadm.c
|
@ -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':
|
||||
|
|
2
mdadm.h
2
mdadm.h
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue