main: extract more functions.

extract misc_scan stop_scan misc_list from main to try to
make main() a little more manageable.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2012-07-09 17:14:16 +10:00
parent 3cbc4d12d0
commit 7d27d1c091
1 changed files with 206 additions and 162 deletions

368
mdadm.c
View File

@ -36,6 +36,15 @@ static int scan_assemble(int autof, struct supertype *ss,
char *homehost, int require_homehost, char *homehost, int require_homehost,
int verbose, int force, int verbose, int force,
int freeze_reshape); int freeze_reshape);
static int misc_scan(char devmode, int verbose, int export, int test,
char *homehost, char *prefer);
static int stop_scan(int quiet);
static int misc_list(struct mddev_dev *devlist,
int brief, int verbose, int export, int test,
char *homehost, char *prefer, char *subarray,
char *update, struct mddev_ident *ident,
struct supertype *ss, int force, int quiet);
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -919,8 +928,8 @@ int main(int argc, char *argv[])
case O(INCREMENTAL,'f'): case O(INCREMENTAL,'f'):
case O(INCREMENTAL,Remove): case O(INCREMENTAL,Remove):
case O(INCREMENTAL,Fail): /* r for incremental is taken, use f case O(INCREMENTAL,Fail): /* r for incremental is taken, use f
* even though we will both fail and * even though we will both fail and
* remove the device */ * remove the device */
devmode = 'f'; devmode = 'f';
continue; continue;
case O(INCREMENTAL,'R'): case O(INCREMENTAL,'R'):
@ -985,20 +994,20 @@ int main(int argc, char *argv[])
} }
devmode = opt; devmode = opt;
continue; continue;
case O(MISC, UdevRules): case O(MISC, UdevRules):
if (devmode && devmode != opt) { if (devmode && devmode != opt) {
fprintf(stderr, Name ": --udev-rules must" fprintf(stderr, Name ": --udev-rules must"
" be the only option.\n"); " be the only option.\n");
} else { } else {
if (udev_filename) if (udev_filename)
fprintf(stderr, Name ": only specify one udev " fprintf(stderr, Name ": only specify one udev "
"rule filename. %s ignored.\n", "rule filename. %s ignored.\n",
optarg); optarg);
else else
udev_filename = optarg; udev_filename = optarg;
} }
devmode = opt; devmode = opt;
continue; continue;
case O(MISC,'t'): case O(MISC,'t'):
test = 1; test = 1;
continue; continue;
@ -1402,149 +1411,23 @@ int main(int argc, char *argv[])
SparcAdjust, ss, homehost); SparcAdjust, ss, homehost);
} else if (devmode == DetailPlatform) { } else if (devmode == DetailPlatform) {
rv = Detail_Platform(ss ? ss->ss : NULL, ss ? scan : 1, verbose); rv = Detail_Platform(ss ? ss->ss : NULL, ss ? scan : 1, verbose);
} else { } else if (devlist == NULL) {
if (devlist == NULL) { if (devmode == 'S' && scan)
if ((devmode=='D' || devmode == Waitclean) && scan) { rv = stop_scan(quiet);
/* apply --detail or --wait-clean to else if ((devmode == 'D' || devmode == Waitclean) && scan)
* all devices in /proc/mdstat rv = misc_scan(devmode, verbose, export,
*/ test, homehost, prefer);
struct mdstat_ent *ms = mdstat_read(0, 1); else if (devmode == UdevRules)
struct mdstat_ent *e; rv = Write_rules(udev_filename);
struct map_ent *map = NULL; else {
int members; fprintf(stderr, Name ": No devices given.\n");
int v = verbose>1?0:verbose+1; exit(2);
for (members = 0; members <= 1; members++) {
for (e=ms ; e ; e=e->next) {
char *name;
struct map_ent *me;
int member = e->metadata_version &&
strncmp(e->metadata_version,
"external:/", 10) == 0;
if (members != member)
continue;
me = map_by_devnum(&map, e->devnum);
if (me && me->path
&& strcmp(me->path, "/unknown") != 0)
name = me->path;
else
name = get_md_name(e->devnum);
if (!name) {
fprintf(stderr, Name ": cannot find device file for %s\n",
e->dev);
continue;
}
if (devmode == 'D')
rv |= Detail(name, v,
export, test,
homehost, prefer);
else
rv |= WaitClean(name, -1, v);
put_md_name(name);
}
}
free_mdstat(ms);
} 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, 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, 1);
if (mdfd >= 0) {
if (Manage_runstop(name, mdfd, -1, quiet?1:last?0:-1))
err = 1;
else
progress = 1;
close(mdfd);
}
put_md_name(name);
}
free_mdstat(ms);
} while (!last && err);
if (err) rv |= 1;
} else if (devmode == UdevRules) {
rv = Write_rules(udev_filename);
} else {
fprintf(stderr, Name ": No devices given.\n");
exit(2);
}
} }
for (dv=devlist ; dv; dv=dv->next) { } else
switch(dv->disposition) { rv = misc_list(devlist, brief, verbose, export, test,
case 'D': homehost, prefer, subarray, update,
rv |= Detail(dv->devname, &ident,
brief?1+verbose:0, ss, force, quiet);
export, test, homehost, prefer);
continue;
case KillOpt: /* Zero superblock */
if (ss)
rv |= Kill(dv->devname, ss, force, quiet,0);
else {
int q = quiet;
do {
rv |= Kill(dv->devname, NULL, force, q, 0);
q = 1;
} while (rv == 0);
rv &= ~2;
}
continue;
case 'Q':
rv |= Query(dv->devname); continue;
case 'X':
rv |= ExamineBitmap(dv->devname, brief, ss); continue;
case 'W':
case WaitOpt:
rv |= Wait(dv->devname); continue;
case Waitclean:
rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
case KillSubarray:
rv |= Kill_subarray(dv->devname, subarray, quiet);
continue;
case UpdateSubarray:
if (update == NULL) {
fprintf(stderr,
Name ": -U/--update must be specified with --update-subarray\n");
rv |= 1;
continue;
}
rv |= Update_subarray(dv->devname, subarray, update, &ident, quiet);
continue;
}
mdfd = open_mddev(dv->devname, 1);
if (mdfd>=0) {
switch(dv->disposition) {
case 'R':
rv |= Manage_runstop(dv->devname, mdfd, 1, quiet); break;
case 'S':
rv |= Manage_runstop(dv->devname, mdfd, -1, quiet); break;
case 'o':
rv |= Manage_ro(dv->devname, mdfd, 1); break;
case 'w':
rv |= Manage_ro(dv->devname, mdfd, -1); break;
}
close(mdfd);
} else
rv |= 1;
}
}
break; break;
case MONITOR: case MONITOR:
if (!devlist && !scan) { if (!devlist && !scan) {
@ -1634,7 +1517,7 @@ int main(int argc, char *argv[])
mdfd, backup_file, mdfd, backup_file,
verbose); verbose);
else if (size >= 0 || raiddisks != 0 || layout_str != NULL else if (size >= 0 || raiddisks != 0 || layout_str != NULL
|| chunk != 0 || level != UnSet) { || chunk != 0 || level != UnSet) {
rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file, rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file,
size, level, layout_str, chunk, raiddisks, size, level, layout_str, chunk, raiddisks,
devlist->next, devlist->next,
@ -1649,12 +1532,12 @@ int main(int argc, char *argv[])
if (scan) { if (scan) {
if (runstop <= 0) { if (runstop <= 0) {
fprintf(stderr, Name fprintf(stderr, Name
": --incremental --scan meaningless without --run.\n"); ": --incremental --scan meaningless without --run.\n");
break; break;
} }
if (devmode == 'f') { if (devmode == 'f') {
fprintf(stderr, Name fprintf(stderr, Name
": --incremental --scan --fail not supported.\n"); ": --incremental --scan --fail not supported.\n");
break; break;
} }
rv = IncrementalScan(verbose); rv = IncrementalScan(verbose);
@ -1669,7 +1552,7 @@ int main(int argc, char *argv[])
} }
if (devlist->next) { if (devlist->next) {
fprintf(stderr, Name fprintf(stderr, Name
": --incremental can only handle one device.\n"); ": --incremental can only handle one device.\n");
rv = 1; rv = 1;
break; break;
} }
@ -1791,3 +1674,164 @@ static int scan_assemble(int autof, struct supertype *ss,
map_unlock(&map); map_unlock(&map);
return rv; return rv;
} }
static int misc_scan(char devmode, int verbose, int export, int test,
char *homehost, char *prefer)
{
/* apply --detail or --wait-clean to
* all devices in /proc/mdstat
*/
struct mdstat_ent *ms = mdstat_read(0, 1);
struct mdstat_ent *e;
struct map_ent *map = NULL;
int members;
int v = verbose>1?0:verbose+1;
int rv = 0;
for (members = 0; members <= 1; members++) {
for (e=ms ; e ; e=e->next) {
char *name;
struct map_ent *me;
int member = e->metadata_version &&
strncmp(e->metadata_version,
"external:/", 10) == 0;
if (members != member)
continue;
me = map_by_devnum(&map, e->devnum);
if (me && me->path
&& strcmp(me->path, "/unknown") != 0)
name = me->path;
else
name = get_md_name(e->devnum);
if (!name) {
fprintf(stderr, Name ": cannot find device file for %s\n",
e->dev);
continue;
}
if (devmode == 'D')
rv |= Detail(name, v,
export, test,
homehost, prefer);
else
rv |= WaitClean(name, -1, v);
put_md_name(name);
}
}
free_mdstat(ms);
return rv;
}
static int stop_scan(int quiet)
{
/* 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;
int rv = 0;
do {
struct mdstat_ent *ms = mdstat_read(0, 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);
int mdfd;
if (!name) {
fprintf(stderr, Name ": cannot find device file for %s\n",
e->dev);
continue;
}
mdfd = open_mddev(name, 1);
if (mdfd >= 0) {
if (Manage_runstop(name, mdfd, -1, quiet?1:last?0:-1))
err = 1;
else
progress = 1;
close(mdfd);
}
put_md_name(name);
}
free_mdstat(ms);
} while (!last && err);
if (err)
rv |= 1;
return rv;
}
static int misc_list(struct mddev_dev *devlist,
int brief, int verbose, int export, int test,
char *homehost, char *prefer, char *subarray,
char *update, struct mddev_ident *ident,
struct supertype *ss, int force, int quiet)
{
struct mddev_dev *dv;
int rv = 0;
for (dv=devlist ; dv; dv=dv->next) {
int mdfd;
switch(dv->disposition) {
case 'D':
rv |= Detail(dv->devname,
brief?1+verbose:0,
export, test, homehost, prefer);
continue;
case KillOpt: /* Zero superblock */
if (ss)
rv |= Kill(dv->devname, ss, force, quiet,0);
else {
int q = quiet;
do {
rv |= Kill(dv->devname, NULL, force, q, 0);
q = 1;
} while (rv == 0);
rv &= ~2;
}
continue;
case 'Q':
rv |= Query(dv->devname); continue;
case 'X':
rv |= ExamineBitmap(dv->devname, brief, ss); continue;
case 'W':
case WaitOpt:
rv |= Wait(dv->devname); continue;
case Waitclean:
rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
case KillSubarray:
rv |= Kill_subarray(dv->devname, subarray, quiet);
continue;
case UpdateSubarray:
if (update == NULL) {
fprintf(stderr,
Name ": -U/--update must be specified with --update-subarray\n");
rv |= 1;
continue;
}
rv |= Update_subarray(dv->devname, subarray,
update, ident, quiet);
continue;
}
mdfd = open_mddev(dv->devname, 1);
if (mdfd>=0) {
switch(dv->disposition) {
case 'R':
rv |= Manage_runstop(dv->devname, mdfd, 1, quiet); break;
case 'S':
rv |= Manage_runstop(dv->devname, mdfd, -1, quiet); break;
case 'o':
rv |= Manage_ro(dv->devname, mdfd, 1); break;
case 'w':
rv |= Manage_ro(dv->devname, mdfd, -1); break;
}
close(mdfd);
} else
rv |= 1;
}
return rv;
}