]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdadm: change the num of cluster node
authorGuoqing Jiang <gqjiang@suse.com>
Wed, 10 Jun 2015 05:42:12 +0000 (13:42 +0800)
committerNeilBrown <neilb@suse.de>
Tue, 16 Jun 2015 23:43:31 +0000 (09:43 +1000)
This extends nodes option for assemble mode, make the num of
cluster node could be change by user.

Before that, it is necessary to ensure there are enough space
for those nodes, calc_bitmap_size is introduced to calculate
the bitmap size of each node.

Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Assemble.c
ReadMe.c
mdadm.8.in
mdadm.c
mdadm.h
super1.c

index 12ac299f2bf3c582e6619de2f6588704f71e6990..07d363c004b556e6ebe95c191697cb28aaac03ad 100644 (file)
@@ -629,6 +629,9 @@ static int load_devices(struct devs *devices, char *devmap,
                        else if (strcmp(c->update, "home-cluster") == 0) {
                                tst->cluster_name = c->homecluster;
                                tst->ss->write_bitmap(tst, dfd, NameUpdate);
                        else if (strcmp(c->update, "home-cluster") == 0) {
                                tst->cluster_name = c->homecluster;
                                tst->ss->write_bitmap(tst, dfd, NameUpdate);
+                       } else if (strcmp(c->update, "nodes") == 0) {
+                               tst->nodes = c->nodes;
+                               err = tst->ss->write_bitmap(tst, dfd, NodeNumUpdate);
                        } else
                                err = tst->ss->update_super(tst, content, c->update,
                                                            devname, c->verbose,
                        } else
                                err = tst->ss->update_super(tst, content, c->update,
                                                            devname, c->verbose,
index c854cd5fe74067aede784712455218afcdee8ff1..d1830e12ccc420b05dd6ba58517fc74176e0641c 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -140,7 +140,7 @@ struct option long_options[] = {
     {"homehost",  1, 0,  HomeHost},
     {"symlinks",  1, 0,  Symlinks},
     {"data-offset",1, 0, DataOffset},
     {"homehost",  1, 0,  HomeHost},
     {"symlinks",  1, 0,  Symlinks},
     {"data-offset",1, 0, DataOffset},
-    {"nodes",1, 0, Nodes},
+    {"nodes",1, 0, Nodes}, /* also for --assemble */
     {"home-cluster",1, 0, ClusterName},
 
     /* For assemble */
     {"home-cluster",1, 0, ClusterName},
 
     /* For assemble */
index 99b02a3098fd4286db7ea41c062c5b9a969d25d4..8b7768d3d5f99d0dd7ec99416506047dbc8c3294 100644 (file)
@@ -1097,6 +1097,7 @@ argument given to this flag can be one of
 .BR summaries ,
 .BR uuid ,
 .BR name ,
 .BR summaries ,
 .BR uuid ,
 .BR name ,
+.BR nodes ,
 .BR homehost ,
 .BR home-cluster ,
 .BR resync ,
 .BR homehost ,
 .BR home-cluster ,
 .BR resync ,
@@ -1149,6 +1150,13 @@ The
 .B name
 option will change the
 .I name
 .B name
 option will change the
 .I name
+of the array as stored in the superblock and bitmap. This option only
+works for clustered environment.
+
+The
+.B nodes
+option will change the
+.I nodes
 of the array as stored in the superblock.  This is only supported for
 version-1 superblocks.
 
 of the array as stored in the superblock.  This is only supported for
 version-1 superblocks.
 
diff --git a/mdadm.c b/mdadm.c
index 426e673c2da871340d2fb3e5fa7306d8440f9ece..c4daf25f99796b97e06a6ad4e6b5ebb2a2dff5a6 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -589,6 +589,7 @@ int main(int argc, char *argv[])
                        }
                        ident.raid_disks = s.raiddisks;
                        continue;
                        }
                        ident.raid_disks = s.raiddisks;
                        continue;
+               case O(ASSEMBLE, Nodes):
                case O(CREATE, Nodes):
                        c.nodes = parse_num(optarg);
                        if (c.nodes <= 0) {
                case O(CREATE, Nodes):
                        c.nodes = parse_num(optarg);
                        if (c.nodes <= 0) {
@@ -744,6 +745,8 @@ int main(int argc, char *argv[])
                                continue;
                        if (strcmp(c.update, "home-cluster")==0)
                                continue;
                                continue;
                        if (strcmp(c.update, "home-cluster")==0)
                                continue;
+                       if (strcmp(c.update, "nodes")==0)
+                               continue;
                        if (strcmp(c.update, "devicesize")==0)
                                continue;
                        if (strcmp(c.update, "no-bitmap")==0)
                        if (strcmp(c.update, "devicesize")==0)
                                continue;
                        if (strcmp(c.update, "no-bitmap")==0)
@@ -782,7 +785,7 @@ int main(int argc, char *argv[])
                                        Name, c.update);
                        }
                        fprintf(outf, "Valid --update options are:\n"
                                        Name, c.update);
                        }
                        fprintf(outf, "Valid --update options are:\n"
-               "     'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n"
+               "     'sparc2.2', 'super-minor', 'uuid', 'name', 'nodes', 'resync',\n"
                "     'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n"
                "     'no-bitmap', 'metadata', 'revert-reshape'\n"
                "     'bbl', 'no-bbl'\n"
                "     'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n"
                "     'no-bitmap', 'metadata', 'revert-reshape'\n"
                "     'bbl', 'no-bbl'\n"
diff --git a/mdadm.h b/mdadm.h
index d8b074990ca04cc0cd9418ee5c7a6dcdf9678770..97892e641cad720bfd99db8729ff8d4ef3879848 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -357,6 +357,7 @@ enum prefix_standard {
 enum bitmap_update {
     NoUpdate,
     NameUpdate,
 enum bitmap_update {
     NoUpdate,
     NameUpdate,
+    NodeNumUpdate,
 };
 
 /* structures read from config file */
 };
 
 /* structures read from config file */
index 167f2cafd1cad9c6f9c46d69cf6cf937710ba6ab..ba74a33126631f0058b916dc68a1cb83e41f96cd 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -134,6 +134,20 @@ struct misc_dev_info {
                                        |MD_FEATURE_NEW_OFFSET          \
                                        )
 
                                        |MD_FEATURE_NEW_OFFSET          \
                                        )
 
+/* return how many bytes are needed for bitmap, for cluster-md each node
+ * should have it's own bitmap */
+static unsigned int calc_bitmap_size(bitmap_super_t *bms, unsigned int boundary)
+{
+       unsigned long long bits, bytes;
+
+       bits = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9);
+       bytes = (bits+7) >> 3;
+       bytes += sizeof(bitmap_super_t);
+       bytes = ROUND_UP(bytes, boundary);
+
+       return bytes;
+}
+
 static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
 {
        unsigned int disk_csum, csum;
 static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
 {
        unsigned int disk_csum, csum;
@@ -2190,6 +2204,7 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
        int towrite, n;
        struct align_fd afd;
        unsigned int i = 0;
        int towrite, n;
        struct align_fd afd;
        unsigned int i = 0;
+       unsigned long long total_bm_space, bm_space_per_node;
 
        switch (update) {
        case NameUpdate:
 
        switch (update) {
        case NameUpdate:
@@ -2199,6 +2214,28 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
                        strncpy((char *)bms->cluster_name, st->cluster_name, 64);
                }
                break;
                        strncpy((char *)bms->cluster_name, st->cluster_name, 64);
                }
                break;
+       case NodeNumUpdate:
+               /* cluster md only supports superblock 1.2 now */
+               if (st->minor_version != 2) {
+                       pr_err("Warning: cluster md only works with superblock 1.2\n");
+                       return -EINVAL;
+               }
+
+               /* Each node has an independent bitmap, it is necessary to calculate the
+                * space is enough or not, first get how many bytes for the total bitmap */
+               bm_space_per_node = calc_bitmap_size(bms, 4096);
+
+               total_bm_space = 512 * (__le64_to_cpu(sb->data_offset) - __le64_to_cpu(sb->super_offset));
+               total_bm_space = total_bm_space - 4096; /* leave another 4k for superblock */
+
+               if (bm_space_per_node * st->nodes > total_bm_space) {
+                       pr_err("Warning: The max num of nodes can't exceed %llu\n",
+                               total_bm_space / bm_space_per_node);
+                       return -ENOMEM;
+               }
+
+               bms->nodes = __cpu_to_le32(st->nodes);
+               break;
        case NoUpdate:
        default:
                break;
        case NoUpdate:
        default:
                break;