]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - mdadm.c
mdadm: improve the dlm locking mechanism for clustered raid
[thirdparty/mdadm.git] / mdadm.c
diff --git a/mdadm.c b/mdadm.c
index b689e328dffebea6a952b4254d5ecfa2e68401bc..5afe4155d7011f2f3b653ff162dedeb940cdd911 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -57,6 +57,7 @@ int main(int argc, char *argv[])
        struct mddev_dev *devlist = NULL;
        struct mddev_dev **devlistend = & devlist;
        struct mddev_dev *dv;
+       mdu_array_info_t array;
        int devs_found = 0;
        char *symlinks = NULL;
        int grow_continue = 0;
@@ -103,6 +104,7 @@ int main(int argc, char *argv[])
        FILE *outf;
 
        int mdfd = -1;
+       int locked = 0;
 
        srandom(time(0) ^ getpid());
 
@@ -619,7 +621,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 */
@@ -1434,6 +1436,22 @@ int main(int argc, char *argv[])
                /* --scan implied --brief unless -vv */
                c.brief = 1;
 
+       if (mode == CREATE) {
+               if (s.bitmap_file && strcmp(s.bitmap_file, "clustered") == 0) {
+                       locked = cluster_get_dlmlock();
+                       if (locked != 1)
+                               exit(1);
+               }
+       } else if (mode == MANAGE || mode == GROW || mode == INCREMENTAL) {
+               if (!md_get_array_info(mdfd, &array) && (devmode != 'c')) {
+                       if (array.state & (1 << MD_SB_CLUSTERED)) {
+                               locked = cluster_get_dlmlock();
+                               if (locked != 1)
+                                       exit(1);
+                       }
+               }
+       }
+
        switch(mode) {
        case MANAGE:
                /* readonly, add/remove, readwrite, runstop */
@@ -1542,8 +1560,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) || s.layout == UnSet)) {
+                               pr_err("only near layout is supported with clustered raid10\n");
                                rv = 1;
                                break;
                        }
@@ -1734,6 +1757,10 @@ int main(int argc, char *argv[])
                autodetect();
                break;
        }
+       if (locked)
+               cluster_release_dlmlock();
+       if (mdfd > 0)
+               close(mdfd);
        exit(rv);
 }
 
@@ -1843,8 +1870,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);
@@ -1857,7 +1883,7 @@ static int misc_scan(char devmode, struct context *c)
                        if (devmode == 'D')
                                rv |= Detail(name, c);
                        else
-                               rv |= WaitClean(name, -1, c->verbose);
+                               rv |= WaitClean(name, c->verbose);
                        put_md_name(name);
                }
        }
@@ -1948,7 +1974,7 @@ static int misc_list(struct mddev_dev *devlist,
                        rv |= Wait(dv->devname);
                        continue;
                case Waitclean:
-                       rv |= WaitClean(dv->devname, -1, c->verbose);
+                       rv |= WaitClean(dv->devname, c->verbose);
                        continue;
                case KillSubarray:
                        rv |= Kill_subarray(dv->devname, c->subarray, c->verbose);