info.component_size = size*2;
info.new_level = level;
info.new_chunk = chunksize * 1024;
- if (raid_disks)
+ if (info.array.level == LEVEL_CONTAINER) {
+ info.delta_disks = UnSet;
+ info.array.raid_disks = raid_disks;
+ } else if (raid_disks)
info.delta_disks = raid_disks - info.array.raid_disks;
else
info.delta_disks = UnSet;
int done;
struct mdinfo *sra = NULL;
- msg = analyse_change(info, &reshape);
+ if (info->reshape_active) {
+ int new_level = info->new_level;
+ info->new_level = UnSet;
+ msg = analyse_change(info, &reshape);
+ info->new_level = new_level;
+ if (!restart)
+ /* Make sure the array isn't read-only */
+ ioctl(fd, RESTART_ARRAY_RW, 0);
+ } else
+ msg = analyse_change(info, &reshape);
if (msg) {
fprintf(stderr, Name ": %s\n", msg);
goto release;
}
- if (reshape.level != info->array.level ||
- reshape.before.layout != info->array.layout ||
- reshape.before.data_disks + reshape.parity != info->array.raid_disks) {
+ if (restart &&
+ (reshape.level != info->array.level ||
+ reshape.before.layout != info->array.layout ||
+ reshape.before.data_disks + reshape.parity != info->array.raid_disks)) {
fprintf(stderr, Name ": reshape info is not in native format -"
" cannot continue.\n");
goto release;
* freeze_array and freeze_container.
*/
sysfs_freeze_array(info);
+ /* Check we have enough spares to not be degraded */
spares_needed = max(reshape.before.data_disks,
reshape.after.data_disks)
+ reshape.parity - array.raid_disks;
info->array.spare_disks);
goto release;
}
+ /* Check we have enough spares to not fail */
+ spares_needed = max(reshape.before.data_disks,
+ reshape.after.data_disks)
+ - array.raid_disks;
+ if ((info->new_level > 1 || info->new_level == 0) &&
+ spares_needed > info->array.spare_disks) {
+ fprintf(stderr,
+ Name ": Need %d spare%s to create working array,"
+ " and only have %d.\n",
+ spares_needed,
+ spares_needed == 1 ? "" : "s",
+ info->array.spare_disks);
+ goto release;
+ }
- if (reshape.level != info->array.level) {
+ if (reshape.level != array.level) {
char *c = map_num(pers, reshape.level);
int err;
if (c == NULL)
if (!quiet)
fprintf(stderr, Name ": level of %s changed to %s\n",
devname, c);
- orig_level = info->array.level;
+ orig_level = array.level;
sysfs_freeze_array(info);
if (reshape.level > 0 && st->ss->external) {
*/
/* read current array info */
if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) {
- dprintf("Canot get array information.\n");
+ dprintf("Cannot get array information.\n");
goto release;
}
/* compare current array info with new values and if
fmt_devname(buf, st->container_dev);
container = buf;
freeze(st);
- if (info->reshape_active == 2)
+
+ if (!mdmon_running(st->container_dev))
+ start_mdmon(st->container_dev);
+ ping_monitor(devnum2devname(st->container_dev));
+
+
+ if (info->reshape_active == 2) {
+ int cfd = open_dev(st->container_dev);
+ if (cfd < 0)
+ return 1;
+ st->ss->load_container(st, cfd, container);
+ close(cfd);
return reshape_container(container, NULL,
st, info, 0, backup_file,
0, 1);
+ }
}
return reshape_array(container, mdfd, "array", st, info, 1,
backup_file, 0, 0, 1);