summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--Create.c4
-rw-r--r--Kill.c2
-rw-r--r--mdadm.810
-rw-r--r--mdadm.c2
-rw-r--r--mdadm.h4
-rw-r--r--super0.c29
-rw-r--r--super1.c31
8 files changed, 59 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index c4e5db3..38ae488 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 2a30ace..21e578b 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 dc6baa1..3924cc1 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 b618f5a..6160462 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 5fb1b8d..b5dce73 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 f88eb23..b4bf343 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 770d96e..757d905 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 88f1502..eb6499e 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);