&chunk, size*2, NULL, &newsize, verbose>=0))
return 1;
- if (chunk) {
+ if (chunk && chunk != UnSet) {
newsize &= ~(unsigned long long)(chunk*2 - 1);
- size &= ~(unsigned long long)(chunk - 1);
+ if (do_default_chunk) {
+ /* default chunk was just set */
+ if (verbose > 0)
+ fprintf(stderr, Name ": chunk size "
+ "defaults to %dK\n", chunk);
+ size &= ~(unsigned long long)(chunk - 1);
+ do_default_chunk = 0;
+ }
}
+
if (size == 0) {
size = newsize / 2;
if (size && verbose > 0)
for (dv=devlist; dv && !have_container; dv=dv->next, dnum++) {
char *dname = dv->devname;
unsigned long long freesize;
+ int dfd;
+
if (strcasecmp(dname, "missing")==0) {
if (first_missing > dnum)
first_missing = dnum;
missing_disks ++;
continue;
}
+ dfd = open(dname, O_RDONLY);
+ if (dfd < 0) {
+ fprintf(stderr, Name ": cannot open %s: %s\n",
+ dname, strerror(errno));
+ exit(2);
+ }
+ if (fstat(dfd, &stb) != 0 ||
+ (stb.st_mode & S_IFMT) != S_IFBLK) {
+ close(dfd);
+ fprintf(stderr, Name ": %s is not a block device\n",
+ dname);
+ exit(2);
+ }
+ close(dfd);
info.array.working_disks++;
if (dnum < raiddisks)
info.array.active_disks++;
verbose > 0)) {
free(st);
st = NULL;
- chunk = do_default_chunk ? 0 : chunk;
+ chunk = do_default_chunk ? UnSet : chunk;
}
}
if (!st) {
+ int dfd = open(dname, O_RDONLY|O_EXCL);
+ if (dfd < 0) {
+ fprintf(stderr, Name ": cannot open %s: %s\n",
+ dname, strerror(errno));
+ exit(2);
+ }
fprintf(stderr, Name ": device %s not suitable "
"for any style of array\n",
dname);
continue;
}
}
- if (verbose > 0 && do_default_chunk) {
- do_default_chunk = 0;
- fprintf(stderr, Name ": chunk size "
- "defaults to %dK\n", chunk);
- }
freesize /= 2; /* convert to K */
- if (chunk) {
+ if (chunk && chunk != UnSet) {
/* round to chunk size */
freesize = freesize & ~(chunk-1);
+ if (do_default_chunk) {
+ /* default chunk was just set */
+ if (verbose > 0)
+ fprintf(stderr, Name ": chunk size "
+ "defaults to %dK\n", chunk);
+ size &= ~(unsigned long long)(chunk - 1);
+ do_default_chunk = 0;
+ }
}
if (size && freesize < size) {
goto abort;
total_slots = info.array.nr_disks;
- sysfs_init(&info, mdfd, 0);
st->ss->getinfo_super(st, &info, NULL);
+ sysfs_init(&info, mdfd, 0);
if (did_default && verbose >= 0) {
if (is_subarray(info.text_version)) {
/* getinfo_super might have lost these ... */
inf->disk.major = major(stb.st_rdev);
inf->disk.minor = minor(stb.st_rdev);
+ /* FIXME the following should not be needed
+ * as getinfo_super is suppose to set
+ * them. However it doesn't for imsm,
+ * so we have this hack for now
+ */
+ if (st->ss == &super_imsm) {
+ inf->disk.number = dnum;
+ inf->disk.raid_disk = dnum;
+ }
}
break;
case 2:
inf->errors = 0;
- rv = 0;
rv = add_disk(mdfd, st, &info, inf);
me = map_by_devnum(&map, st->container_dev);
}
- st->ss->write_init_super(st);
+ if (st->ss->write_init_super(st)) {
+ fprintf(stderr,
+ Name ": Failed to write metadata to %s\n",
+ dv->devname);
+ st->ss->free_super(st);
+ goto abort;
+ }
/* update parent container uuid */
if (me) {
if (ioctl(mdfd, RUN_ARRAY, ¶m)) {
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
strerror(errno));
+ if (info.array.chunk_size & (info.array.chunk_size-1)) {
+ fprintf(stderr, " : Problem may be that "
+ "chunk size is not a power of 2\n");
+ }
ioctl(mdfd, STOP_ARRAY, NULL);
goto abort;
}
if (need_mdmon)
start_mdmon(st->container_dev);
- ping_monitor(devnum2devname(st->container_dev));
+ ping_monitor_by_id(st->container_dev);
close(container_fd);
}
wait_for(chosen_name, mdfd);