]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - mdadm.c
mdadm: create ident_init()
[thirdparty/mdadm.git] / mdadm.c
diff --git a/mdadm.c b/mdadm.c
index 073b72416858cd5a0daad78adf7dabfbc0182155..74fdec31aa8f527cce10f3a62d3846b3c070c7de 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -49,7 +49,6 @@ int main(int argc, char *argv[])
        int i;
 
        unsigned long long array_size = 0;
-       unsigned long long data_offset = INVALID_SECTORS;
        struct mddev_ident ident;
        char *configfile = NULL;
        int devmode = 0;
@@ -59,7 +58,6 @@ int main(int argc, char *argv[])
        struct mddev_dev *dv;
        mdu_array_info_t array;
        int devs_found = 0;
-       char *symlinks = NULL;
        int grow_continue = 0;
        /* autof indicates whether and how to create device node.
         * bottom 3 bits are style.  Rest (when shifted) are number of parts
@@ -80,6 +78,7 @@ int main(int argc, char *argv[])
                .layout         = UnSet,
                .bitmap_chunk   = UnSet,
                .consistency_policy     = CONSISTENCY_POLICY_UNKNOWN,
+               .data_offset = INVALID_SECTORS,
        };
 
        char sys_hostname[256];
@@ -108,25 +107,13 @@ int main(int argc, char *argv[])
 
        srandom(time(0) ^ getpid());
 
-       ident.uuid_set = 0;
-       ident.level = UnSet;
-       ident.raid_disks = UnSet;
-       ident.super_minor = UnSet;
-       ident.devices = 0;
-       ident.spare_group = NULL;
-       ident.autof = 0;
-       ident.st = NULL;
-       ident.bitmap_fd = -1;
-       ident.bitmap_file = NULL;
-       ident.name[0] = 0;
-       ident.container = NULL;
-       ident.member = NULL;
-
        if (get_linux_version() < 2006015) {
                pr_err("This version of mdadm does not support kernels older than 2.6.15\n");
                exit(1);
        }
 
+       ident_init(&ident);
+
        while ((option_index = -1),
               (opt = getopt_long(argc, argv, shortopt, long_options,
                                  &option_index)) != -1) {
@@ -227,6 +214,7 @@ int main(int argc, char *argv[])
                        shortopt = short_bitmap_auto_options;
                        break;
                case 'F': newmode = MONITOR;
+                       shortopt = short_monitor_options;
                        break;
                case 'G': newmode = GROW;
                        shortopt = short_bitmap_options;
@@ -280,8 +268,8 @@ int main(int argc, char *argv[])
                        else
                                fprintf(stderr, "-%c", opt);
                        fprintf(stderr, " would set mdadm mode to \"%s\", but it is already set to \"%s\".\n",
-                               map_num(modes, newmode),
-                               map_num(modes, mode));
+                               map_num_s(modes, newmode),
+                               map_num_s(modes, mode));
                        exit(2);
                } else if (!mode && newmode) {
                        mode = newmode;
@@ -479,15 +467,15 @@ int main(int argc, char *argv[])
 
                case O(CREATE,DataOffset):
                case O(GROW,DataOffset):
-                       if (data_offset != INVALID_SECTORS) {
+                       if (s.data_offset != INVALID_SECTORS) {
                                pr_err("data-offset may only be specified one. Second value is %s.\n", optarg);
                                exit(2);
                        }
                        if (mode == CREATE && strcmp(optarg, "variable") == 0)
-                               data_offset = VARIABLE_OFFSET;
+                               s.data_offset = VARIABLE_OFFSET;
                        else
-                               data_offset = parse_size(optarg);
-                       if (data_offset == INVALID_SECTORS) {
+                               s.data_offset = parse_size(optarg);
+                       if (s.data_offset == INVALID_SECTORS) {
                                pr_err("invalid data-offset: %s\n",
                                        optarg);
                                exit(2);
@@ -544,7 +532,7 @@ int main(int argc, char *argv[])
                        switch(s.level) {
                        default:
                                pr_err("layout not meaningful for %s arrays.\n",
-                                       map_num(pers, s.level));
+                                       map_num_s(pers, s.level));
                                exit(2);
                        case UnSet:
                                pr_err("raid level must be given before layout.\n");
@@ -610,8 +598,7 @@ int main(int argc, char *argv[])
                                        s.raiddisks, optarg);
                                exit(2);
                        }
-                       s.raiddisks = parse_num(optarg);
-                       if (s.raiddisks <= 0) {
+                       if (parse_num(&s.raiddisks, optarg) != 0 || s.raiddisks <= 0) {
                                pr_err("invalid number of raid devices: %s\n",
                                        optarg);
                                exit(2);
@@ -621,8 +608,7 @@ int main(int argc, char *argv[])
                case O(ASSEMBLE, Nodes):
                case O(GROW, Nodes):
                case O(CREATE, Nodes):
-                       c.nodes = parse_num(optarg);
-                       if (c.nodes < 2) {
+                       if (parse_num(&c.nodes, optarg) != 0 || c.nodes < 2) {
                                pr_err("clustered array needs two nodes at least: %s\n",
                                        optarg);
                                exit(2);
@@ -647,8 +633,7 @@ int main(int argc, char *argv[])
                                        s.level);
                                exit(2);
                        }
-                       s.sparedisks = parse_num(optarg);
-                       if (s.sparedisks < 0) {
+                       if (parse_num(&s.sparedisks, optarg) != 0 || s.sparedisks < 0) {
                                pr_err("invalid number of spare-devices: %s\n",
                                        optarg);
                                exit(2);
@@ -665,13 +650,6 @@ int main(int argc, char *argv[])
                case O(ASSEMBLE,Auto): /* auto-creation of device node */
                        c.autof = parse_auto(optarg, "--auto flag", 0);
                        continue;
-
-               case O(CREATE,Symlinks):
-               case O(BUILD,Symlinks):
-               case O(ASSEMBLE,Symlinks): /* auto creation of symlinks in /dev to /dev/md */
-                       symlinks = optarg;
-                       continue;
-
                case O(BUILD,'f'): /* force honouring '-n 1' */
                case O(BUILD,Force): /* force honouring '-n 1' */
                case O(GROW,'f'): /* ditto */
@@ -732,12 +710,9 @@ int main(int argc, char *argv[])
                        }
                        if (strcmp(optarg, "dev") == 0)
                                ident.super_minor = -2;
-                       else {
-                               ident.super_minor = parse_num(optarg);
-                               if (ident.super_minor < 0) {
-                                       pr_err("Bad super-minor number: %s.\n", optarg);
-                                       exit(2);
-                               }
+                       else if (parse_num(&ident.super_minor, optarg) != 0 || ident.super_minor < 0) {
+                               pr_err("Bad super-minor number: %s.\n", optarg);
+                               exit(2);
                        }
                        continue;
 
@@ -907,8 +882,8 @@ int main(int argc, char *argv[])
 
                case O(MONITOR,'r'): /* rebuild increments */
                case O(MONITOR,Increment):
-                       increments = atoi(optarg);
-                       if (increments > 99 || increments < 1) {
+                       if (parse_num(&increments, optarg) != 0
+                               || increments > 99 || increments < 1) {
                                pr_err("please specify positive integer between 1 and 99 as rebuild increments.\n");
                                exit(2);
                        }
@@ -919,15 +894,10 @@ int main(int argc, char *argv[])
                case O(BUILD,'d'): /* delay for bitmap updates */
                case O(CREATE,'d'):
                        if (c.delay)
-                               pr_err("only specify delay once. %s ignored.\n",
-                                       optarg);
-                       else {
-                               c.delay = parse_num(optarg);
-                               if (c.delay < 1) {
-                                       pr_err("invalid delay: %s\n",
-                                               optarg);
-                                       exit(2);
-                               }
+                               pr_err("only specify delay once. %s ignored.\n", optarg);
+                       else if (parse_num(&c.delay, optarg) != 0 || c.delay < 1) {
+                               pr_err("invalid delay: %s\n", optarg);
+                               exit(2);
                        }
                        continue;
                case O(MONITOR,'f'): /* daemonise */
@@ -1209,18 +1179,16 @@ int main(int argc, char *argv[])
 
                case O(GROW, WriteBehind):
                case O(BUILD, WriteBehind):
-               case O(CREATE, WriteBehind): /* write-behind mode */
+               case O(CREATE, WriteBehind):
                        s.write_behind = DEFAULT_MAX_WRITE_BEHIND;
-                       if (optarg) {
-                               s.write_behind = parse_num(optarg);
-                               if (s.write_behind < 0 ||
-                                   s.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);
-                               }
+                       if (optarg &&
+                           (parse_num(&s.write_behind, optarg) != 0 ||
+                            s.write_behind < 0 || s.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);
                        }
                        continue;
-
                case O(INCREMENTAL, 'r'):
                case O(INCREMENTAL, RebuildMapOpt):
                        rebuild_map = 1;
@@ -1262,10 +1230,10 @@ int main(int argc, char *argv[])
                if (option_index > 0)
                        pr_err(":option --%s not valid in %s mode\n",
                                long_options[option_index].name,
-                               map_num(modes, mode));
+                               map_num_s(modes, mode));
                else
                        pr_err("option -%c not valid in %s mode\n",
-                               opt, map_num(modes, mode));
+                               opt, map_num_s(modes, mode));
                exit(2);
 
        }
@@ -1290,7 +1258,7 @@ int main(int argc, char *argv[])
                if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN &&
                    s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
                        pr_err("--write-journal is not supported with consistency policy: %s\n",
-                              map_num(consistency_policies, s.consistency_policy));
+                              map_num_s(consistency_policies, s.consistency_policy));
                        exit(2);
                }
        }
@@ -1299,12 +1267,12 @@ int main(int argc, char *argv[])
            s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
                if (s.level <= 0) {
                        pr_err("--consistency-policy not meaningful with level %s.\n",
-                              map_num(pers, s.level));
+                              map_num_s(pers, s.level));
                        exit(2);
                } else if (s.consistency_policy == CONSISTENCY_POLICY_JOURNAL &&
                           !s.journaldisks) {
                        pr_err("--write-journal is required for consistency policy: %s\n",
-                              map_num(consistency_policies, s.consistency_policy));
+                              map_num_s(consistency_policies, s.consistency_policy));
                        exit(2);
                } else if (s.consistency_policy == CONSISTENCY_POLICY_PPL &&
                           s.level != 5) {
@@ -1314,14 +1282,14 @@ int main(int argc, char *argv[])
                           (!s.bitmap_file ||
                            strcmp(s.bitmap_file, "none") == 0)) {
                        pr_err("--bitmap is required for consistency policy: %s\n",
-                              map_num(consistency_policies, s.consistency_policy));
+                              map_num_s(consistency_policies, s.consistency_policy));
                        exit(2);
                } else if (s.bitmap_file &&
                           strcmp(s.bitmap_file, "none") != 0 &&
                           s.consistency_policy != CONSISTENCY_POLICY_BITMAP &&
                           s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
                        pr_err("--bitmap is not compatible with consistency policy: %s\n",
-                              map_num(consistency_policies, s.consistency_policy));
+                              map_num_s(consistency_policies, s.consistency_policy));
                        exit(2);
                }
        }
@@ -1337,18 +1305,6 @@ int main(int argc, char *argv[])
                exit(2);
        }
 
-       if (symlinks) {
-               struct createinfo *ci = conf_get_create_info();
-
-               if (strcasecmp(symlinks, "yes") == 0)
-                       ci->symlinks = 1;
-               else if (strcasecmp(symlinks, "no") == 0)
-                       ci->symlinks = 0;
-               else {
-                       pr_err("option --symlinks must be 'no' or 'yes'\n");
-                       exit(2);
-               }
-       }
        /* Ok, got the option parsing out of the way
         * hopefully it's mostly right but there might be some stuff
         * missing
@@ -1361,6 +1317,9 @@ int main(int argc, char *argv[])
 
        if (mode == MANAGE || mode == BUILD || mode == CREATE ||
            mode == GROW || (mode == ASSEMBLE && ! c.scan)) {
+               struct stat stb;
+               int ret;
+
                if (devs_found < 1) {
                        pr_err("an md device must be given in this mode\n");
                        exit(2);
@@ -1373,30 +1332,34 @@ int main(int argc, char *argv[])
                        mdfd = open_mddev(devlist->devname, 1);
                        if (mdfd < 0)
                                exit(1);
-               } else
-                       /* non-existent device is OK */
-                       mdfd = open_mddev(devlist->devname, 0);
-               if (mdfd == -2) {
-                       pr_err("device %s exists but is not an md array.\n", devlist->devname);
-                       exit(1);
-               }
-               if ((int)ident.super_minor == -2) {
-                       struct stat stb;
-                       if (mdfd < 0) {
+
+                       ret = fstat(mdfd, &stb);
+                       if (ret) {
+                               pr_err("fstat failed on %s.\n", devlist->devname);
+                               exit(1);
+                       }
+               } else {
+                       char *bname = basename(devlist->devname);
+
+                       if (strlen(bname) > MD_NAME_MAX) {
+                               pr_err("Name %s is too long.\n", devlist->devname);
+                               exit(1);
+                       }
+
+                       ret = stat(devlist->devname, &stb);
+                       if (ident.super_minor == -2 && ret != 0) {
                                pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n",
-                                       devlist->devname);
+                                      devlist->devname);
+                               exit(1);
+                       }
+
+                       if (!ret && !stat_is_md_dev(&stb)) {
+                               pr_err("device %s exists but is not an md array.\n", devlist->devname);
                                exit(1);
                        }
-                       fstat(mdfd, &stb);
-                       ident.super_minor = minor(stb.st_rdev);
-               }
-               if (mdfd >= 0 && mode != MANAGE && mode != GROW) {
-                       /* We don't really want this open yet, we just might
-                        * have wanted to check some things
-                        */
-                       close(mdfd);
-                       mdfd = -1;
                }
+               if (ident.super_minor == -2)
+                       ident.super_minor = minor(stb.st_rdev);
        }
 
        if (s.raiddisks) {
@@ -1441,7 +1404,7 @@ int main(int argc, char *argv[])
                exit(1);
        }
 
-       if (c.backup_file && data_offset != INVALID_SECTORS) {
+       if (c.backup_file && s.data_offset != INVALID_SECTORS) {
                pr_err("--backup-file and --data-offset are incompatible\n");
                exit(2);
        }
@@ -1612,8 +1575,7 @@ int main(int argc, char *argv[])
 
                rv = Create(ss, devlist->devname,
                            ident.name, ident.uuid_set ? ident.uuid : NULL,
-                           devs_found-1, devlist->next,
-                           &s, &c, data_offset);
+                           devs_found - 1, devlist->next, &s, &c);
                break;
        case MISC:
                if (devmode == 'E') {
@@ -1731,10 +1693,9 @@ int main(int argc, char *argv[])
                                                   c.verbose);
                else if (s.size > 0 || s.raiddisks || s.layout_str ||
                         s.chunk != 0 || s.level != UnSet ||
-                        data_offset != INVALID_SECTORS) {
+                        s.data_offset != INVALID_SECTORS) {
                        rv = Grow_reshape(devlist->devname, mdfd,
-                                         devlist->next,
-                                         data_offset, &c, &s);
+                                         devlist->next, &c, &s);
                } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
                        rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s);
                } else if (array_size == 0)
@@ -1784,8 +1745,7 @@ int main(int argc, char *argv[])
        }
        if (locked)
                cluster_release_dlmlock();
-       if (mdfd > 0)
-               close(mdfd);
+       close_fd(&mdfd);
        exit(rv);
 }