]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Support --uuid= with --create to choose your own UUID.
authorNeil Brown <neilb@suse.de>
Thu, 14 Dec 2006 06:33:10 +0000 (17:33 +1100)
committerNeil Brown <neilb@suse.de>
Thu, 14 Dec 2006 06:33:10 +0000 (17:33 +1100)
ChangeLog
Create.c
Kill.c
mdadm.8
mdadm.c
mdadm.h
super0.c
super1.c

index c4e5db3044657f16920995a612207398f91f3174..38ae4887674edfda16c161ceddfd94364caccc12 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -27,6 +27,7 @@ Changes Prior to this release
        of error message.
     -   Don't hold md device open for so long in --monitor mode - map_dev
        can be slow and interferes with trying to stop the array.
+    -   Support --uuid= with --create to choose your own UUID.
 
 Changes Prior to 2.5.6 release
     -   Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled
index 2a30ace7e0acd54eea67bb22946d4ae96611423b..21e578b8bb0b7c4bd9860400f1635e0f5302665b 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -34,7 +34,7 @@
 
 int Create(struct supertype *st, char *mddev, int mdfd,
           int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
-          char *name, char *homehost,
+          char *name, char *homehost, int *uuid,
           int subdevs, mddev_dev_t devlist,
           int runstop, int verbose, int force, int assume_clean,
           char *bitmap_file, int bitmap_chunk, int write_behind, int delay)
@@ -407,7 +407,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                name += 2;
                }
        }
-       if (!st->ss->init_super(st, &super, &array, size, name, homehost))
+       if (!st->ss->init_super(st, &super, &array, size, name, homehost, uuid))
                return 1;
 
        if (bitmap_file && vers < 9003) {
diff --git a/Kill.c b/Kill.c
index dc6baa159aa8e44e9be93839b01c985fd526478e..3924cc1cbfcdf20445e1587a70163b714034f0be 100644 (file)
--- a/Kill.c
+++ b/Kill.c
@@ -67,7 +67,7 @@ int Kill(char *dev, int force, int quiet)
                mdu_array_info_t info;
                info.major_version = -1; /* zero superblock */
                free(super);
-               st->ss->init_super(st, &super, &info, 0, "", NULL);
+               st->ss->init_super(st, &super, &info, 0, "", NULL, NULL);
                if (st->ss->store_super(st, fd, super)) {
                        if (!quiet)
                                fprintf(stderr, Name ": Could not zero superblock on %s\n",
diff --git a/mdadm.8 b/mdadm.8
index b618f5a671a2adaae1819f0ad4e16042cddb2d0b..61604627f106c7d5085f9cc4db0d4afc64740fd2 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -1259,6 +1259,16 @@ is being created, then the name
 .B home
 will be used.
 
+A new array will normally get a randomly assigned 128bit UUID which is
+very likely to be unique.  If you have a specific need, you can choose
+a UUID for the array by giving the
+.B --uuid=
+option.  Be warned that creating two arrays with the same UUID is a
+recipe for disaster.  Also, using
+.B --uuid=
+when creating a v0.90 array will silently override any
+.B --homehost=
+setting.
 '''If the
 '''.B --size
 '''option is given, it is not necessary to list any component-devices in this command.
diff --git a/mdadm.c b/mdadm.c
index 5fb1b8de503efb36725dd5acf88cac0790baf090..b5dce73af2482ebd4123aefa103aef0a1612e00f 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -516,6 +516,7 @@ int main(int argc, char *argv[])
                        continue;
 
                        /* now for the Assemble options */
+               case O(CREATE,'u'): /* uuid of array */
                case O(ASSEMBLE,'u'): /* uuid of array */
                        if (ident.uuid_set) {
                                fprintf(stderr, Name ": uuid cannot be set twice.  "
@@ -1136,6 +1137,7 @@ int main(int argc, char *argv[])
 
                rv = Create(ss, devlist->devname, mdfd, chunk, level, layout, size<0 ? 0 : size,
                            raiddisks, sparedisks, ident.name, 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);
                break;
diff --git a/mdadm.h b/mdadm.h
index f88eb23fd02347e77f77f104cee87dc8103e69b9..b4bf343524ef65cfc1b676e8ebdc74ddd2212a64 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -319,7 +319,7 @@ extern struct superswitch {
        int (*update_super)(struct mdinfo *info, void *sbv, char *update,
                            char *devname, int verbose,
                            int uuid_set, char *homehost);
-       int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info, unsigned long long size, char *name, char *homehost);
+       int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info, unsigned long long size, char *name, char *homehost, int *uuid);
        void (*add_to_super)(void *sbv, mdu_disk_info_t *dinfo);
        int (*store_super)(struct supertype *st, int fd, void *sbv);
        int (*write_init_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname);
@@ -409,7 +409,7 @@ extern int Build(char *mddev, int mdfd, int chunk, int level, int layout,
 
 extern int Create(struct supertype *st, char *mddev, int mdfd,
                  int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
-                 char *name, char *homehost,
+                 char *name, char *homehost, int *uuid,
                  int subdevs, mddev_dev_t devlist,
                  int runstop, int verbose, int force, int assume_clean,
                  char *bitmap_file, int bitmap_chunk, int write_behind, int delay);
index 770d96e990ec492ea6b71154d2a19d219644bcea..757d9056672b2f1110acbdae5ea2d08da19fde73 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -505,11 +505,11 @@ static int update_super0(struct mdinfo *info, void *sbv, char *update,
 
 
 static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info,
-                      unsigned long long size, char *ignored_name, char *homehost)
+                      unsigned long long size, char *ignored_name, char *homehost,
+                      int *uuid)
 {
        mdp_super_t *sb = malloc(MD_SB_BYTES + sizeof(bitmap_super_t));
        int spares;
-       int rfd;
        memset(sb, 0, MD_SB_BYTES + sizeof(bitmap_super_t));
 
        if (info->major_version == -1) {
@@ -525,14 +525,11 @@ static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info,
                return 0;
        }
 
-       rfd = open("/dev/urandom", O_RDONLY);
        sb->md_magic = MD_SB_MAGIC;
        sb->major_version = 0;
        sb->minor_version = 90;
        sb->patch_version = 0;
        sb->gvalid_words = 0; /* ignored */
-       if (rfd < 0 || read(rfd, &sb->set_uuid0, 4) != 4)
-               sb->set_uuid0 = random();
        sb->ctime = time(0);
        sb->level = info->level;
        if (size != info->size)
@@ -542,13 +539,23 @@ static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info,
        sb->raid_disks = info->raid_disks;
        sb->md_minor = info->md_minor;
        sb->not_persistent = 0;
-       if (rfd < 0 || read(rfd, &sb->set_uuid1, 12) != 12) {
-               sb->set_uuid1 = random();
-               sb->set_uuid2 = random();
-               sb->set_uuid3 = random();
+       if (uuid) {
+               sb->set_uuid0 = uuid[0];
+               sb->set_uuid1 = uuid[1];
+               sb->set_uuid2 = uuid[2];
+               sb->set_uuid3 = uuid[3];
+       } else {
+               int rfd = open("/dev/urandom", O_RDONLY);
+               if (rfd < 0 || read(rfd, &sb->set_uuid0, 4) != 4)
+                       sb->set_uuid0 = random();
+               if (rfd < 0 || read(rfd, &sb->set_uuid1, 12) != 12) {
+                       sb->set_uuid1 = random();
+                       sb->set_uuid2 = random();
+                       sb->set_uuid3 = random();
+               }
+               if (rfd >= 0)
+                       close(rfd);
        }
-       if (rfd >= 0)
-               close(rfd);
        if (homehost) {
                char buf[20];
                char *hash = sha1_buffer(homehost,
index 88f1502455d2dab9f06f2a39b0eb467a26973b43..eb6499e912e400980115b29d615abc01123d37d6 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -600,7 +600,7 @@ static int update_super1(struct mdinfo *info, void *sbv, char *update,
 }
 
 static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
-                      unsigned long long size, char *name, char *homehost)
+                      unsigned long long size, char *name, char *homehost, int *uuid)
 {
        struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t) +
                                             sizeof(struct misc_dev_info));
@@ -627,14 +627,29 @@ static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
        sb->feature_map = 0;
        sb->pad0 = 0;
 
-       if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
-           read(rfd, sb->set_uuid, 16) != 16) {
-               *(__u32*)(sb->set_uuid) = random();
-               *(__u32*)(sb->set_uuid+4) = random();
-               *(__u32*)(sb->set_uuid+8) = random();
-               *(__u32*)(sb->set_uuid+12) = random();
+       if (uuid) {
+               if (super1.swapuuid) {
+                       unsigned char *ac = (unsigned char *)sb->set_uuid;
+                       unsigned char *bc = (unsigned char *)uuid;
+                       int i;
+                       for (i=0; i<16; i+= 4) {
+                               ac[i+0] = bc[i+3];
+                               ac[i+1] = bc[i+2];
+                               ac[i+2] = bc[i+1];
+                               ac[i+3] = bc[i+0];
+                       }
+               } else
+                       memcpy(sb->set_uuid, uuid, 16);
+       } else {
+               if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
+                   read(rfd, sb->set_uuid, 16) != 16) {
+                       *(__u32*)(sb->set_uuid) = random();
+                       *(__u32*)(sb->set_uuid+4) = random();
+                       *(__u32*)(sb->set_uuid+8) = random();
+                       *(__u32*)(sb->set_uuid+12) = random();
+               }
+               if (rfd >= 0) close(rfd);
        }
-       if (rfd >= 0) close(rfd);
 
        if (name == NULL || *name == 0) {
                sprintf(defname, "%d", info->md_minor);