]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - mdadm.c
Discard 'quiet' context variable.
[thirdparty/mdadm.git] / mdadm.c
diff --git a/mdadm.c b/mdadm.c
index fa3da9fda7756e19d76ad6fd842060d662e905ee..d2ad3b4383ab45887cf5789179c870eb5b728146 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -38,12 +38,12 @@ static int scan_assemble(int autof, struct supertype *ss,
                         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 stop_scan(int verbose);
 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 supertype *ss, int force);
 
 
 int main(int argc, char *argv[])
@@ -51,7 +51,6 @@ int main(int argc, char *argv[])
        int mode = 0;
        int opt;
        int option_index;
-       char *c;
        int rv;
        int i;
 
@@ -65,31 +64,16 @@ int main(int argc, char *argv[])
        int sparedisks = 0;
        struct mddev_ident ident;
        char *configfile = NULL;
-       char *cp;
-       char *update = NULL;
-       int scan = 0;
        int devmode = 0;
-       int runstop = 0;
-       int readonly = 0;
        int write_behind = 0;
        int bitmap_fd = -1;
        char *bitmap_file = NULL;
-       char *backup_file = NULL;
-       int invalid_backup = 0;
        int bitmap_chunk = UnSet;
-       int SparcAdjust = 0;
        struct mddev_dev *devlist = NULL;
        struct mddev_dev **devlistend = & devlist;
        struct mddev_dev *dv;
        int devs_found = 0;
-       int verbose = 0;
-       int quiet = 0;
-       int brief = 0;
-       int force = 0;
-       int test = 0;
-       int export = 0;
        int assume_clean = 0;
-       char *prefer = NULL;
        char *symlinks = NULL;
        int grow_continue = 0;
        /* autof indicates whether and how to create device node.
@@ -102,26 +86,23 @@ int main(int argc, char *argv[])
         * 5  - default to md if not is_standard (md in config file)
         * 6  - default to mdp if not is_standard (part, or mdp in config file)
         */
-       int autof = 0;
+       struct context c = {
+               .require_homehost = 1,
+       };
 
-       char *homehost = NULL;
        char sys_hostname[256];
-       int require_homehost = 1;
        char *mailaddr = NULL;
        char *program = NULL;
        int increments = 20;
-       int delay = 0;
        int daemonise = 0;
        char *pidfile = NULL;
        int oneshot = 0;
        int spare_sharing = 1;
        struct supertype *ss = NULL;
        int writemostly = 0;
-       int re_add = 0;
        char *shortopt = short_options;
        int dosyslog = 0;
        int rebuild_map = 0;
-       char *subarray = NULL;
        char *remove_path = NULL;
        char *udev_filename = NULL;
 
@@ -130,8 +111,6 @@ int main(int argc, char *argv[])
 
        int mdfd = -1;
 
-       int freeze_reshape = 0;
-
        srandom(time(0) ^ getpid());
 
        ident.uuid_set=0;
@@ -166,10 +145,10 @@ int main(int argc, char *argv[])
                        fputs(Version, stderr);
                        exit(0);
 
-               case 'v': verbose++;
+               case 'v': c.verbose++;
                        continue;
 
-               case 'q': quiet++;
+               case 'q': c.verbose--;
                        continue;
 
                case 'b':
@@ -178,17 +157,17 @@ int main(int argc, char *argv[])
                            || mode == MANAGE)
                                break; /* b means bitmap */
                case Brief:
-                       brief = 1;
+                       c.brief = 1;
                        continue;
 
-               case 'Y': export++;
+               case 'Y': c.export++;
                        continue;
 
                case HomeHost:
                        if (strcasecmp(optarg, "<ignore>") == 0)
-                               require_homehost = 0;
+                               c.require_homehost = 0;
                        else
-                               homehost = optarg;
+                               c.homehost = optarg;
                        continue;
 
                /*
@@ -202,10 +181,10 @@ int main(int argc, char *argv[])
                        continue;
 
                case Prefer:
-                       if (prefer)
-                               free(prefer);
-                       if (asprintf(&prefer, "/%s/", optarg) <= 0)
-                               prefer = NULL;
+                       if (c.prefer)
+                               free(c.prefer);
+                       if (asprintf(&c.prefer, "/%s/", optarg) <= 0)
+                               c.prefer = NULL;
                        continue;
 
                case ':':
@@ -318,15 +297,10 @@ int main(int argc, char *argv[])
                        /* If first option is a device, don't force the mode yet */
                        if (opt == 1) {
                                if (devs_found == 0) {
-                                       dv = malloc(sizeof(*dv));
-                                       if (dv == NULL) {
-                                               pr_err("malloc failed\n");
-                                               exit(3);
-                                       }
+                                       dv = xmalloc(sizeof(*dv));
                                        dv->devname = optarg;
                                        dv->disposition = devmode;
                                        dv->writemostly = writemostly;
-                                       dv->re_add = re_add;
                                        dv->used = 0;
                                        dv->next = NULL;
                                        *devlistend = dv;
@@ -374,15 +348,10 @@ int main(int argc, char *argv[])
                                       " devices to add: %s\n", optarg);
                                exit(2);
                        }
-                       dv = malloc(sizeof(*dv));
-                       if (dv == NULL) {
-                               pr_err("malloc failed\n");
-                               exit(3);
-                       }
+                       dv = xmalloc(sizeof(*dv));
                        dv->devname = optarg;
                        dv->disposition = devmode;
                        dv->writemostly = writemostly;
-                       dv->re_add = re_add;
                        dv->used = 0;
                        dv->next = NULL;
                        *devlistend = dv;
@@ -601,8 +570,8 @@ int main(int argc, char *argv[])
                                        raiddisks, optarg);
                                exit(2);
                        }
-                       raiddisks = strtol(optarg, &c, 10);
-                       if (!optarg[0] || *c || raiddisks<=0) {
+                       raiddisks = parse_num(optarg);
+                       if (raiddisks <= 0) {
                                pr_err("invalid number of raid devices: %s\n",
                                        optarg);
                                exit(2);
@@ -621,8 +590,8 @@ int main(int argc, char *argv[])
                                        level);
                                exit(2);
                        }
-                       sparedisks = strtol(optarg, &c, 10);
-                       if (!optarg[0] || *c || sparedisks < 0) {
+                       sparedisks = parse_num(optarg);
+                       if (sparedisks < 0) {
                                pr_err("invalid number of spare-devices: %s\n",
                                        optarg);
                                exit(2);
@@ -637,7 +606,7 @@ int main(int argc, char *argv[])
                case O(INCREMENTAL,Auto):
                case O(ASSEMBLE,'a'):
                case O(ASSEMBLE,Auto): /* auto-creation of device node */
-                       autof = parse_auto(optarg, "--auto flag", 0);
+                       c.autof = parse_auto(optarg, "--auto flag", 0);
                        continue;
 
                case O(CREATE,Symlinks):
@@ -657,13 +626,13 @@ int main(int argc, char *argv[])
                case O(MISC,'f'): /* force zero */
                case O(MISC,Force): /* force zero */
                case O(MANAGE,Force): /* add device which is too large */
-                       force=1;
+                       c.force=1;
                        continue;
                        /* now for the Assemble options */
                case O(ASSEMBLE, FreezeReshape):   /* Freeze reshape during
                                                    * initrd phase */
                case O(INCREMENTAL, FreezeReshape):
-                       freeze_reshape = 1;
+                       c.freeze_reshape = 1;
                        continue;
                case O(CREATE,'u'): /* uuid of array */
                case O(ASSEMBLE,'u'): /* uuid of array */
@@ -688,7 +657,7 @@ int main(int argc, char *argv[])
                                        "Second value %s.\n", optarg);
                                exit(2);
                        }
-                       if (mode == MISC && !subarray) {
+                       if (mode == MISC && !c.subarray) {
                                pr_err("-N/--name only valid with --update-subarray in misc mode\n");
                                exit(2);
                        }
@@ -710,47 +679,53 @@ int main(int argc, char *argv[])
                        if (strcmp(optarg, "dev")==0)
                                ident.super_minor = -2;
                        else {
-                               ident.super_minor = strtoul(optarg, &cp, 10);
-                               if (!optarg[0] || *cp) {
+                               ident.super_minor = parse_num(optarg);
+                               if (ident.super_minor < 0) {
                                        pr_err("Bad super-minor number: %s.\n", optarg);
                                        exit(2);
                                }
                        }
                        continue;
 
+               case O(ASSEMBLE,'o'):
+               case O(MANAGE,'o'):
+               case O(CREATE,'o'):
+                       c.readonly = 1;
+                       continue;
+
                case O(ASSEMBLE,'U'): /* update the superblock */
                case O(MISC,'U'):
-                       if (update) {
+                       if (c.update) {
                                pr_err("Can only update one aspect"
                                        " of superblock, both %s and %s given.\n",
-                                       update, optarg);
+                                       c.update, optarg);
                                exit(2);
                        }
-                       if (mode == MISC && !subarray) {
+                       if (mode == MISC && !c.subarray) {
                                pr_err("Only subarrays can be"
                                        " updated in misc mode\n");
                                exit(2);
                        }
-                       update = optarg;
-                       if (strcmp(update, "sparc2.2")==0)
+                       c.update = optarg;
+                       if (strcmp(c.update, "sparc2.2")==0)
                                continue;
-                       if (strcmp(update, "super-minor") == 0)
+                       if (strcmp(c.update, "super-minor") == 0)
                                continue;
-                       if (strcmp(update, "summaries")==0)
+                       if (strcmp(c.update, "summaries")==0)
                                continue;
-                       if (strcmp(update, "resync")==0)
+                       if (strcmp(c.update, "resync")==0)
                                continue;
-                       if (strcmp(update, "uuid")==0)
+                       if (strcmp(c.update, "uuid")==0)
                                continue;
-                       if (strcmp(update, "name")==0)
+                       if (strcmp(c.update, "name")==0)
                                continue;
-                       if (strcmp(update, "homehost")==0)
+                       if (strcmp(c.update, "homehost")==0)
                                continue;
-                       if (strcmp(update, "devicesize")==0)
+                       if (strcmp(c.update, "devicesize")==0)
                                continue;
-                       if (strcmp(update, "no-bitmap")==0)
+                       if (strcmp(c.update, "no-bitmap")==0)
                                continue;
-                       if (strcmp(update, "byteorder")==0) {
+                       if (strcmp(c.update, "byteorder")==0) {
                                if (ss) {
                                        pr_err("must not set metadata"
                                               " type with --update=byteorder.\n");
@@ -767,15 +742,15 @@ int main(int argc, char *argv[])
 
                                continue;
                        }
-                       if (strcmp(update,"?") == 0 ||
-                           strcmp(update, "help") == 0) {
+                       if (strcmp(c.update,"?") == 0 ||
+                           strcmp(c.update, "help") == 0) {
                                outf = stdout;
                                fprintf(outf, Name ": ");
                        } else {
                                outf = stderr;
                                fprintf(outf,
                                        Name ": '--update=%s' is invalid.  ",
-                                       update);
+                                       c.update);
                        }
                        fprintf(outf, "Valid --update options are:\n"
                "     'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n"
@@ -785,19 +760,19 @@ int main(int argc, char *argv[])
 
                case O(MANAGE,'U'):
                        /* update=devicesize is allowed with --re-add */
-                       if (devmode != 'a' || re_add != 1) {
+                       if (devmode != 'A') {
                                pr_err("--update in Manage mode only"
                                        " allowed with --re-add.\n");
                                exit(1);
                        }
-                       if (update) {
+                       if (c.update) {
                                pr_err("Can only update one aspect"
                                        " of superblock, both %s and %s given.\n",
-                                       update, optarg);
+                                       c.update, optarg);
                                exit(2);
                        }
-                       update = optarg;
-                       if (strcmp(update, "devicesize") != 0) {
+                       c.update = optarg;
+                       if (strcmp(c.update, "devicesize") != 0) {
                                pr_err("only 'devicesize' can be"
                                        " updated with --re-add\n");
                                exit(2);
@@ -807,8 +782,8 @@ int main(int argc, char *argv[])
                case O(INCREMENTAL,NoDegraded):
                        pr_err("--no-degraded is deprecated in Incremental mode\n");
                case O(ASSEMBLE,NoDegraded): /* --no-degraded */
-                       runstop = -1; /* --stop isn't allowed for --assemble,
-                                      * so we overload slightly */
+                       c.runstop = -1; /* --stop isn't allowed for --assemble,
+                                        * so we overload slightly */
                        continue;
 
                case O(ASSEMBLE,'c'):
@@ -832,7 +807,7 @@ int main(int argc, char *argv[])
                case O(MISC,'s'):
                case O(MONITOR,'s'):
                case O(INCREMENTAL,'s'):
-                       scan = 1;
+                       c.scan = 1;
                        continue;
 
                case O(MONITOR,'m'): /* mail address */
@@ -866,12 +841,12 @@ int main(int argc, char *argv[])
                case O(GROW, 'd'):
                case O(BUILD,'d'): /* delay for bitmap updates */
                case O(CREATE,'d'):
-                       if (delay)
+                       if (c.delay)
                                pr_err("only specify delay once. %s ignored.\n",
                                        optarg);
                        else {
-                               delay = strtol(optarg, &c, 10);
-                               if (!optarg[0] || *c || delay<1) {
+                               c.delay = parse_num(optarg);
+                               if (c.delay < 1) {
                                        pr_err("invalid delay: %s\n",
                                                optarg);
                                        exit(2);
@@ -894,7 +869,7 @@ int main(int argc, char *argv[])
                        spare_sharing = 0;
                        continue;
                case O(MONITOR,'t'): /* test */
-                       test = 1;
+                       c.test = 1;
                        continue;
                case O(MONITOR,'y'): /* log messages to syslog */
                        openlog("mdadm", LOG_PID, SYSLOG_FACILITY);
@@ -912,11 +887,9 @@ int main(int argc, char *argv[])
                case O(MANAGE,'a'):
                case O(MANAGE,Add): /* add a drive */
                        devmode = 'a';
-                       re_add = 0;
                        continue;
                case O(MANAGE,ReAdd):
-                       devmode = 'a';
-                       re_add = 1;
+                       devmode = 'A';
                        continue;
                case O(MANAGE,'r'): /* remove a drive */
                case O(MANAGE,Remove):
@@ -936,21 +909,21 @@ int main(int argc, char *argv[])
                case O(ASSEMBLE,'R'):
                case O(BUILD,'R'):
                case O(CREATE,'R'): /* Run the array */
-                       if (runstop < 0) {
+                       if (c.runstop < 0) {
                                pr_err("Cannot both Stop and Run an array\n");
                                exit(2);
                        }
-                       runstop = 1;
+                       c.runstop = 1;
                        continue;
                case O(MANAGE,'S'):
-                       if (runstop > 0) {
+                       if (c.runstop > 0) {
                                pr_err("Cannot both Run and Stop an array\n");
                                exit(2);
                        }
-                       runstop = -1;
+                       c.runstop = -1;
                        continue;
                case O(MANAGE,'t'):
-                       test = 1;
+                       c.test = 1;
                        continue;
 
                case O(MISC,'Q'):
@@ -969,12 +942,12 @@ int main(int argc, char *argv[])
                case O(MISC, KillSubarray):
                case O(MISC, UpdateSubarray):
                        if (opt == KillSubarray || opt == UpdateSubarray) {
-                               if (subarray) {
+                               if (c.subarray) {
                                        pr_err("subarray can only"
                                                " be specified once\n");
                                        exit(2);
                                }
-                               subarray = optarg;
+                               c.subarray = optarg;
                        }
                        if (devmode && devmode != opt &&
                            (devmode == 'E' || (opt == 'E' && devmode != 'Q'))) {
@@ -1008,7 +981,7 @@ int main(int argc, char *argv[])
                        devmode = opt;
                        continue;
                case O(MISC,'t'):
-                       test = 1;
+                       c.test = 1;
                        continue;
 
                case O(MISC, Sparc22):
@@ -1016,7 +989,7 @@ int main(int argc, char *argv[])
                                pr_err("--sparc2.2 only allowed with --examine\n");
                                exit(2);
                        }
-                       SparcAdjust = 1;
+                       c.SparcAdjust = 1;
                        continue;
 
                case O(ASSEMBLE,'b'): /* here we simply set the bitmap file */
@@ -1042,11 +1015,11 @@ int main(int argc, char *argv[])
                        /* Specify a file into which grow might place a backup,
                         * or from which assemble might recover a backup
                         */
-                       if (backup_file) {
+                       if (c.backup_file) {
                                pr_err("backup file already specified, rejecting %s\n", optarg);
                                exit(2);
                        }
-                       backup_file = optarg;
+                       c.backup_file = optarg;
                        continue;
 
                case O(GROW, Continue):
@@ -1058,7 +1031,7 @@ int main(int argc, char *argv[])
                        /* Acknowledge that the backupfile is invalid, but ask
                         * to continue anyway
                         */
-                       invalid_backup = 1;
+                       c.invalid_backup = 1;
                        continue;
 
                case O(BUILD,'b'):
@@ -1102,8 +1075,8 @@ int main(int argc, char *argv[])
                case O(CREATE, WriteBehind): /* write-behind mode */
                        write_behind = DEFAULT_MAX_WRITE_BEHIND;
                        if (optarg) {
-                               write_behind = strtol(optarg, &c, 10);
-                               if (write_behind < 0 || *c ||
+                               write_behind = parse_num(optarg);
+                               if (write_behind < 0 ||
                                    write_behind > 16383) {
                                        pr_err("Invalid value for maximum outstanding write-behind writes: %s.\n\tMust be between 0 and 16383.\n", optarg);
                                        exit(2);
@@ -1180,12 +1153,12 @@ int main(int argc, char *argv[])
 
        if (mode == MANAGE || mode == BUILD || mode == CREATE
            || mode == GROW
-           || (mode == ASSEMBLE && ! scan)) {
+           || (mode == ASSEMBLE && ! c.scan)) {
                if (devs_found < 1) {
                        pr_err("an md device must be given in this mode\n");
                        exit(2);
                }
-               if ((int)ident.super_minor == -2 && autof) {
+               if ((int)ident.super_minor == -2 && c.autof) {
                        pr_err("--super-minor=dev is incompatible with --auto\n");
                        exit(2);
                }
@@ -1222,7 +1195,7 @@ int main(int argc, char *argv[])
        }
 
        if (raiddisks) {
-               if (raiddisks == 1 &&  !force && level != LEVEL_FAULTY) {
+               if (raiddisks == 1 &&  !c.force && level != LEVEL_FAULTY) {
                        pr_err("'1' is an unusual number of drives for an array, so it is probably\n"
                                "     a mistake.  If you really mean it you will need to specify --force before\n"
                                "     setting the number of drives.\n");
@@ -1230,17 +1203,17 @@ int main(int argc, char *argv[])
                }
        }
 
-       if (homehost == NULL)
-               homehost = conf_get_homehost(&require_homehost);
-       if (homehost == NULL || strcasecmp(homehost, "<system>")==0) {
+       if (c.homehost == NULL)
+               c.homehost = conf_get_homehost(&c.require_homehost);
+       if (c.homehost == NULL || strcasecmp(c.homehost, "<system>")==0) {
                if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
                        sys_hostname[sizeof(sys_hostname)-1] = 0;
-                       homehost = sys_hostname;
+                       c.homehost = sys_hostname;
                }
        }
-       if (homehost && (!homehost[0] || strcasecmp(homehost, "<none>") == 0)) {
-               homehost = NULL;
-               require_homehost = 0;
+       if (c.homehost && (!c.homehost[0] || strcasecmp(c.homehost, "<none>") == 0)) {
+               c.homehost = NULL;
+               c.require_homehost = 0;
        }
 
        if ((mode == MISC && devmode == 'E')
@@ -1251,26 +1224,26 @@ int main(int argc, char *argv[])
                exit(1);
        }
 
-       ident.autof = autof;
+       ident.autof = c.autof;
 
        rv = 0;
        switch(mode) {
        case MANAGE:
                /* readonly, add/remove, readwrite, runstop */
-               if (readonly>0)
-                       rv = Manage_ro(devlist->devname, mdfd, readonly);
+               if (c.readonly > 0)
+                       rv = Manage_ro(devlist->devname, mdfd, c.readonly);
                if (!rv && devs_found>1)
                        rv = Manage_subdevs(devlist->devname, mdfd,
-                                           devlist->next, verbose-quiet, test,
-                                           update, force);
-               if (!rv && readonly < 0)
-                       rv = Manage_ro(devlist->devname, mdfd, readonly);
-               if (!rv && runstop)
-                       rv = Manage_runstop(devlist->devname, mdfd, runstop, quiet);
+                                           devlist->next, c.verbose, c.test,
+                                           c.update, c.force);
+               if (!rv && c.readonly < 0)
+                       rv = Manage_ro(devlist->devname, mdfd, c.readonly);
+               if (!rv && c.runstop)
+                       rv = Manage_runstop(devlist->devname, mdfd, c.runstop, c.verbose, 0);
                break;
        case ASSEMBLE:
                if (devs_found == 1 && ident.uuid_set == 0 &&
-                   ident.super_minor == UnSet && ident.name[0] == 0 && !scan ) {
+                   ident.super_minor == UnSet && ident.name[0] == 0 && !c.scan ) {
                        /* Only a device has been given, so get details from config file */
                        struct mddev_ident *array_ident = conf_get_ident(devlist->devname);
                        if (array_ident == NULL) {
@@ -1281,27 +1254,27 @@ int main(int argc, char *argv[])
                                        close(mdfd);
                        } else {
                                if (array_ident->autof == 0)
-                                       array_ident->autof = autof;
+                                       array_ident->autof = c.autof;
                                rv |= Assemble(ss, devlist->devname, array_ident,
-                                              NULL, backup_file, invalid_backup,
-                                              readonly, runstop, update,
-                                              homehost, require_homehost,
-                                              verbose-quiet, force,
-                                              freeze_reshape);
+                                              NULL, c.backup_file, c.invalid_backup,
+                                              c.readonly, c.runstop, c.update,
+                                              c.homehost, c.require_homehost,
+                                              c.verbose, c.force,
+                                              c.freeze_reshape);
                        }
-               } else if (!scan)
+               } else if (!c.scan)
                        rv = Assemble(ss, devlist->devname, &ident,
-                                     devlist->next, backup_file, invalid_backup,
-                                     readonly, runstop, update,
-                                     homehost, require_homehost,
-                                     verbose-quiet, force,
-                                     freeze_reshape);
+                                     devlist->next, c.backup_file, c.invalid_backup,
+                                     c.readonly, c.runstop, c.update,
+                                     c.homehost, c.require_homehost,
+                                     c.verbose, c.force,
+                                     c.freeze_reshape);
                else if (devs_found > 0) {
-                       if (update && devs_found > 1) {
+                       if (c.update && devs_found > 1) {
                                pr_err("can only update a single array at a time\n");
                                exit(1);
                        }
-                       if (backup_file && devs_found > 1) {
+                       if (c.backup_file && devs_found > 1) {
                                pr_err("can only assemble a single array when providing a backup file.\n");
                                exit(1);
                        }
@@ -1314,33 +1287,34 @@ int main(int argc, char *argv[])
                                        continue;
                                }
                                if (array_ident->autof == 0)
-                                       array_ident->autof = autof;
+                                       array_ident->autof = c.autof;
                                rv |= Assemble(ss, dv->devname, array_ident,
-                                              NULL, backup_file, invalid_backup,
-                                              readonly, runstop, update,
-                                              homehost, require_homehost,
-                                              verbose-quiet, force,
-                                              freeze_reshape);
+                                              NULL, c.backup_file, c.invalid_backup,
+                                              c.readonly, c.runstop, c.update,
+                                              c.homehost, c.require_homehost,
+                                              c.verbose, c.force,
+                                              c.freeze_reshape);
                        }
                } else {
-                       if (update) {
+                       if (c.update) {
                                pr_err("--update not meaningful with a --scan assembly.\n");
                                exit(1);
                        }
-                       if (backup_file) {
+                       if (c.backup_file) {
                                pr_err("--backup_file not meaningful with a --scan assembly.\n");
                                exit(1);
                        }
-                       rv = scan_assemble(autof, ss, readonly, runstop,
-                                          &ident, homehost,
-                                          require_homehost,
-                                          verbose - quiet,
-                                          force, freeze_reshape);
+                       rv = scan_assemble(c.autof, ss, c.readonly, c.runstop,
+                                          &ident, c.homehost,
+                                          c.require_homehost,
+                                          c.verbose,
+                                          c.force, c.freeze_reshape);
                }
 
                break;
        case BUILD:
-               if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
+               if (c.delay == 0)
+                       c.delay = DEFAULT_BITMAP_DELAY;
                if (write_behind && !bitmap_file) {
                        pr_err("write-behind mode requires a bitmap.\n");
                        rv = 1;
@@ -1362,10 +1336,11 @@ int main(int argc, char *argv[])
                rv = Build(devlist->devname, chunk, level, layout,
                           raiddisks, devlist->next, assume_clean,
                           bitmap_file, bitmap_chunk, write_behind,
-                          delay, verbose-quiet, autof, size);
+                          c.delay, c.verbose, c.autof, size);
                break;
        case CREATE:
-               if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
+               if (c.delay == 0)
+                       c.delay = DEFAULT_BITMAP_DELAY;
                if (write_behind && !bitmap_file) {
                        pr_err("write-behind mode requires a bitmap.\n");
                        rv = 1;
@@ -1378,14 +1353,15 @@ int main(int argc, char *argv[])
                }
 
                rv = Create(ss, devlist->devname, chunk, level, layout, size<0 ? 0 : size,
-                           raiddisks, sparedisks, ident.name, homehost,
+                           raiddisks, sparedisks, ident.name, c.homehost,
                            ident.uuid_set ? ident.uuid : NULL,
-                           devs_found-1, devlist->next, runstop, verbose-quiet, force, assume_clean,
-                           bitmap_file, bitmap_chunk, write_behind, delay, autof);
+                           devs_found-1, devlist->next, c.runstop,
+                           c.readonly, c.verbose, c.force, assume_clean,
+                           bitmap_file, bitmap_chunk, write_behind, c.delay, c.autof);
                break;
        case MISC:
                if (devmode == 'E') {
-                       if (devlist == NULL && !scan) {
+                       if (devlist == NULL && !c.scan) {
                                pr_err("No devices to examine\n");
                                exit(2);
                        }
@@ -1395,19 +1371,19 @@ int main(int argc, char *argv[])
                                pr_err("No devices listed in %s\n", configfile?configfile:DefaultConfFile);
                                exit(1);
                        }
-                       if (brief && verbose)
-                               brief = 2;
-                       rv = Examine(devlist, scan?(verbose>1?0:verbose+1):brief,
-                                    export, scan,
-                                    SparcAdjust, ss, homehost);
+                       if (c.brief && c.verbose > 0)
+                               c.brief = 2;
+                       rv = Examine(devlist, c.scan?(c.verbose>1?0:c.verbose):c.brief,
+                                    c.export, c.scan,
+                                    c.SparcAdjust, ss, c.homehost);
                } else if (devmode == DetailPlatform) {
-                       rv = Detail_Platform(ss ? ss->ss : NULL, ss ? scan : 1, verbose);
+                       rv = Detail_Platform(ss ? ss->ss : NULL, ss ? c.scan : 1, c.verbose);
                } else if (devlist == NULL) {
-                       if (devmode == 'S' && scan)
-                               rv = stop_scan(quiet);
-                       else if ((devmode == 'D' || devmode == Waitclean) && scan)
-                               rv = misc_scan(devmode, verbose, export,
-                                              test, homehost, prefer);
+                       if (devmode == 'S' && c.scan)
+                               rv = stop_scan(c.verbose);
+                       else if ((devmode == 'D' || devmode == Waitclean) && c.scan)
+                               rv = misc_scan(devmode, c.verbose, c.export,
+                                              c.test, c.homehost, c.prefer);
                        else if (devmode == UdevRules)
                                rv = Write_rules(udev_filename);
                        else {
@@ -1415,13 +1391,13 @@ int main(int argc, char *argv[])
                                exit(2);
                        }
                } else
-                       rv = misc_list(devlist, brief, verbose, export, test,
-                                      homehost, prefer, subarray, update,
+                       rv = misc_list(devlist, c.brief, c.verbose, c.export, c.test,
+                                      c.homehost, c.prefer, c.subarray, c.update,
                                       &ident,
-                                      ss, force, quiet);
+                                      ss, c.force);
                break;
        case MONITOR:
-               if (!devlist && !scan) {
+               if (!devlist && !c.scan) {
                        pr_err("Cannot monitor: need --scan or at least one device\n");
                        rv = 1;
                        break;
@@ -1431,17 +1407,17 @@ int main(int argc, char *argv[])
                        rv = 1;
                        break;
                }
-               if (delay == 0) {
+               if (c.delay == 0) {
                        if (get_linux_version() > 2006016)
                                /* mdstat responds to poll */
-                               delay = 1000;
+                               c.delay = 1000;
                        else
-                               delay = 60;
+                               c.delay = 60;
                }
                rv= Monitor(devlist, mailaddr, program,
-                           delay?delay:60, daemonise, scan, oneshot,
-                           dosyslog, test, pidfile, increments,
-                           spare_sharing, prefer);
+                           c.delay?c.delay:60, daemonise, c.scan, oneshot,
+                           dosyslog, c.test, pidfile, increments,
+                           spare_sharing, c.prefer);
                break;
 
        case GROW:
@@ -1499,20 +1475,20 @@ int main(int argc, char *argv[])
                                rv = 1;
                                break;
                        }
-                       if (delay == 0)
-                               delay = DEFAULT_BITMAP_DELAY;
+                       if (c.delay == 0)
+                               c.delay = DEFAULT_BITMAP_DELAY;
                        rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,
-                                           bitmap_chunk, delay, write_behind, force);
+                                           bitmap_chunk, c.delay, write_behind, c.force);
                } else if (grow_continue)
                        rv = Grow_continue_command(devlist->devname,
-                                                  mdfd, backup_file,
-                                                  verbose);
+                                                  mdfd, c.backup_file,
+                                                  c.verbose);
                else if (size >= 0 || raiddisks != 0 || layout_str != NULL
                         || chunk != 0 || level != UnSet) {
-                       rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file,
+                       rv = Grow_reshape(devlist->devname, mdfd, c.verbose, c.backup_file,
                                          size, level, layout_str, chunk, raiddisks,
                                          devlist->next,
-                                         assume_clean, force);
+                                         assume_clean, c.force);
                } else if (array_size < 0)
                        pr_err("no changes to --grow\n");
                break;
@@ -1520,8 +1496,8 @@ int main(int argc, char *argv[])
                if (rebuild_map) {
                        RebuildMap();
                }
-               if (scan) {
-                       if (runstop <= 0) {
+               if (c.scan) {
+                       if (c.runstop <= 0) {
                                pr_err("--incremental --scan meaningless without --run.\n");
                                break;
                        }
@@ -1529,10 +1505,10 @@ int main(int argc, char *argv[])
                                pr_err("--incremental --scan --fail not supported.\n");
                                break;
                        }
-                       rv = IncrementalScan(verbose);
+                       rv = IncrementalScan(c.verbose);
                }
                if (!devlist) {
-                       if (!rebuild_map && !scan) {
+                       if (!rebuild_map && !c.scan) {
                                pr_err("--incremental requires a device.\n");
                                rv = 1;
                        }
@@ -1545,12 +1521,12 @@ int main(int argc, char *argv[])
                }
                if (devmode == 'f')
                        rv = IncrementalRemove(devlist->devname, remove_path,
-                                              verbose-quiet);
+                                              c.verbose);
                else
-                       rv = Incremental(devlist->devname, verbose-quiet,
-                                        runstop, ss, homehost,
-                                        require_homehost, autof,
-                                        freeze_reshape);
+                       rv = Incremental(devlist->devname, c.verbose,
+                                        c.runstop, ss, c.homehost,
+                                        c.require_homehost, c.autof,
+                                        c.freeze_reshape);
                break;
        case AUTODETECT:
                autodetect();
@@ -1708,7 +1684,7 @@ static int misc_scan(char devmode, int verbose, int export, int test,
        return rv;
 }
 
-static int stop_scan(int quiet)
+static int stop_scan(int verbose)
 {
        /* apply --stop to all devices in /proc/mdstat */
        /* Due to possible stacking of devices, repeat until
@@ -1734,7 +1710,7 @@ static int stop_scan(int quiet)
                        }
                        mdfd = open_mddev(name, 1);
                        if (mdfd >= 0) {
-                               if (Manage_runstop(name, mdfd, -1, quiet?1:last?0:-1))
+                               if (Manage_runstop(name, mdfd, -1, verbose, !last))
                                        err = 1;
                                else
                                        progress = 1;
@@ -1754,7 +1730,7 @@ 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 supertype *ss, int force)
 {
        struct mddev_dev *dv;
        int rv = 0;
@@ -1770,12 +1746,12 @@ static int misc_list(struct mddev_dev *devlist,
                        continue;
                case KillOpt: /* Zero superblock */
                        if (ss)
-                               rv |= Kill(dv->devname, ss, force, quiet,0);
+                               rv |= Kill(dv->devname, ss, force, verbose,0);
                        else {
-                               int q = quiet;
+                               int v = verbose;
                                do {
-                                       rv |= Kill(dv->devname, NULL, force, q, 0);
-                                       q = 1;
+                                       rv |= Kill(dv->devname, NULL, force, v, 0);
+                                       v = -1;
                                } while (rv == 0);
                                rv &= ~2;
                        }
@@ -1788,9 +1764,9 @@ static int misc_list(struct mddev_dev *devlist,
                case WaitOpt:
                        rv |= Wait(dv->devname); continue;
                case Waitclean:
-                       rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
+                       rv |= WaitClean(dv->devname, -1, verbose); continue;
                case KillSubarray:
-                       rv |= Kill_subarray(dv->devname, subarray, quiet);
+                       rv |= Kill_subarray(dv->devname, subarray, verbose);
                        continue;
                case UpdateSubarray:
                        if (update == NULL) {
@@ -1799,16 +1775,16 @@ static int misc_list(struct mddev_dev *devlist,
                                continue;
                        }
                        rv |= Update_subarray(dv->devname, subarray,
-                                             update, ident, quiet);
+                                             update, ident, verbose);
                        continue;
                }
                mdfd = open_mddev(dv->devname, 1);
                if (mdfd>=0) {
                        switch(dv->disposition) {
                        case 'R':
-                               rv |= Manage_runstop(dv->devname, mdfd, 1, quiet); break;
+                               rv |= Manage_runstop(dv->devname, mdfd, 1, verbose, 0); break;
                        case 'S':
-                               rv |= Manage_runstop(dv->devname, mdfd, -1, quiet); break;
+                               rv |= Manage_runstop(dv->devname, mdfd, -1, verbose, 0); break;
                        case 'o':
                                rv |= Manage_ro(dv->devname, mdfd, 1); break;
                        case 'w':