From d7288ddc3a06a0912f5f0a3f23ccca76a66ff332 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 18 Sep 2008 16:08:10 +1000 Subject: [PATCH 1/1] Use uuid as /dev name when assembling array of uncertain origin. If we aren't sure that the array belongs to 'this' host, use the uuid to choose a name to avoid any conflict. --- Assemble.c | 31 ++++++++++++++++++++++------ Incremental.c | 56 ++++++++++++++++++++++++++++++++++----------------- mdadm.h | 2 ++ util.c | 19 +++++++++++++++++ 4 files changed, 84 insertions(+), 24 deletions(-) diff --git a/Assemble.c b/Assemble.c index 148ddbf7..3d29d41b 100644 --- a/Assemble.c +++ b/Assemble.c @@ -139,6 +139,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, struct mdinfo info; char *avail; int nextspare = 0; + int uuid_for_name = 0; memset(&info, 0, sizeof(info)); @@ -296,15 +297,28 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, if (mdfd < 0) { if (tst == NULL || tst->sb == NULL) continue; - if (update == NULL && - tst->ss->match_home(tst, homehost)==0) { + switch(tst->ss->match_home(tst, homehost)) + { + case 1: /* happy with match. */ + break; + case -1: /* cannot match */ + uuid_for_name = 1; + break; + case 0: /* Doesn't match */ + if (update) + /* We are changing the name*/ + break; if ((inargv && verbose >= 0) || verbose > 0) - fprintf(stderr, Name ": %s is not built for host %s.\n", + fprintf(stderr, Name ": %s is not built for " + "host %s - using UUID for " + "device name.\n", devname, homehost); + /* Auto-assemble, and this is not a usable host */ /* if update != NULL, we are updating the host * name... */ - goto loop; + uuid_for_name = 1; + break; } } /* If we are this far, then we are nearly commited to this device. @@ -381,12 +395,17 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, */ mdu_array_info_t inf; char *c; + char nbuf[64]; if (!st || !st->sb) { return 2; } st->ss->getinfo_super(st, &info); - c = strchr(info.name, ':'); - if (c) c++; else c= info.name; + if (uuid_for_name) + c = fname_from_uuid(st, &info, nbuf); + else { + c = strchr(info.name, ':'); + if (c) c++; else c= info.name; + } if (isdigit(*c) && ((ident->autof & 7)==4 || (ident->autof&7)==6)) /* /dev/md/d0 style for partitionable */ asprintf(&mddev, "/dev/md/d%s", c); diff --git a/Incremental.c b/Incremental.c index f57c9bb1..869ae839 100644 --- a/Incremental.c +++ b/Incremental.c @@ -85,7 +85,9 @@ int Incremental(char *devname, int verbose, int runstop, int dfd, mdfd; char *avail; int active_disks; - + int uuid_for_name = 0; + char *name_to_use; + char nbuf[64]; struct createinfo *ci = conf_get_create_info(); @@ -217,12 +219,8 @@ int Incremental(char *devname, int verbose, int runstop, /* 3a/ if not, check for homehost match. If no match, reject. */ if (!match) { if (homehost == NULL || - st->ss->match_home(st, homehost) != 1) { - if (verbose >= 0) - fprintf(stderr, Name - ": not found in mdadm.conf and not identified by homehost.\n"); - return 2; - } + st->ss->match_home(st, homehost) != 1) + uuid_for_name = 1; } /* 4/ Determine device number. */ /* - If in mdadm.conf with std name, use that */ @@ -232,9 +230,20 @@ int Incremental(char *devname, int verbose, int runstop, /* - Choose a free, high number. */ /* - Use a partitioned device unless strong suggestion not to. */ /* e.g. auto=md */ + mp = map_by_uuid(&map, info.uuid); + + if (uuid_for_name && ! mp) { + name_to_use = fname_from_uuid(st, &info, nbuf); + if (verbose >= 0) + fprintf(stderr, Name + ": not found in mdadm.conf and not identified by homehost" + " - using uuid based name\n"); + } else + name_to_use = info.name; + if (match && is_standard(match->devname, &devnum)) /* We have devnum now */; - else if ((mp = map_by_uuid(&map, info.uuid)) != NULL) + else if (mp != NULL) devnum = mp->devnum; else { /* Have to guess a bit. */ @@ -247,11 +256,11 @@ int Incremental(char *devname, int verbose, int runstop, use_partitions = 0; if (st->ss->external) use_partitions = 0; - np = strchr(info.name, ':'); + np = strchr(name_to_use, ':'); if (np) np++; else - np = info.name; + np = name_to_use; devnum = strtoul(np, &ep, 10); if (ep > np && *ep == 0) { /* This is a number. Let check that it is unused. */ @@ -290,9 +299,10 @@ int Incremental(char *devname, int verbose, int runstop, } else devnum = use_partitions ? (-1-devnum) : devnum; } - mdfd = open_mddev_devnum(match ? match->devname : NULL, + + mdfd = open_mddev_devnum(match ? match->devname : mp ? mp->path : NULL, devnum, - info.name, + name_to_use, chosen_name, autof >> 3); if (mdfd < 0) { fprintf(stderr, Name ": failed to open %s: %s.\n", @@ -781,23 +791,33 @@ int Incremental_container(struct supertype *st, char *devname, int verbose, char *n; int working = 0, preexist = 0; struct map_ent *mp, *map = NULL; + char nbuf[64]; + char *name_to_use; if ((autof&7) == 3 || (autof&7) == 5) usepart = 0; mp = map_by_uuid(&map, ra->uuid); + + name_to_use = ra->name; + if (! name_to_use || + ! *name_to_use || + (*devname != '/' || strncmp("UUID-", strrchr(devname,'/')+1,5) == 0) + ) + name_to_use = fname_from_uuid(st, ra, nbuf); + if (mp) devnum = mp->devnum; else { - n = ra->name; + n = name_to_use; if (*n == 'd') n++; if (*n && devnum < 0) { devnum = strtoul(n, &n, 10); if (devnum >= 0 && (*n == 0 || *n == ' ')) { /* Use this devnum */ - usepart = (ra->name[0] == 'd'); + usepart = (name_to_use[0] == 'd'); if (mddev_busy(usepart ? (-1-devnum) : devnum)) devnum = -1; } else @@ -805,7 +825,7 @@ int Incremental_container(struct supertype *st, char *devname, int verbose, } if (devnum < 0) { - char *nm = ra->name; + char *nm = name_to_use; char nbuf[1024]; struct stat stb; if (strchr(nm, ':')) @@ -831,7 +851,7 @@ int Incremental_container(struct supertype *st, char *devname, int verbose, else devnum = find_free_devnum(usepart); } - mdfd = open_mddev_devnum(mp ? mp->path : NULL, devnum, ra->name, + mdfd = open_mddev_devnum(mp ? mp->path : NULL, devnum, name_to_use, chosen_name, autof>>3); if (mdfd < 0) { @@ -870,7 +890,7 @@ int Incremental_container(struct supertype *st, char *devname, int verbose, sysfs_set_safemode(ra, ra->safe_mode_delay); if (verbose >= 0) { fprintf(stderr, Name - "Started %s with %d devices", + ": Started %s with %d devices", chosen_name, working + preexist); if (preexist) fprintf(stderr, " (%d new)", working); @@ -880,7 +900,7 @@ int Incremental_container(struct supertype *st, char *devname, int verbose, } else if (verbose >= 0) fprintf(stderr, Name - "%s assembled with %d devices but " + ": %s assembled with %d devices but " "not started\n", chosen_name, working); close(mdfd); diff --git a/mdadm.h b/mdadm.h index 7c73b6ac..f70e361b 100644 --- a/mdadm.h +++ b/mdadm.h @@ -763,6 +763,8 @@ extern int match_oneof(char *devices, char *devname); extern void uuid_from_super(int uuid[4], mdp_super_t *super); extern int same_uuid(int a[4], int b[4], int swapuuid); extern void copy_uuid(void *a, int b[4], int swapuuid); +extern char *fname_from_uuid(struct supertype *st, + struct mdinfo *info, char *buf); extern unsigned long calc_csum(void *super, int bytes); extern int enough(int level, int raid_disks, int layout, int clean, char *avail, int avail_disks); diff --git a/util.c b/util.c index b63251f4..b65d2ad8 100644 --- a/util.c +++ b/util.c @@ -269,6 +269,25 @@ void copy_uuid(void *a, int b[4], int swapuuid) memcpy(a, b, 16); } +char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf) +{ + int i; + char uuid[16]; + char *c = buf; + strcpy(c, "UUID-"); + c += strlen(c); + copy_uuid(uuid, info->uuid, st->ss->swapuuid); + for (i=0; i<16; i++) { + if (i && (i&3)==0) { + strcpy(c, "-"); + c++; + } + sprintf(c,"%02x", (unsigned char)uuid[i]); + c+= 2; + } + return buf; +} + #ifndef MDASSEMBLE int check_ext2(int fd, char *name) { -- 2.39.2