int lfd = -1;
int sysfd = -1;
int count = 0; /* number of actions taken */
+ struct mdinfo info;
+ int frozen = 0;
if (ioctl(fd, GET_ARRAY_INFO, &array)) {
fprintf(stderr, Name ": cannot get array info for %s\n",
devname);
goto abort;
}
+ sysfs_init(&info, fd, 0);
/* array.size is only 32 bit and may be truncated.
* So read from sysfs if possible, and record number of sectors
char *dnprintable = dv->devname;
char *add_dev = dv->devname;
int err;
- int re_add_failed = 0;
+ int array_failed;
next = dv->next;
jnext = 0;
dv->devname, dv->disposition);
goto abort;
}
- for (; j < 1024 && remaining_disks > 0; j++) {
+ for (; j < MAX_DISKS && remaining_disks > 0; j++) {
unsigned dev;
disc.number = j;
if (ioctl(fd, GET_DISK_INFO, &disc))
dv->devname, dv->disposition);
goto abort;
}
- for (; j < 1024 && remaining_disks > 0; j++) {
+ for (; j < MAX_DISKS && remaining_disks > 0; j++) {
int sfd;
unsigned dev;
disc.number = j;
dv->devname, strerror(errno));
goto abort;
}
+ if (!frozen) {
+ if (sysfs_freeze_array(&info) == 1)
+ frozen = 1;
+ else
+ frozen = -1;
+ }
st = dup_super(tst);
": %s is larger than %s can "
"effectively use.\n"
" Add --force is you "
- "really wan to add this device.\n",
+ "really want to add this device.\n",
add_dev, devname);
st->ss->free_super(st);
close(tfd);
continue;
goto abort;
}
- skip_re_add:
- re_add_failed = 1;
}
+ skip_re_add:
st->ss->free_super(st);
}
if (add_dev != dv->devname) {
dv->devname, devname);
goto abort;
}
- if (re_add_failed) {
- fprintf(stderr, Name ": %s reports being an active member for %s, but a --re-add fails.\n",
- dv->devname, devname);
- fprintf(stderr, Name ": not performing --add as that would convert %s in to a spare.\n",
- dv->devname);
- fprintf(stderr, Name ": To make this a spare, use \"mdadm --zero-superblock %s\" first.\n",
+ if (array.active_disks < array.raid_disks) {
+ char *avail = calloc(array.raid_disks, 1);
+ int d;
+ int found = 0;
+
+ for (d = 0; d < MAX_DISKS && found < array.active_disks; d++) {
+ disc.number = d;
+ if (ioctl(fd, GET_DISK_INFO, &disc))
+ continue;
+ if (disc.major == 0 && disc.minor == 0)
+ continue;
+ if (!(disc.state & (1<<MD_DISK_SYNC)))
+ continue;
+ avail[disc.raid_disk] = 1;
+ found++;
+ }
+ array_failed = !enough(array.level, array.raid_disks,
+ array.layout, 1, avail);
+ } else
+ array_failed = 0;
+ if (array_failed) {
+ fprintf(stderr, Name ": %s has failed so using --add cannot work and might destroy\n",
+ devname);
+ fprintf(stderr, Name ": data on %s. You should stop the array and re-assemble it.\n",
dv->devname);
if (tfd >= 0)
close(tfd);
break;
}
}
+ if (frozen > 0)
+ sysfs_set_str(&info, NULL, "sync_action","idle");
if (test && count == 0)
return 2;
return 0;
abort:
+ if (frozen > 0)
+ sysfs_set_str(&info, NULL, "sync_action","idle");
return 1;
}