Support --uuid= with --create to choose your own UUID.

This commit is contained in:
Neil Brown 2006-12-14 17:33:10 +11:00
parent 4855f95c70
commit 3d3dd91e38
8 changed files with 59 additions and 24 deletions

View File

@ -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

View File

@ -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) {

2
Kill.c
View File

@ -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",

10
mdadm.8
View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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);