/*
* 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"
__u64 utime; /* 40 bits second, 24 btes microseconds */
__u64 events; /* incremented when superblock updated */
__u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */
- __u32 sb_csum; /* checksum upto devs[max_dev] */
- __u32 max_dev; /* size of devs[] array to consider */
+ __u32 sb_csum; /* checksum upto dev_roles[max_dev] */
+ __u32 max_dev; /* size of dev_roles[] array to consider */
__u8 pad3[64-32]; /* set to 0 when writing */
/* device state information. Indexed by dev_number.
time_t atime;
int d;
int role;
+ int delta_extra = 0;
int i;
char *c;
int l = homehost ? strlen(homehost) : 0;
human_size(__le64_to_cpu(sb->reshape_position)<<9));
if (__le32_to_cpu(sb->delta_disks)) {
printf(" Delta Devices : %d", __le32_to_cpu(sb->delta_disks));
- if (__le32_to_cpu(sb->delta_disks))
- printf(" (%d->%d)\n",
- __le32_to_cpu(sb->raid_disks)-__le32_to_cpu(sb->delta_disks),
- __le32_to_cpu(sb->raid_disks));
- else
- printf(" (%d->%d)\n", __le32_to_cpu(sb->raid_disks),
- __le32_to_cpu(sb->raid_disks)+__le32_to_cpu(sb->delta_disks));
+ printf(" (%d->%d)\n",
+ __le32_to_cpu(sb->raid_disks)-__le32_to_cpu(sb->delta_disks),
+ __le32_to_cpu(sb->raid_disks));
+ if ((int)__le32_to_cpu(sb->delta_disks) < 0)
+ delta_extra = -__le32_to_cpu(sb->delta_disks);
}
if (__le32_to_cpu(sb->new_level) != __le32_to_cpu(sb->level)) {
c = map_num(pers, __le32_to_cpu(sb->new_level));
c = map_num(r5layout, __le32_to_cpu(sb->new_layout));
printf(" New Layout : %s\n", c?c:"-unknown-");
}
+ if (__le32_to_cpu(sb->level) == 6) {
+ c = map_num(r6layout, __le32_to_cpu(sb->new_layout));
+ printf(" New Layout : %s\n", c?c:"-unknown-");
+ }
if (__le32_to_cpu(sb->level) == 10) {
printf(" New Layout :");
print_r10_layout(__le32_to_cpu(sb->new_layout));
c = map_num(r5layout, __le32_to_cpu(sb->layout));
printf(" Layout : %s\n", c?c:"-unknown-");
}
+ if (__le32_to_cpu(sb->level) == 6) {
+ c = map_num(r6layout, __le32_to_cpu(sb->layout));
+ printf(" Layout : %s\n", c?c:"-unknown-");
+ }
if (__le32_to_cpu(sb->level) == 10) {
int lo = __le32_to_cpu(sb->layout);
printf(" Layout :");
#endif
printf(" Device Role : ");
d = __le32_to_cpu(sb->dev_number);
- if (d < sb->raid_disks)
+ if (d < __le32_to_cpu(sb->max_dev))
role = __le16_to_cpu(sb->dev_roles[d]);
else
role = 0xFFFF;
printf("Active device %d\n", role);
printf(" Array State : ");
- for (d=0; d<__le32_to_cpu(sb->raid_disks); d++) {
+ for (d=0; d<__le32_to_cpu(sb->raid_disks) + delta_extra; d++) {
int cnt = 0;
int me = 0;
int i;
}
-static void brief_examine_super1(struct supertype *st)
+static void brief_examine_super1(struct supertype *st, int verbose)
{
struct mdp_superblock_1 *sb = st->sb;
int i;
else
nm = NULL;
- printf("ARRAY%s%s level=%s ",
- nm ? " /dev/md/":"", nm,
- c?c:"-unknown-");
+ printf("ARRAY%s%s", nm ? " /dev/md/":"", nm);
+ if (verbose && c)
+ printf(" level=%s", c);
sb_offset = __le64_to_cpu(sb->super_offset);
if (sb_offset <= 4)
- printf("metadata=1.1 ");
+ printf(" metadata=1.1 ");
else if (sb_offset <= 8)
- printf("metadata=1.2 ");
+ printf(" metadata=1.2 ");
else
- printf("metadata=1.0 ");
- printf("num-devices=%d UUID=", __le32_to_cpu(sb->raid_disks));
+ printf(" metadata=1.0 ");
+ if (verbose)
+ printf("num-devices=%d ", __le32_to_cpu(sb->raid_disks));
+ printf("UUID=");
for (i=0; i<16; i++) {
if ((i&3)==0 && i != 0) printf(":");
printf("%02x", sb->set_uuid[i]);
info->disk.raid_disk = -1;
switch(role) {
case 0xFFFF:
- info->disk.state = 2; /* spare: ACTIVE, not sync, not faulty */
+ info->disk.state = 0; /* spare: not active, not sync, not faulty */
break;
case 0xFFFE:
info->disk.state = 1; /* faulty */
info->delta_disks = __le32_to_cpu(sb->delta_disks);
info->new_layout = __le32_to_cpu(sb->new_layout);
info->new_chunk = __le32_to_cpu(sb->new_chunk)<<9;
+ if (info->delta_disks < 0)
+ info->array.raid_disks -= info->delta_disks;
} else
info->reshape_active = 0;
if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
read(rfd, sb->device_uuid, 16) != 16) {
- *(__u32*)(sb->device_uuid) = random();
- *(__u32*)(sb->device_uuid+4) = random();
- *(__u32*)(sb->device_uuid+8) = random();
- *(__u32*)(sb->device_uuid+12) = random();
+ __u32 r[4] = {random(), random(), random(), random()};
+ memcpy(sb->device_uuid, r, 16);
}
+ if (rfd >= 0)
+ close(rfd);
sb->dev_roles[i] =
__cpu_to_le16(info->disk.raid_disk);
else {
if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
read(rfd, sb->set_uuid, 16) != 16) {
- *(__u32*)(sb->set_uuid) = random();
- *(__u32*)(sb->set_uuid+4) = random();
- *(__u32*)(sb->set_uuid+8) = random();
- *(__u32*)(sb->set_uuid+12) = random();
+ __u32 r[4] = {random(), random(), random(), random()};
+ memcpy(sb->set_uuid, r, 16);
}
if (rfd >= 0) close(rfd);
}
if (di->fd < 0)
continue;
- Kill(di->devname, 0, 1, 1);
- Kill(di->devname, 0, 1, 1);
+ while (Kill(di->devname, NULL, 0, 1, 1) == 0)
+ ;
sb->dev_number = __cpu_to_le32(di->disk.number);
if (di->disk.state & (1<<MD_DISK_WRITEMOSTLY))
if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
read(rfd, sb->device_uuid, 16) != 16) {
- *(__u32*)(sb->device_uuid) = random();
- *(__u32*)(sb->device_uuid+4) = random();
- *(__u32*)(sb->device_uuid+8) = random();
- *(__u32*)(sb->device_uuid+12) = random();
+ __u32 r[4] = {random(), random(), random(), random()};
+ memcpy(sb->device_uuid, r, 16);
}
- if (rfd >= 0) close(rfd);
+ if (rfd >= 0)
+ close(rfd);
+
sb->events = 0;
refst =*st;
return st;
}
if (strcmp(arg, "1.1") == 0 ||
- strcmp(arg, "1.01") == 0) {
+ strcmp(arg, "1.01") == 0 ||
+ strcmp(arg, "default") == 0 ||
+ strcmp(arg, "") == 0 /* no metadata */
+ ) {
st->minor_version = 1;
return st;
}
min_chunk *= 2;
bits = (bits+1)/2;
}
- if (chunk == UnSet)
+ if (chunk == UnSet) {
+ /* For practical purpose, 64Meg is a good
+ * default chunk size for internal bitmaps.
+ */
chunk = min_chunk;
- else if (chunk < min_chunk)
+ if (chunk < 64*1024*1024)
+ chunk = 64*1024*1024;
+ } else if (chunk < min_chunk)
return 0; /* chunk size too small */
if (chunk == 0) /* rounding problem */
return 0;
unsigned long long ldsize;
int fd;
- if (level == LEVEL_CONTAINER)
+ if (level == LEVEL_CONTAINER) {
+ if (verbose)
+ fprintf(stderr, Name ": 1.x metadata does not support containers\n");
return 0;
+ }
if (!subdev)
return 1;
#else
.swapuuid = 1,
#endif
- .name = "1.0",
+ .name = "1.x",
};