- st->ss->getinfo_super(st, &info);
- if (md->devnum > 0)
- path = map_dev(MD_MAJOR, md->devnum, 0);
- else
- path = map_dev(mdp, (-1-md->devnum)<< 6, 0);
- map_add(&map, md->devnum,
- info.text_version,
- info.uuid, path ? : "/unknown");
+ if (subarray)
+ info = st->ss->container_content(st, subarray);
+ else {
+ info = xmalloc(sizeof(*info));
+ st->ss->getinfo_super(st, info, NULL);
+ }
+ if (!info)
+ continue;
+
+ devid = devnm2devid(md->devnm);
+ path = map_dev(major(devid), minor(devid), 0);
+ if (path == NULL ||
+ strncmp(path, "/dev/md/", 8) != 0) {
+ /* We would really like a name that provides
+ * an MD_DEVNAME for udev.
+ * The name needs to be unique both in /dev/md/
+ * and in this mapfile.
+ * It needs to match what -I or -As would come
+ * up with.
+ * That means:
+ * Check if array is in mdadm.conf
+ * - if so use that.
+ * determine trustworthy from homehost etc
+ * find a unique name based on metadata name.
+ *
+ */
+ struct mddev_ident *match = conf_match(st, info,
+ NULL, 0,
+ NULL);
+ struct stat stb;
+ if (match && match->devname && match->devname[0] == '/') {
+ path = match->devname;
+ if (path[0] != '/') {
+ strcpy(namebuf, "/dev/md/");
+ strcat(namebuf, path);
+ path = namebuf;
+ }
+ } else {
+ int unum = 0;
+ char *sep = "_";
+ const char *name;
+ int conflict = 1;
+ if ((homehost == NULL ||
+ st->ss->match_home(st, homehost) != 1) &&
+ st->ss->match_home(st, "any") != 1 &&
+ (require_homehost
+ || ! conf_name_is_free(info->name)))
+ /* require a numeric suffix */
+ unum = 0;
+ else
+ /* allow name to be used as-is if no conflict */
+ unum = -1;
+ name = info->name;
+ if (!*name) {
+ name = st->ss->name;
+ if (!isdigit(name[strlen(name)-1]) &&
+ unum == -1) {
+ unum = 0;
+ sep = "";
+ }
+ }
+ if (strchr(name, ':')) {
+ /* Probably a uniquifying
+ * hostname prefix. Allow
+ * without a suffix, and strip
+ * hostname if it is us.
+ */
+ if (homehost && unum == -1 &&
+ strncmp(name, homehost,
+ strlen(homehost)) == 0 &&
+ name[strlen(homehost)] == ':')
+ name += strlen(homehost)+1;
+ unum = -1;
+ }
+
+ while (conflict) {
+ if (unum >= 0)
+ sprintf(namebuf, "/dev/md/%s%s%d",
+ name, sep, unum);
+ else
+ sprintf(namebuf, "/dev/md/%s",
+ name);
+ unum++;
+ if (lstat(namebuf, &stb) != 0 &&
+ (map == NULL ||
+ !map_by_name(&map, namebuf+8)))
+ conflict = 0;
+ }
+ path = namebuf;
+ }
+ }
+ map_add(&map, md->devnm,
+ info->text_version,
+ info->uuid, path);