+ bitmap_fd = open(bitmap_file, O_RDWR);
+ if (bitmap_fd < 0) {
+ fprintf(stderr, Name ": weird: %s cannot be openned\n",
+ bitmap_file);
+ return 1;
+ }
+ if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
+ fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n",
+ mddev, strerror(errno));
+ return 1;
+ }
+ }
+
+
+ for (pass=1; pass <=2 ; pass++) {
+ mddev_dev_t moved_disk = NULL; /* the disk that was moved out of the insert point */
+
+ for (dnum=0, dv = devlist ; dv ;
+ dv=(dv->next)?(dv->next):moved_disk, dnum++) {
+ int fd;
+ struct stat stb;
+
+ info.disk.number = dnum;
+ if (dnum == insert_point) {
+ moved_disk = dv;
+ }
+ info.disk.raid_disk = info.disk.number;
+ if (info.disk.raid_disk < raiddisks)
+ info.disk.state = (1<<MD_DISK_ACTIVE) |
+ (1<<MD_DISK_SYNC);
+ else
+ info.disk.state = 0;
+ if (dv->writemostly)
+ info.disk.state |= (1<<MD_DISK_WRITEMOSTLY);
+
+ if (dnum == insert_point ||
+ strcasecmp(dv->devname, "missing")==0)
+ continue;
+
+ if (st->ss->external == 2)
+ fd = open(dv->devname, O_RDWR, 0);
+ else
+ 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:
+ remove_partitions(fd);
+ st->ss->add_to_super(st, &info.disk,
+ fd, dv->devname);
+ break;
+ case 2:
+ info.component_size = info.array.size * 2;
+ info.errors = 0;
+ rv = 0;
+
+ if (st->ss->external) {
+ st->ss->getinfo_super_n(st, &info);
+ rv = sysfs_add_disk(sra, fd, &info);
+ close(fd);
+ } else {
+ close(fd);
+ rv = ioctl(mdfd, ADD_NEW_DISK,
+ &info.disk);
+ }
+ if (rv) {
+ 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);
+
+ /* param is not actually used */
+ if (level == LEVEL_CONTAINER)
+ /* No need to start */
+ ;
+ else if (runstop == 1 || subdevs >= raiddisks) {
+ if (st->ss->external) {
+ switch(level) {
+ case LEVEL_LINEAR:
+ case LEVEL_MULTIPATH:
+ case 0:
+ sysfs_set_str(sra, NULL, "array_state",
+ "active");
+ break;
+ default:
+ sysfs_set_str(sra, NULL, "array_state",
+ "readonly");
+ break;
+ }
+ } else {
+ mdu_param_t param;
+ if (ioctl(mdfd, RUN_ARRAY, ¶m)) {
+ fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
+ strerror(errno));
+ Manage_runstop(mddev, mdfd, -1, 0);
+ return 1;
+ }
+ }
+ if (verbose >= 0)
+ fprintf(stderr, Name ": array %s started.\n", mddev);