]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdopen: use small sequence number for uniquifying array names.
authorNeilBrown <neilb@suse.de>
Tue, 4 Nov 2008 09:51:12 +0000 (20:51 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 4 Nov 2008 09:51:12 +0000 (20:51 +1100)
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>
mapfile.c
mdadm.h
mdassemble.c
mdopen.c

index 1c2dc52b31f742d2bf6e160b0638c4fe4523d104..6169d5232e35d7b7d9e73f8eec7db21c48912ff6 100644 (file)
--- a/mapfile.c
+++ b/mapfile.c
@@ -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;
+}
diff --git a/mdadm.h b/mdadm.h
index 8131b60a3bde1861c3962668fb1f722550ac550d..af0f9e8ee6d43f79027825cdb68c63ea22dcdc1e 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -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);
index 02afc2d46c05b557b2d375f7830e44cbdd5e8680..a680378a113c04778b54b93c73ba1cfc9be62dd9 100644 (file)
@@ -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;
index 44efb84068a948c335705bd8f29ebee1a714520a..32ccdbbe404f2cb977e73c38a578b1cd8e3d5c86 100644 (file)
--- a/mdopen.c
+++ b/mdopen.c
@@ -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);