/* Have to guess a bit. */
int use_partitions = 1;
char *np, *ep;
+ char *nm, nbuf[1024];
if ((autof&7) == 3 || (autof&7) == 5)
use_partitions = 0;
np = strchr(info.name, ':');
} else
devnum = -1;
+ if (match)
+ nm = match->devname;
+ else {
+ sprintf(nbuf, "/dev/md/%s", np);
+ nm = nbuf;
+ }
+ if (stat(nm, &stb) == 0 &&
+ S_ISBLK(stb.st_mode) &&
+ major(stb.st_rdev) == (use_partitions ?
+ get_mdp_major() : MD_MAJOR)) {
+ if (use_partitions)
+ devnum = minor(stb.st_rdev) >> MdpMinorShift;
+ else
+ devnum = minor(stb.st_rdev);
+ if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
+ devnum = -1;
+ }
+
if (devnum < 0) {
/* Haven't found anything yet, choose something free */
devnum = find_free_devnum(use_partitions);
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 *sra;
int usepart = 1;
char *n;
int working = 0;
+ char ver[100];
if ((autof&7) == 3 || (autof&7) == 5)
usepart = 0;
devnum = -1;
}
+ if (devnum < 0) {
+ char *nm = ra->name;
+ char nbuf[1024];
+ struct stat stb;
+ if (strchr(nm, ':'))
+ nm = strchr(nm, ':')+1;
+ sprintf(nbuf, "/dev/md/%s", nm);
+
+ if (stat(nbuf, &stb) == 0 &&
+ S_ISBLK(stb.st_mode) &&
+ major(stb.st_rdev) == (usepart ?
+ get_mdp_major() : MD_MAJOR)){
+ if (usepart)
+ devnum = minor(stb.st_rdev)
+ >> MdpMinorShift;
+ else
+ devnum = minor(stb.st_rdev);
+ if (mddev_busy(usepart ? (-1-devnum) : devnum))
+ devnum = -1;
+ }
+ }
+
if (devnum >= 0)
devnum = usepart ? (-1-devnum) : devnum;
else
sra = sysfs_read(mdfd, 0, 0);
+ sprintf(ver, "external:%s", ra->text_version);
+ sysfs_set_str(sra, NULL, "metadata_version", ver);
+
sysfs_set_array(sra, ra);
- for (dev = ra->devs; dev; dev = dev->next) {
- char buf[20];
- int dfd;
- sprintf(buf, "%d:%d", dev->disk.major, dev->disk.minor);
- dfd = dev_open(buf, O_RDONLY);
- if (sysfs_add_disk(sra, dfd, dev) == 0)
+ for (dev = ra->devs; dev; dev = dev->next)
+ if (sysfs_add_disk(sra, dev) == 0)
working++;
- }
+
if (runstop > 0 || working >= ra->array.working_disks) {
switch(ra->array.level) {
case LEVEL_LINEAR:
default:
sysfs_set_str(sra, NULL, "array_state",
"readonly");
+ /* start mdmon if needed. */
+ if (mdmon_running(st->container_dev))
+ signal_mdmon(st->container_dev);
+ else {
+ int dn = st->container_dev;
+ int i;
+ switch(fork()) {
+ case 0:
+ /* FIXME yuk. CLOSE_EXEC?? */
+ for (i=3; i < 100; i++)
+ close(i);
+ execl("./mdmon", "mdmon",
+ map_dev(dev2major(dn),
+ dev2minor(dn),
+ 1), NULL);
+ exit(1);
+ case -1: fprintf(stderr, Name
+ ": cannot fork. "
+ "Array remains readonly\n");
+ return 1;
+ default: ; /* parent - good */
+ }
+ }
break;
}
if (verbose >= 0)
printf("Started %s with %d devices\n",
chosen_name, working);
+ /* FIXME should have an O_EXCL and wait for read-auto */
} else
if (verbose >= 0)
printf("%s assembled with %d devices but "