diff options
author | NeilBrown <neilb@suse.de> | 2008-11-04 20:51:12 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2008-11-04 20:51:12 +1100 |
commit | f2e55eccfb92969c3e11bc5d4883315f2e866a14 (patch) | |
tree | 41d9383f638fa80ca94f8b79afe8bceb9adca1cd | |
parent | f05641cf7a250bda189f16d9c6b917683e5c9aad (diff) |
mdopen: use small sequence number for uniquifying array names.
Rather than appending the md minor number, we now append a small
sequence number to make sure name in /dev/md/ that aren't LOCAL are
unique. As the map file is locked while we do this, we are sure
of no losing any races.
Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r-- | mapfile.c | 15 | ||||
-rw-r--r-- | mdadm.h | 3 | ||||
-rw-r--r-- | mdassemble.c | 4 | ||||
-rw-r--r-- | mdopen.c | 32 |
4 files changed, 44 insertions, 10 deletions
@@ -245,3 +245,18 @@ struct map_ent *map_by_devnum(struct map_ent **map, int devnum) return mp; return NULL; } + +struct map_ent *map_by_name(struct map_ent **map, char *name) +{ + struct map_ent *mp; + if (!*map) + map_read(map); + + for (mp = *map ; mp ; mp = mp->next) { + if (strncmp(mp->path, "/dev/md/", 8) != 0) + continue; + if (strcmp(mp->path+8, name) == 0) + return mp; + } + return NULL; +} @@ -320,7 +320,8 @@ struct map_ent { extern int map_update(struct map_ent **mpp, int devnum, char *metadata, int uuid[4], char *path); extern struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]); -struct map_ent *map_by_devnum(struct map_ent **map, int devnum); +extern struct map_ent *map_by_devnum(struct map_ent **map, int devnum); +extern struct map_ent *map_by_name(struct map_ent **map, char *name); extern void map_read(struct map_ent **melp); extern int map_write(struct map_ent *mel); extern void map_delete(struct map_ent **mapp, int devnum); diff --git a/mdassemble.c b/mdassemble.c index 02afc2d4..a680378a 100644 --- a/mdassemble.c +++ b/mdassemble.c @@ -84,6 +84,10 @@ int map_update(struct map_ent **mpp, int devnum, char *metadata, { return 0; } +struct map_ent *map_by_name(struct map_ent **mpp, char *name) +{ + return NULL; +} int rv; int mdfd = -1; @@ -269,19 +269,33 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, * reasonable length and remove '/' */ char *cp; + struct map_ent *map = NULL; + int conflict = 1; + int unum = 0; + int cnlen; strncpy(cname, name, 200); cname[200] = 0; while ((cp = strchr(cname, '/')) != NULL) *cp = '-'; - if (trustworthy == METADATA) - /* always add device number to metadata */ - sprintf(cname+strlen(cname), "%d", num); - else if (trustworthy == FOREIGN && - strchr(cname, ':') == NULL) - /* add _%d to FOREIGN array that don't have - * a 'host:' prefix - */ - sprintf(cname+strlen(cname), "_%d", num<0?(-1-num):num); + if (trustworthy == LOCAL || + (trustworthy == FOREIGN && strchr(cname, ':') != NULL)) { + /* Only need suffix if there is a conflict */ + if (map_by_name(&map, cname) == NULL) + conflict = 0; + } + cnlen = strlen(cname); + while (conflict) { + if (trustworthy == METADATA) + sprintf(cname+cnlen, "%d", unum); + else + /* add _%d to FOREIGN array that don't + * a 'host:' prefix + */ + sprintf(cname+cnlen, "_%d", unum); + unum++; + if (map_by_name(&map, cname) == NULL) + conflict = 0; + } } if (cname[0] == 0) strcpy(chosen, devname); |