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();
- if (autof == 0)
- autof = ci->autof;
/* 1/ Check if device is permitted by mdadm.conf */
match = array_list;
}
- /* 3a/ if not, check for homehost match. If no match, reject. */
+ /* 3a/ if not, check for homehost match. If no match, continue
+ * but don't trust the 'name' in the array. Thus a 'random' minor
+ * number will be assigned, and the device name will be based
+ * on that. */
if (!match) {
if (homehost == NULL ||
- st->ss->match_home(st, homehost) == 0) {
- 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 */
- /* - UUID in /var/run/mdadm.map use that */
+ /* - If in mdadm.conf with std name, get number from name. */
+ /* - UUID in /var/run/mdadm.map get number from mapping */
/* - If name is suggestive, use that. unless in use with */
/* different uuid. */
/* - Choose a free, high number. */
/* - Use a partitioned device unless strong suggestion not to. */
/* e.g. auto=md */
- if (match && is_standard(match->devname, &devnum))
- /* We have devnum now */;
- else if ((mp = map_by_uuid(&map, info.uuid)) != NULL)
+ 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;
+
+ /* There are three possible sources for 'autof': command line,
+ * ARRAY line in mdadm.conf, or CREATE line in mdadm.conf.
+ * ARRAY takes precedence, then command line, then
+ * CREATE.
+ */
+ if (match && match->autof)
+ autof = match->autof;
+ if (autof == 0)
+ autof = ci->autof;
+
+ if (match && (rv = is_standard(match->devname, &devnum))) {
+ devnum = (rv > 0) ? (-1-devnum) : devnum;
+ } else if (mp != NULL)
devnum = mp->devnum;
else {
/* Have to guess a bit. */
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. */
} else
devnum = use_partitions ? (-1-devnum) : devnum;
}
- mdfd = open_mddev_devnum(match ? match->devname : NULL,
+
+ mdfd = create_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",
close(bmfd);
}
sra = sysfs_read(mdfd, devnum, 0);
- if (sra == NULL || active_disks >= info.array.working_disks)
+ if ((sra == NULL || active_disks >= info.array.working_disks)
+ && uuid_for_name == 0)
rv = ioctl(mdfd, RUN_ARRAY, NULL);
else
rv = sysfs_set_str(sra, NULL,
if (ok != 0)
continue;
st->ss->getinfo_super(st, &info);
+ if (!avail) {
+ avail = malloc(info.array.raid_disks);
+ if (!avail) {
+ fprintf(stderr, Name ": out of memory.\n");
+ exit(1);
+ }
+ memset(avail, 0, info.array.raid_disks);
+ *availp = avail;
+ }
+
if (info.disk.state & (1<<MD_DISK_SYNC))
{
- if (avail == NULL) {
- avail = malloc(info.array.raid_disks);
- memset(avail, 0, info.array.raid_disks);
- }
if (cnt == 0) {
cnt++;
max_events = info.events;
mdu_array_info_t array;
mdu_bitmap_file_t bmf;
struct mdinfo *sra;
- int mdfd = open_mddev_devnum(me->path, me->devnum,
+ int mdfd = create_mddev_devnum(me->path, me->devnum,
NULL, path, 0);
if (mdfd < 0)
continue;
return rv;
}
-static char *container2devname(char *devname)
-{
- int fd = open(devname, O_RDONLY);
- char *mdname = NULL;
-
- if (fd >= 0) {
- mdname = devnum2devname(fd2devnum(fd));
- close(fd);
- }
-
- return mdname;
-}
-
int Incremental_container(struct supertype *st, char *devname, int verbose,
int runstop, int autof)
{
struct mdinfo *list = st->ss->container_content(st);
struct mdinfo *ra;
- char *mdname = container2devname(devname);
-
- if (!mdname) {
- fprintf(stderr, Name": failed to determine device name\n");
- return 2;
- }
for (ra = list ; ra ; ra = ra->next) {
- struct mdinfo *dev;
+ struct mdinfo *dev, *sra;
int devnum = -1;
int mdfd;
char chosen_name[1024];
char *n;
int working = 0, preexist = 0;
struct map_ent *mp, *map = NULL;
+ char nbuf[64];
+ char *name_to_use;
+ struct mddev_ident_s *match = NULL;
if ((autof&7) == 3 || (autof&7) == 5)
usepart = 0;
mp = map_by_uuid(&map, ra->uuid);
- if (mp)
+
+ 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) {
+
+ /* Check in mdadm.conf for devices == devname and
+ * member == ra->text_version after second slash.
+ */
+ char *sub = strchr(ra->text_version+1, '/');
+ struct mddev_ident_s *array_list;
+ if (sub) {
+ sub++;
+ array_list = conf_get_ident(NULL);
+ } else
+ array_list = NULL;
+ for(; array_list ; array_list = array_list->next) {
+ int fd;
+ char *dn;
+ if (array_list->member == NULL ||
+ array_list->container == NULL)
+ continue;
+ if (strcmp(array_list->member, sub) != 0)
+ continue;
+ if (array_list->uuid_set &&
+ !same_uuid(ra->uuid, array_list->uuid, st->ss->swapuuid))
+ continue;
+ fd = open(array_list->container, O_RDONLY);
+ if (fd < 0)
+ continue;
+ dn = devnum2devname(fd2devnum(fd));
+ close(fd);
+ if (strncmp(dn, ra->text_version+1,
+ strlen(dn)) != 0 ||
+ ra->text_version[strlen(dn)+1] != '/') {
+ free(dn);
+ continue;
+ }
+ free(dn);
+ /* we have a match */
+ match = array_list;
+ if (verbose>0)
+ fprintf(stderr, Name ": match found for member %s\n",
+ array_list->member);
+ break;
+ }
+ }
+
+ if (match && is_standard(match->devname, &devnum))
+ /* we have devnum now */;
+ else if (mp)
devnum = mp->devnum;
+ else if (is_standard(name_to_use, &devnum))
+ /* have 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
}
if (devnum < 0) {
- char *nm = ra->name;
+ char *nm = name_to_use;
char nbuf[1024];
struct stat stb;
if (strchr(nm, ':'))
else
devnum = find_free_devnum(usepart);
}
- mdfd = open_mddev_devnum(mp ? mp->path : NULL, devnum, ra->name,
+ mdfd = create_mddev_devnum(mp ? mp->path : match ? match->devname : NULL,
+ devnum, name_to_use,
chosen_name, autof>>3);
if (mdfd < 0) {
return 2;
}
+
sysfs_init(ra, mdfd, 0);
- sysfs_set_array(ra, md_get_version(mdfd));
+
+ sra = sysfs_read(mdfd, 0, GET_VERSION);
+ if (sra == NULL || strcmp(sra->text_version, ra->text_version) != 0)
+ if (sysfs_set_array(ra, md_get_version(mdfd)) != 0)
+ return 1;
+ if (sra)
+ sysfs_free(sra);
+
for (dev = ra->devs; dev; dev = dev->next)
if (sysfs_add_disk(ra, dev) == 0)
working++;
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);
} 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);