From 3d3dd91e3837d5eb6eeaa876c39153f2b0a4929d Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Thu, 14 Dec 2006 17:33:10 +1100 Subject: [PATCH] Support --uuid= with --create to choose your own UUID. --- ChangeLog | 1 + Create.c | 4 ++-- Kill.c | 2 +- mdadm.8 | 10 ++++++++++ mdadm.c | 2 ++ mdadm.h | 4 ++-- super0.c | 29 ++++++++++++++++++----------- super1.c | 31 +++++++++++++++++++++++-------- 8 files changed, 59 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4e5db30..38ae4887 100644 --- 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 diff --git a/Create.c b/Create.c index 2a30ace7..21e578b8 100644 --- 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 dc6baa15..3924cc1c 100644 --- 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 b618f5a6..61604627 100644 --- 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 5fb1b8de..b5dce73a 100644 --- 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 f88eb23f..b4bf3435 100644 --- 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); diff --git a/super0.c b/super0.c index 770d96e9..757d9056 100644 --- 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, diff --git a/super1.c b/super1.c index 88f15024..eb6499e9 100644 --- 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); -- 2.39.2