/*
* mdadm - manage Linux "md" devices aka RAID arrays.
*
- * Copyright (C) 2001-2012 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2001-2013 Neil Brown <neilb@suse.de>
*
*
* This program is free software; you can redistribute it and/or modify
return strcmp(* (char * const *) p1, * (char * const *) p2);
}
+static int add_device(const char *dev, char ***p_devices,
+ int *p_max_devices, int n_devices)
+{
+ if (n_devices + 1 >= *p_max_devices) {
+ *p_max_devices += 16;
+ *p_devices = xrealloc(*p_devices, *p_max_devices *
+ sizeof(**p_devices));
+ if (!*p_devices) {
+ *p_max_devices = 0;
+ return 0;
+ }
+ };
+ (*p_devices)[n_devices] = xstrdup(dev);
+ return n_devices + 1;
+}
+
int Detail(char *dev, struct context *c)
{
/*
st = super_by_fd(fd, &subarray);
if (ioctl(fd, GET_ARRAY_INFO, &array) == 0) {
inactive = 0;
- } else if (errno == ENODEV) {
+ } else if (errno == ENODEV && sra) {
+ if (sra->array.major_version == -1 &&
+ sra->array.minor_version == -1 &&
+ sra->devs == NULL) {
+ pr_err("Array associated with md device %s does not exist.\n", dev);
+ close(fd);
+ sysfs_free(sra);
+ return rv;
+ }
array = sra->array;
inactive = 1;
} else {
/* This is a subarray of some container.
* We want the name of the container, and the member
*/
- int devid = devnm2devid(st->container_devnm);
+ dev_t devid = devnm2devid(st->container_devnm);
int cfd, err;
member = subarray;
goto out;
}
- disks = xmalloc(max_disks * sizeof(mdu_disk_info_t));
- for (d = 0; d < max_disks; d++) {
+ disks = xmalloc(max_disks * 2 * sizeof(mdu_disk_info_t));
+ for (d = 0; d < max_disks * 2; d++) {
disks[d].state = (1<<MD_DISK_REMOVED);
disks[d].major = disks[d].minor = 0;
- disks[d].number = disks[d].raid_disk = d;
+ disks[d].number = -1;
+ disks[d].raid_disk = d/2;
}
next = array.raid_disks*2;
if (disk.major == 0 && disk.minor == 0)
continue;
if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks
- && disks[disk.raid_disk*2].state == (1<<MD_DISK_REMOVED))
+ && disks[disk.raid_disk*2].state == (1<<MD_DISK_REMOVED)
+ && ((disk.state & (1<<MD_DISK_JOURNAL)) == 0))
disks[disk.raid_disk*2] = disk;
else if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks
- && disks[disk.raid_disk*2+1].state == (1<<MD_DISK_REMOVED))
+ && disks[disk.raid_disk*2+1].state == (1<<MD_DISK_REMOVED)
+ && !(disk.state & (1<<MD_DISK_JOURNAL)))
disks[disk.raid_disk*2+1] = disk;
- else if (next < max_disks)
+ else if (next < max_disks*2)
disks[next++] = disk;
}
(disks[d*2+1].state & (1<<MD_DISK_SYNC))) {
avail_disks ++;
avail[d] = 1;
- }
+ } else
+ rv |= !! c->test;
}
if (c->brief) {
else
printf(" Used Dev Size : unknown\n");
} else
- printf(" Used Dev Size : %d%s\n", array.size,
- human_size((long long)array.size<<10));
+ printf(" Used Dev Size : %lu%s\n",
+ (unsigned long)array.size,
+ human_size((unsigned long long)array.size<<10));
}
if (array.raid_disks)
printf(" Raid Devices : %d\n", array.raid_disks);
(!e || (e->percent < 0 && e->percent != RESYNC_PENDING &&
e->percent != RESYNC_DELAYED)) ? "" : sync_action[e->resync],
larray_size ? "": ", Not Started",
- e->percent == RESYNC_DELAYED ? " (DELAYED)": "",
- e->percent == RESYNC_PENDING ? " (PENDING)": "");
+ (e && e->percent == RESYNC_DELAYED) ? " (DELAYED)": "",
+ (e && e->percent == RESYNC_PENDING) ? " (PENDING)": "");
} else if (inactive) {
printf(" State : inactive\n");
}
printf(" Member Arrays :");
while (dir && (de = readdir(dir)) != NULL) {
- char path[200];
+ char path[287];
char vbuf[1024];
int nlen = strlen(sra->sys_name);
- int devid;
+ dev_t devid;
if (de->d_name[0] == '.')
continue;
sprintf(path, "/sys/block/%s/md/metadata_version",
de->d_name);
- if (load_sys(path, vbuf) < 0)
+ if (load_sys(path, vbuf, sizeof(vbuf)) < 0)
continue;
if (strncmp(vbuf, "external:", 9) != 0 ||
!is_subarray(vbuf+9) ||
}
free(info);
- for (d= 0; d < max_disks; d++) {
+ for (d= 0; d < max_disks * 2; d++) {
char *dv;
mdu_disk_info_t disk = disks[d];
continue;
if (!c->brief) {
if (d == array.raid_disks*2) printf("\n");
- if (disk.number < 0)
+ if (disk.number < 0 && disk.raid_disk < 0)
printf(" - %5d %5d - ",
disk.major, disk.minor);
- else if (disk.raid_disk < 0)
+ else if (disk.raid_disk < 0 || disk.state & (1<<MD_DISK_JOURNAL))
printf(" %5d %5d %5d - ",
disk.number, disk.major, disk.minor);
+ else if (disk.number < 0)
+ printf(" - %5d %5d %5d ",
+ disk.major, disk.minor, disk.raid_disk);
else
printf(" %5d %5d %5d %5d ",
disk.number, disk.major, disk.minor, disk.raid_disk);
}
if (disk.state & (1<<MD_DISK_REMOVED)) printf(" removed");
if (disk.state & (1<<MD_DISK_WRITEMOSTLY)) printf(" writemostly");
+ if (disk.state & (1<<MD_DISK_FAILFAST)) printf(" failfast");
+ if (disk.state & (1<<MD_DISK_JOURNAL)) printf(" journal");
if ((disk.state &
((1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC)
- |(1<<MD_DISK_REMOVED)|(1<<MD_DISK_FAULTY)))
+ |(1<<MD_DISK_REMOVED)|(1<<MD_DISK_FAULTY)|(1<<MD_DISK_JOURNAL)))
== 0) {
printf(" spare");
if (is_26) {
}
}
if (disk.state == 0) spares++;
- if (c->test && d < array.raid_disks
- && !(disk.state & (1<<MD_DISK_SYNC)))
- rv |= 1;
dv=map_dev_preferred(disk.major, disk.minor, 0, c->prefer);
if (dv != NULL) {
- if (c->brief) {
- if (n_devices + 1 >= max_devices) {
- max_devices += 16;
- devices = xrealloc(devices, max_devices
- *sizeof(*devices));
- if (!devices)
- goto out;
- };
- devices[n_devices] = xstrdup(dv);
- n_devices++;
- } else
+ if (c->brief)
+ n_devices = add_device(dv, &devices,
+ &max_devices,
+ n_devices);
+ else
printf(" %s", dv);
}
if (!c->brief) printf("\n");