unsigned long safe_mode_delay = 0;
char chosen_name[1024];
struct map_ent *map = NULL;
+ unsigned long long newsize;
int major_num = BITMAP_MAJOR_HI;
else
st = NULL;
}
+ if (have_container)
+ subdevs = raiddisks;
}
if (fd >= 0)
close(fd);
- if (have_container) {
- subdevs = 0;
- devlist = NULL;
- }
}
if (st && st->ss->external && sparedisks) {
fprintf(stderr,
fprintf(stderr, Name ": unknown level %d\n", level);
return 1;
}
-
+
+ newsize = size * 2;
if (st && ! st->ss->validate_geometry(st, level, layout, raiddisks,
- chunk, size, NULL, NULL, verbose>=0))
+ chunk, size*2, NULL, &newsize, verbose>=0))
return 1;
+ if (size == 0) {
+ size = newsize / 2;
+ if (size && verbose > 0)
+ fprintf(stderr, Name ": setting size to %lluK\n",
+ (unsigned long long)size);
+ }
/* now look at the subdevs */
info.array.active_disks = 0;
info.array.working_disks = 0;
dnum = 0;
- for (dv=devlist; dv; dv=dv->next, dnum++) {
+ for (dv=devlist; dv && !have_container; dv=dv->next, dnum++) {
char *dname = dv->devname;
unsigned long long freesize;
if (strcasecmp(dname, "missing")==0) {
st = superlist[i]->match_metadata_desc(name);
if (st && !st->ss->validate_geometry
(st, level, layout, raiddisks,
- chunk, size, dname, &freesize,
+ chunk, size*2, dname, &freesize,
verbose > 0))
st = NULL;
}
} else {
if (!st->ss->validate_geometry(st, level, layout,
raiddisks,
- chunk, size, dname,
+ chunk, size*2, dname,
&freesize,
verbose > 0)) {
close(fd);
}
}
+ if (have_container)
+ info.array.working_disks = raiddisks;
if (fail) {
fprintf(stderr, Name ": create aborted\n");
return 1;
/* size is meaningful */
if (!st->ss->validate_geometry(st, level, layout,
raiddisks,
- chunk, minsize,
+ chunk, minsize*2,
NULL, NULL, 0)) {
fprintf(stderr, Name ": devices too large for RAID level %d\n", level);
return 1;
fprintf(stderr, Name ": size set to %lluK\n", size);
}
}
- if (level > 0 && ((maxsize-size)*100 > maxsize)) {
+ if (!have_container && level > 0 && ((maxsize-size)*100 > maxsize)) {
if (runstop != 1 || verbose >= 0)
- fprintf(stderr, Name ": largest drive (%s) exceed size (%lluK) by more than 1%%\n",
+ fprintf(stderr, Name ": largest drive (%s) exceeds size (%lluK) by more than 1%%\n",
maxdisc, size);
warn = 1;
}
abort();
if (dnum == insert_point) {
moved_disk = dv;
+ continue;
}
- if (dnum == insert_point ||
- strcasecmp(dv->devname, "missing")==0)
+ if (strcasecmp(dv->devname, "missing")==0)
continue;
+ if (have_container)
+ moved_disk = NULL;
+ if (have_container && dnum < info.array.raid_disks - 1)
+ /* repeatedly use the container */
+ moved_disk = dv;
switch(pass) {
case 1:
if (dv->writemostly == 1)
inf->disk.state |= (1<<MD_DISK_WRITEMOSTLY);
- if (st->ss->external && st->subarray[0])
- fd = open(dv->devname, O_RDWR);
- else
- fd = open(dv->devname, O_RDWR|O_EXCL);
-
- if (fd < 0) {
- fprintf(stderr, Name ": failed to open %s "
- "after earlier success - aborting\n",
- dv->devname);
- goto abort;
+ if (have_container)
+ fd = -1;
+ else {
+ if (st->ss->external && st->subarray[0])
+ fd = open(dv->devname, O_RDWR);
+ else
+ fd = open(dv->devname, O_RDWR|O_EXCL);
+
+ if (fd < 0) {
+ fprintf(stderr, Name ": failed to open %s "
+ "after earlier success - aborting\n",
+ dv->devname);
+ goto abort;
+ }
+ fstat(fd, &stb);
+ inf->disk.major = major(stb.st_rdev);
+ inf->disk.minor = minor(stb.st_rdev);
}
- fstat(fd, &stb);
- inf->disk.major = major(stb.st_rdev);
- inf->disk.minor = minor(stb.st_rdev);
-
- remove_partitions(fd);
- st->ss->add_to_super(st, &inf->disk,
- fd, dv->devname);
+ if (fd >= 0)
+ remove_partitions(fd);
+ if (st->ss->add_to_super(st, &inf->disk,
+ fd, dv->devname))
+ goto abort;
st->ss->getinfo_super(st, inf);
safe_mode_delay = inf->safe_mode_delay;
- /* getinfo_super might have lost these ... */
- inf->disk.major = major(stb.st_rdev);
- inf->disk.minor = minor(stb.st_rdev);
+ if (have_container && verbose > 0)
+ fprintf(stderr, Name ": Using %s for device %d\n",
+ map_dev(inf->disk.major,
+ inf->disk.minor,
+ 0), dnum);
+
+ if (!have_container) {
+ /* getinfo_super might have lost these ... */
+ inf->disk.major = major(stb.st_rdev);
+ inf->disk.minor = minor(stb.st_rdev);
+ }
break;
case 2:
inf->errors = 0;
}
break;
}
- if (dv == moved_disk && dnum != insert_point) break;
+ if (!have_container &&
+ dv == moved_disk && dnum != insert_point) break;
}
if (pass == 1) {
st->ss->write_init_super(st);
/* No need to start. But we should signal udev to
* create links */
sysfs_uevent(&info, "change");
- ;
+ if (verbose >= 0)
+ fprintf(stderr, Name ": container %s prepared.\n", mddev);
} else if (runstop == 1 || subdevs >= raiddisks) {
if (st->ss->external) {
switch(level) {
ping_monitor(devnum2devname(st->container_dev));
close(container_fd);
}
+ wait_for(chosen_name);
} else {
fprintf(stderr, Name ": not starting array - not enough devices.\n");
}