int rv;
int bitmap_fd;
unsigned long long bitmapsize;
+ struct mdinfo *sra;
struct mdinfo info;
int major_num = BITMAP_MAJOR_HI;
return 1;
}
}
+ if (level == UnSet) {
+ /* "ddf" metadata only supports one level - should possibly
+ * push this into metadata handler??
+ */
+ if (st && st->ss == &super_ddf)
+ level = LEVEL_CONTAINER;
+ }
+
if (level == UnSet) {
fprintf(stderr,
Name ": a RAID level is needed to create an array.\n");
}
+ sra = sysfs_read(mdfd, 0, 0);
- if ((vers % 100) >= 1) { /* can use different versions */
+ if (st->ss->external) {
+ char ver[100];
+ strcat(strcpy(ver, "external:"), st->ss->text_version);
+ if ((vers % 100) < 2 ||
+ sra == NULL ||
+ sysfs_set_str(sra, NULL, "metadata_version",
+ ver) < 0) {
+ fprintf(stderr, Name ": This kernel does not "
+ "support external metadata.\n");
+ return 1;
+ }
+ rv = 0;
+ } else if ((vers % 100) >= 1) { /* can use different versions */
mdu_array_info_t inf;
memset(&inf, 0, sizeof(inf));
inf.major_version = st->ss->major;
}
-
for (pass=1; pass <=2 ; pass++) {
mddev_dev_t moved_disk = NULL; /* the disk that was moved out of the insert point */
info.disk.state |= (1<<MD_DISK_WRITEMOSTLY);
if (dnum == insert_point ||
- strcasecmp(dv->devname, "missing")==0) {
- info.disk.major = 0;
- info.disk.minor = 0;
- info.disk.state = (1<<MD_DISK_FAULTY);
- } else {
- fd = open(dv->devname, O_RDONLY|O_EXCL, 0);
- if (fd < 0) {
- fprintf(stderr, Name ": failed to open %s after earlier success - aborting\n",
- dv->devname);
- return 1;
- }
- fstat(fd, &stb);
- info.disk.major = major(stb.st_rdev);
- info.disk.minor = minor(stb.st_rdev);
- remove_partitions(fd);
- close(fd);
+ strcasecmp(dv->devname, "missing")==0)
+ continue;
+
+ fd = open(dv->devname, O_RDWR|O_EXCL, 0);
+ if (fd < 0) {
+ fprintf(stderr, Name ": failed to open %s "
+ "after earlier success - aborting\n",
+ dv->devname);
+ return 1;
}
+ fstat(fd, &stb);
+ info.disk.major = major(stb.st_rdev);
+ info.disk.minor = minor(stb.st_rdev);
+
switch(pass){
case 1:
- st->ss->add_to_super(st, &info.disk);
+ remove_partitions(fd);
+ st->ss->add_to_super(st, &info.disk,
+ fd, dv->devname);
break;
case 2:
- if (info.disk.state == 1) break;
- Kill(dv->devname, 0, 1); /* Just be sure it is clean */
- Kill(dv->devname, 0, 1); /* and again, there could be two superblocks */
- st->ss->write_init_super(st, &info.disk,
- dv->devname);
-
- if (ioctl(mdfd, ADD_NEW_DISK, &info.disk)) {
- fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n",
+ close(fd);
+
+ if (st->ss->external) {
+ char dv[100];
+ sprintf(dv, "%d:%d\n",
+ info.disk.major,
+ info.disk.minor);
+ sysfs_set_str(sra, NULL, "new_dev", dv);
+ /* FIXME check error */
+ /*FIXME find that device and set it up*/
+ } else if (ioctl(mdfd, ADD_NEW_DISK,
+ &info.disk)) {
+ fprintf(stderr,
+ Name ": ADD_NEW_DISK for %s "
+ "failed: %s\n",
dv->devname, strerror(errno));
st->ss->free_super(st);
return 1;
}
-
break;
}
if (dv == moved_disk && dnum != insert_point) break;
}
+ if (pass == 1)
+ st->ss->write_init_super(st);
}
st->ss->free_super(st);