/*
* mdadm - manage Linux "md" devices aka RAID arrays.
*
- * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
*
*
* This program is free software; you can redistribute it and/or modify
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Neil Brown
- * Email: <neilb@cse.unsw.edu.au>
- * Paper: Neil Brown
- * School of Computer Science and Engineering
- * The University of New South Wales
- * Sydney, 2052
- * Australia
+ * Email: <neilb@suse.de>
*/
#include "mdadm.h"
if (st && st->ss->external && sparedisks) {
fprintf(stderr,
Name ": This metadata type does not support "
- "spare disks are create time\n");
+ "spare disks at create time\n");
return 1;
}
if (subdevs > raiddisks+sparedisks) {
case 10:
case 6:
case 0:
- case LEVEL_LINEAR: /* linear */
if (chunk == 0) {
+ chunk = 512;
+ if (verbose > 0)
+ fprintf(stderr, Name ": chunk size defaults to 512K\n");
+ }
+ break;
+ case LEVEL_LINEAR:
+ /* a chunksize of zero 0s perfectly valid (and preferred) since 2.6.16 */
+ if (get_linux_version() < 2006016 && chunk == 0) {
chunk = 64;
if (verbose > 0)
fprintf(stderr, Name ": chunk size defaults to 64K\n");
raiddisks,
chunk, size*2, dname,
&freesize,
- verbose > 0)) {
+ verbose >= 0)) {
fprintf(stderr,
Name ": %s is not suitable for "
warn |= check_ext2(fd, dname);
warn |= check_reiser(fd, dname);
warn |= check_raid(fd, dname);
+ if (strcmp(st->ss->name, "1.x") == 0 &&
+ st->minor_version >= 1)
+ /* metadata at front */
+ warn |= check_partitions(fd, dname, 0);
+ else if (level == 1 || level == LEVEL_CONTAINER)
+ /* partitions could be meaningful */
+ warn |= check_partitions(fd, dname, freesize*2);
+ else
+ /* partitions cannot be meaningful */
+ warn |= check_partitions(fd, dname, 0);
+ if (strcmp(st->ss->name, "1.x") == 0 &&
+ st->minor_version >= 1 &&
+ did_default &&
+ level == 1 &&
+ (warn & 1024) == 0) {
+ warn |= 1024;
+ fprintf(stderr, Name ": Note: this array has metadata at the start and\n"
+ " may not be suitable as a boot device. If you plan to\n"
+ " store '/boot' on this device please ensure that\n"
+ " your boot-loader understands md/v1.x metadata, or use\n"
+ " --metadata=0.90\n");
+ }
close(fd);
}
}
assume_clean
) {
info.array.state = 1; /* clean, but one+ drive will be missing*/
- info.resync_start = ~0ULL;
+ info.resync_start = MaxSector;
} else {
info.array.state = 0; /* not clean, but no errors */
info.resync_start = 0;
fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n");
goto abort;
}
+ if (!st->ss->add_internal_bitmap) {
+ fprintf(stderr, Name ": internal bitmaps not supported with %s metadata\n",
+ st->ss->name);
+ goto abort;
+ }
if (!st->ss->add_internal_bitmap(st, &bitmap_chunk,
delay, write_behind,
bitmapsize, 1, major_num)) {
if (fd >= 0)
remove_partitions(fd);
if (st->ss->add_to_super(st, &inf->disk,
- fd, dv->devname))
+ fd, dv->devname)) {
+ ioctl(mdfd, STOP_ARRAY, NULL);
goto abort;
+ }
st->ss->getinfo_super(st, inf);
safe_mode_delay = inf->safe_mode_delay;
dv == moved_disk && dnum != insert_point) break;
}
if (pass == 1) {
+ struct mdinfo info_new;
+ struct map_ent *me = NULL;
+
+ /* check to see if the uuid has changed due to these
+ * metadata changes, and if so update the member array
+ * and container uuid. Note ->write_init_super clears
+ * the subarray cursor such that ->getinfo_super once
+ * again returns container info.
+ */
+ map_lock(&map);
+ st->ss->getinfo_super(st, &info_new);
+ if (st->ss->external && level != LEVEL_CONTAINER &&
+ !same_uuid(info_new.uuid, info.uuid, 0)) {
+ map_update(&map, fd2devnum(mdfd),
+ info_new.text_version,
+ info_new.uuid, chosen_name);
+ me = map_by_devnum(&map, st->container_dev);
+ }
+
st->ss->write_init_super(st);
+
+ /* update parent container uuid */
+ if (me) {
+ char *path = strdup(me->path);
+
+ st->ss->getinfo_super(st, &info_new);
+ map_update(&map, st->container_dev,
+ info_new.text_version,
+ info_new.uuid, path);
+ free(path);
+ }
+ map_unlock(&map);
+
flush_metadata_updates(st);
}
}
if (ioctl(mdfd, RUN_ARRAY, ¶m)) {
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
strerror(errno));
- Manage_runstop(mddev, mdfd, -1, 0);
+ ioctl(mdfd, STOP_ARRAY, NULL);
goto abort;
}
}
return 0;
abort:
+ map_lock(&map);
+ map_remove(&map, fd2devnum(mdfd));
+ map_unlock(&map);
+
if (mdfd >= 0)
close(mdfd);
return 1;