#include "md_u.h"
#include <dirent.h>
-int Detail(char *dev, int brief, int export, int test, char *homehost)
+int Detail(char *dev, int brief, int export, int test, char *homehost, char *prefer)
{
/*
* Print out details for an md array by using
int rv = test ? 4 : 1;
int avail_disks = 0;
- char *avail;
+ char *avail = NULL;
if (fd < 0) {
- fprintf(stderr, Name ": cannot open %s: %s\n",
+ pr_err("cannot open %s: %s\n",
dev, strerror(errno));
return rv;
}
vers = md_get_version(fd);
if (vers < 0) {
- fprintf(stderr, Name ": %s does not appear to be an md device\n",
+ pr_err("%s does not appear to be an md device\n",
dev);
close(fd);
return rv;
}
if (vers < 9000) {
- fprintf(stderr, Name ": cannot get detail for md device %s: driver version too old.\n",
+ pr_err("cannot get detail for md device %s: driver version too old.\n",
dev);
close(fd);
return rv;
}
if (ioctl(fd, GET_ARRAY_INFO, &array)<0) {
if (errno == ENODEV)
- fprintf(stderr, Name ": md device %s does not appear to be active.\n",
+ pr_err("md device %s does not appear to be active.\n",
dev);
else
- fprintf(stderr, Name ": cannot get array detail for %s: %s\n",
+ pr_err("cannot get array detail for %s: %s\n",
dev, strerror(errno));
close(fd);
return rv;
int dn = st->container_dev;
member = subarray;
- container = map_dev(dev2major(dn), dev2minor(dn), 1);
+ container = map_dev_preferred(dev2major(dn), dev2minor(dn), 1, prefer);
}
/* try to load a superblock */
continue;
}
/* some formats (imsm) have free-floating-spares
- * with a uuid of uuid_match_any, they don't
+ * with a uuid of uuid_zero, they don't
* have very good info about the rest of the
* container, so keep searching when
* encountering such a device. Otherwise, stop
* after the first successful call to
* ->load_super.
*/
- if (memcmp(uuid_match_any,
+ if (memcmp(uuid_zero,
info->uuid,
- sizeof(uuid_match_any)) == 0) {
+ sizeof(uuid_zero)) == 0) {
st->ss->free_super(st);
continue;
}
disk.number = d;
if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
if (d < array.raid_disks)
- fprintf(stderr, Name ": cannot get device detail for device %d: %s\n",
+ pr_err("cannot get device detail for device %d: %s\n",
d, strerror(errno));
continue;
}
if (avail_disks == array.raid_disks)
st = "";
else if (!enough(array.level, array.raid_disks,
- array.layout, 1, avail, avail_disks))
+ array.layout, 1, avail))
st = ", FAILED";
else
st = ", degraded";
- printf(" State : %s%s%s%s\n",
- (array.state&(1<<MD_SB_CLEAN))?"clean":"active",
- st,
- (!e || e->percent < 0) ? "" : sync_action[e->resync],
- larray_size ? "": ", Not Started");
+ printf(" State : %s%s%s%s%s%s \n",
+ (array.state&(1<<MD_SB_CLEAN))?"clean":"active", st,
+ (!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)": "");
}
if (array.raid_disks)
printf(" Active Devices : %d\n", array.active_disks);
}
if (e && e->percent >= 0) {
- printf(" Re%s Status : %d%% complete\n",
- (st && st->sb && info->reshape_active)?
- "shape":"build",
- e->percent);
+ static char *sync_action[] = {"Rebuild", "Resync", "Reshape", "Check"};
+ printf(" %7s Status : %d%% complete\n", sync_action[e->resync], e->percent);
is_rebuilding = 1;
}
free_mdstat(ms);
printf(" Reshape pos'n : %llu%s\n", (unsigned long long) info->reshape_progress<<9,
human_size((unsigned long long)info->reshape_progress<<9));
#endif
- if (info->delta_disks > 0)
+ if (info->delta_disks != 0)
printf(" Delta Devices : %d, (%d->%d)\n",
info->delta_disks, array.raid_disks - info->delta_disks, array.raid_disks);
- if (info->delta_disks < 0)
- printf(" Delta Devices : %d, (%d->%d)\n",
- info->delta_disks, array.raid_disks, array.raid_disks + info->delta_disks);
if (info->new_level != array.level) {
char *c = map_num(pers, info->new_level);
printf(" New Level : %s\n", c?c:"-unknown-");
if (load_sys(path, vbuf) < 0)
continue;
if (strncmp(vbuf, "external:", 9) != 0 ||
- !is_subarray(sra->sys_name+9) ||
+ !is_subarray(vbuf+9) ||
strncmp(vbuf+10, sra->sys_name, nlen) != 0 ||
vbuf[10+nlen] != '/')
continue;
dn = devname2devnum(de->d_name);
- printf(" %s", map_dev(dev2major(dn),
- dev2minor(dn), 1));
+ printf(" %s", map_dev_preferred(
+ dev2major(dn),
+ dev2minor(dn), 1, prefer));
}
if (dir)
closedir(dir);
failed++;
}
if (disk.state & (1<<MD_DISK_ACTIVE)) printf(" active");
- if (disk.state & (1<<MD_DISK_SYNC)) printf(" sync");
+ if (disk.state & (1<<MD_DISK_SYNC)) {
+ printf(" sync");
+ if (array.level == 10 && (array.layout & ~0x1FFFF) == 0) {
+ int nc = array.layout & 0xff;
+ int fc = (array.layout >> 8) & 0xff;
+ int copies = nc*fc;
+ if (array.raid_disks % copies == 0 && copies <= 26) {
+ /* We can divide the devices into 'sets' */
+ int set = disk.raid_disk % copies;
+ printf(" set-%c", set + 'A');
+ }
+ }
+ }
if (disk.state & (1<<MD_DISK_REMOVED)) printf(" removed");
if (disk.state & (1<<MD_DISK_WRITEMOSTLY)) printf(" writemostly");
if ((disk.state &
if (test && d < array.raid_disks
&& !(disk.state & (1<<MD_DISK_SYNC)))
rv |= 1;
- if ((dv=map_dev(disk.major, disk.minor, 0))) {
+ if ((dv=map_dev_preferred(disk.major, disk.minor, 0, prefer))) {
if (brief) {
if (devices) {
devices = realloc(devices,
if (brief) printf("\n");
if (test &&
!enough(array.level, array.raid_disks, array.layout,
- 1, avail, avail_disks))
+ 1, avail))
rv = 2;
free(disks);
out:
close(fd);
free(subarray);
+ free(avail);
+ sysfs_free(sra);
return rv;
}
err = ss->detail_platform(verbose, 0);
else if (ss) {
if (verbose)
- fprintf(stderr, Name ": %s metadata is platform independent\n",
+ pr_err("%s metadata is platform independent\n",
ss->name ? : "[no name]");
} else if (!scan) {
if (verbose)
- fprintf(stderr, Name ": specify a metadata type or --scan\n");
+ pr_err("specify a metadata type or --scan\n");
}
if (!scan)
if (meta == ss)
continue;
if (verbose)
- fprintf(stderr, Name ": checking metadata %s\n",
+ pr_err("checking metadata %s\n",
meta->name ? : "[no name]");
if (!meta->detail_platform) {
if (verbose)
- fprintf(stderr, Name ": %s metadata is platform independent\n",
+ pr_err("%s metadata is platform independent\n",
meta->name ? : "[no name]");
} else
err |= meta->detail_platform(verbose, 0);