]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - mdadm.c
To support clustered raid10
[thirdparty/mdadm.git] / mdadm.c
diff --git a/mdadm.c b/mdadm.c
index 0f3277382637df5c940242be6861d67234b3b274..87cb33f84ac2f414dfd5a4f636ce116ee34ba2ff 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -78,7 +78,7 @@ int main(int argc, char *argv[])
                .level          = UnSet,
                .layout         = UnSet,
                .bitmap_chunk   = UnSet,
-               .consistency_policy     = UnSet,
+               .consistency_policy     = CONSISTENCY_POLICY_UNKNOWN,
        };
 
        char sys_hostname[256];
@@ -120,6 +120,11 @@ int main(int argc, char *argv[])
        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);
+       }
+
        while ((option_index = -1),
               (opt = getopt_long(argc, argv, shortopt, long_options,
                                  &option_index)) != -1) {
@@ -614,7 +619,7 @@ int main(int argc, char *argv[])
                        c.homecluster = optarg;
                        if (strlen(c.homecluster) > 64) {
                                pr_err("Cluster name too big.\n");
-                               exit(ERANGE);
+                               exit(2);
                        }
                        continue;
                case O(CREATE,'x'): /* number of spare (eXtra) disks */
@@ -1223,8 +1228,7 @@ int main(int argc, char *argv[])
                case O(GROW, 'k'):
                        s.consistency_policy = map_name(consistency_policies,
                                                        optarg);
-                       if (s.consistency_policy == UnSet ||
-                           s.consistency_policy < CONSISTENCY_POLICY_RESYNC) {
+                       if (s.consistency_policy < CONSISTENCY_POLICY_RESYNC) {
                                pr_err("Invalid consistency policy: %s\n",
                                       optarg);
                                exit(2);
@@ -1262,7 +1266,7 @@ int main(int argc, char *argv[])
                        pr_err("--write-journal is only supported for RAID level 4/5/6.\n");
                        exit(2);
                }
-               if (s.consistency_policy != UnSet &&
+               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));
@@ -1270,7 +1274,8 @@ int main(int argc, char *argv[])
                }
        }
 
-       if (mode == CREATE && s.consistency_policy != UnSet) {
+       if (mode == CREATE &&
+           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));
@@ -1537,8 +1542,13 @@ int main(int argc, char *argv[])
                                break;
                        }
 
-                       if (s.level != 1) {
-                               pr_err("--bitmap=clustered is currently supported with RAID mirror only\n");
+                       if (s.level != 1 && s.level != 10) {
+                               pr_err("--bitmap=clustered is currently supported with raid1/10 only\n");
+                               rv = 1;
+                               break;
+                       }
+                       if (s.level == 10 && !is_near_layout_10(s.layout)) {
+                               pr_err("only near layout is supported with clustered raid10\n");
                                rv = 1;
                                break;
                        }
@@ -1631,7 +1641,10 @@ int main(int argc, char *argv[])
                                rv = 1;
                                break;
                        }
-                       sysfs_init(&sra, mdfd, NULL);
+                       if (sysfs_init(&sra, mdfd, NULL)) {
+                               rv = 1;
+                               break;
+                       }
                        if (array_size == MAX_SIZE)
                                err = sysfs_set_str(&sra, NULL, "array_size", "default");
                        else
@@ -1679,7 +1692,7 @@ int main(int argc, char *argv[])
                        rv = Grow_reshape(devlist->devname, mdfd,
                                          devlist->next,
                                          data_offset, &c, &s);
-               } else if (s.consistency_policy != UnSet) {
+               } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
                        rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s);
                } else if (array_size == 0)
                        pr_err("no changes to --grow\n");
@@ -1726,6 +1739,8 @@ int main(int argc, char *argv[])
                autodetect();
                break;
        }
+       if (mdfd > 0)
+               close(mdfd);
        exit(rv);
 }
 
@@ -1835,8 +1850,7 @@ static int misc_scan(char devmode, struct context *c)
                        if (members != member)
                                continue;
                        me = map_by_devnm(&map, e->devnm);
-                       if (me && me->path
-                           && strcmp(me->path, "/unknown") != 0)
+                       if (me && me->path && strcmp(me->path, "/unknown") != 0)
                                name = me->path;
                        if (name == NULL || stat(name, &stb) != 0)
                                name = get_md_name(e->devnm);
@@ -1908,7 +1922,7 @@ static int misc_list(struct mddev_dev *devlist,
        int rv = 0;
 
        for (dv = devlist; dv; dv = (rv & 16) ? NULL : dv->next) {
-               int mdfd;
+               int mdfd = -1;
 
                switch(dv->disposition) {
                case 'D':
@@ -1965,14 +1979,12 @@ static int misc_list(struct mddev_dev *devlist,
                        rv |= SetAction(dv->devname, c->action);
                        continue;
                }
-               switch(dv->devname[0] == '/') {
-                       case 0:
-                               mdfd = open_dev(dv->devname);
-                               if (mdfd >= 0)
-                                       break;
-                       case 1:
-                               mdfd = open_mddev(dv->devname, 1);  
-               }
+
+               if (dv->devname[0] != '/')
+                       mdfd = open_dev(dv->devname);
+               if (dv->devname[0] == '/' || mdfd < 0)
+                       mdfd = open_mddev(dv->devname, 1);
+
                if (mdfd >= 0) {
                        switch(dv->disposition) {
                        case 'R':
@@ -2000,13 +2012,15 @@ int SetAction(char *dev, char *action)
 {
        int fd = open(dev, O_RDONLY);
        struct mdinfo mdi;
+       int retval;
+
        if (fd < 0) {
                pr_err("Couldn't open %s: %s\n", dev, strerror(errno));
                return 1;
        }
-       sysfs_init(&mdi, fd, NULL);
+       retval = sysfs_init(&mdi, fd, NULL);
        close(fd);
-       if (!mdi.sys_name[0]) {
+       if (retval) {
                pr_err("%s is no an md array\n", dev);
                return 1;
        }