return n_devices + 1;
}
+/**
+ * detail_fname_from_uuid() - generate uuid string with special super1 handling.
+ * @mp: map entry to parse.
+ * @buf: buf to write.
+ *
+ * Hack to workaround an issue with super1 superblocks. It swapuuid set in order for assembly
+ * to work, but can't have it set if we want this printout to match all the other uuid printouts
+ * in super1.c, so we force swapuuid to 1 to make our printout match the rest of super1.
+ *
+ * Always convert uuid if host is big endian.
+ */
+char *detail_fname_from_uuid(struct map_ent *mp, char *buf)
+{
+#if __BYTE_ORDER == BIG_ENDIAN
+ bool swap = true;
+#else
+ bool swap = false;
+#endif
+ if (strncmp(mp->metadata, "1.", 2) == 0)
+ swap = true;
+
+ return __fname_from_uuid(mp->uuid, swap, buf, ':');
+}
+
int Detail(char *dev, struct context *c)
{
/*
int spares = 0;
struct stat stb;
int failed = 0;
- struct supertype *st;
+ struct supertype *st = NULL;
char *subarray = NULL;
int max_disks = MD_SB_DISKS; /* just a default */
struct mdinfo *info = NULL;
- struct mdinfo *sra;
+ struct mdinfo *sra = NULL;
struct mdinfo *subdev;
char *member = NULL;
char *container = NULL;
if (!sra) {
if (md_get_array_info(fd, &array)) {
pr_err("%s does not appear to be an md device\n", dev);
- close(fd);
- return rv;
+ goto out;
}
}
external = (sra != NULL && sra->array.major_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;
+ goto out;
}
array = sra->array;
} else {
pr_err("cannot get array detail for %s: %s\n",
dev, strerror(errno));
- close(fd);
- return rv;
+ goto out;
}
}
}
/* Ok, we have some info to print... */
- str = map_num(pers, array.level);
+ if (inactive && info)
+ str = map_num(pers, info->array.level);
+ else
+ str = map_num(pers, array.level);
if (c->export) {
+ char nbuf[64];
+ struct map_ent *mp = NULL, *map = NULL;
+
if (array.raid_disks) {
if (str)
printf("MD_LEVEL=%s\n", str);
array.minor_version);
}
- if (st && st->sb && info) {
- char nbuf[64];
- struct map_ent *mp, *map = NULL;
+ if (info)
+ mp = map_by_uuid(&map, info->uuid);
+ if (!mp)
+ mp = map_by_devnm(&map, fd2devnm(fd));
- fname_from_uuid(st, info, nbuf, ':');
+ if (mp) {
+ detail_fname_from_uuid(mp, nbuf);
printf("MD_UUID=%s\n", nbuf + 5);
- mp = map_by_uuid(&map, info->uuid);
- if (mp && mp->path &&
- strncmp(mp->path, "/dev/md/", 8) == 0) {
- printf("MD_DEVNAME=");
- print_escape(mp->path + 8);
- putchar('\n');
- }
+ if (mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
+ printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN);
+ }
+ map_free(map);
+ if (st && st->sb) {
if (st->ss->export_detail_super)
st->ss->export_detail_super(st);
- map_free(map);
- } else {
- struct map_ent *mp, *map = NULL;
- char nbuf[64];
- mp = map_by_devnm(&map, fd2devnm(fd));
- if (mp) {
- __fname_from_uuid(mp->uuid, 0, nbuf, ':');
- printf("MD_UUID=%s\n", nbuf+5);
- }
- if (mp && mp->path &&
- strncmp(mp->path, "/dev/md/", 8) == 0) {
- printf("MD_DEVNAME=");
- print_escape(mp->path+8);
- putchar('\n');
- }
- map_free(map);
}
if (!c->no_devices && sra) {
struct mdinfo *mdi;
if (path)
printf("MD_DEVICE_%s_DEV=%s\n",
sysdev, path);
+ free(sysdev);
}
}
goto out;
avail = xcalloc(array.raid_disks, 1);
for (d = 0; d < array.raid_disks; d++) {
-
- if ((disks[d*2].state & (1<<MD_DISK_SYNC)) ||
- (disks[d*2+1].state & (1<<MD_DISK_SYNC))) {
+ char dv[PATH_MAX], dv_rep[PATH_MAX];
+ snprintf(dv, PATH_MAX, "/sys/dev/block/%d:%d",
+ disks[d*2].major, disks[d*2].minor);
+ snprintf(dv_rep, PATH_MAX, "/sys/dev/block/%d:%d",
+ disks[d*2+1].major, disks[d*2+1].minor);
+
+ if ((is_dev_alive(dv) && (disks[d*2].state & (1<<MD_DISK_SYNC))) ||
+ (is_dev_alive(dv_rep) && (disks[d*2+1].state & (1<<MD_DISK_SYNC)))) {
avail_disks ++;
avail[d] = 1;
} else
if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) {
printf(" Intent Bitmap : %s\n", bmf.pathname);
printf("\n");
- } else if (array.state & (1<<MD_SB_BITMAP_PRESENT))
+ } else if (array.state & (1<<MD_SB_CLUSTERED))
+ printf(" Intent Bitmap : Internal(Clustered)\n\n");
+ else if (array.state & (1<<MD_SB_BITMAP_PRESENT))
printf(" Intent Bitmap : Internal\n\n");
atime = array.utime;
if (atime)
if (array.state & (1 << MD_SB_CLEAN)) {
if ((array.level == 0) ||
(array.level == LEVEL_LINEAR))
- arrayst = map_num(sysfs_array_states,
- sra->array_state);
+ arrayst = map_num_s(sysfs_array_states,
+ sra->array_state);
else
arrayst = "clean";
- } else
+ } else {
arrayst = "active";
+ if (array.state & (1<<MD_SB_CLUSTERED)) {
+ for (d = 0; d < max_disks * 2; d++) {
+ char *dv;
+ mdu_disk_info_t disk = disks[d];
+
+ /* only check first valid disk in cluster env */
+ if ((disk.state & (MD_DISK_SYNC | MD_DISK_ACTIVE))
+ && (disk.major | disk.minor)) {
+ dv = map_dev_preferred(disk.major, disk.minor, 0,
+ c->prefer);
+ if (!dv)
+ continue;
+ arrayst = IsBitmapDirty(dv) ? "active" : "clean";
+ break;
+ }
+ }
+ }
+ }
- printf(" State : %s%s%s%s%s%s \n",
+ printf(" State : %s%s%s%s%s%s%s \n",
arrayst, st,
(!e || (e->percent < 0 &&
e->percent != RESYNC_PENDING &&
- e->percent != RESYNC_DELAYED)) ?
+ e->percent != RESYNC_DELAYED &&
+ e->percent != RESYNC_REMOTE)) ?
"" : sync_action[e->resync],
larray_size ? "": ", Not Started",
(e && e->percent == RESYNC_DELAYED) ?
" (DELAYED)": "",
(e && e->percent == RESYNC_PENDING) ?
- " (PENDING)": "");
+ " (PENDING)": "",
+ (e && e->percent == RESYNC_REMOTE) ?
+ " (REMOTE)": "");
} else if (inactive && !is_container) {
printf(" State : inactive\n");
}
array.working_disks);
if (array.raid_disks) {
printf(" Failed Devices : %d\n", array.failed_disks);
- printf(" Spare Devices : %d\n", array.spare_disks);
+ if (!external)
+ printf(" Spare Devices : %d\n", array.spare_disks);
}
printf("\n");
if (array.level == 5) {
printf(" Layout : %s\n",
str ? str : "-unknown-");
}
+ if (array.level == 0 && array.layout) {
+ str = map_num(r0layout, array.layout);
+ printf(" Layout : %s\n",
+ str ? str : "-unknown-");
+ }
if (array.level == 6) {
str = map_num(r6layout, array.layout);
printf(" Layout : %s\n",
}
if ((st && st->sb) && (info && info->reshape_active)) {
-#if 0
-This is pretty boring
- 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)
printf(" Delta Devices : %d, (%d->%d)\n",
info->delta_disks,
free_mdstat(ms);
if (st && st->sb)
- st->ss->detail_super(st, c->homehost);
+ st->ss->detail_super(st, c->homehost, subarray);
if (array.raid_disks == 0 && sra &&
sra->array.major_version == -1 &&
&max_devices, n_devices);
else
printf(" %s", dv);
- }
+ } else if (disk.major | disk.minor)
+ printf(" missing");
if (!c->brief)
printf("\n");
}
if (spares && c->brief && array.raid_disks)
printf(" spares=%d", spares);
if (c->brief && st && st->sb)
- st->ss->brief_detail_super(st);
+ st->ss->brief_detail_super(st, subarray);
if (st)
st->ss->free_super(st);
close(fd);
free(subarray);
free(avail);
- for (d = 0; d < n_devices; d++)
- free(devices[d]);
+ if (devices)
+ for (d = 0; d < n_devices; d++)
+ free(devices[d]);
free(devices);
sysfs_free(sra);
+ free(st);
return rv;
}