X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=Detail.c;h=ae00bb493373c46292927fd64d3743c472ec2833;hp=2b2111cd2f448cf691753d9382cda86c2eea4910;hb=ff54de6e47163944185f231700e72d3122b58f4c;hpb=3dff19c8e867360b703f864497d8d0e0fb95a568 diff --git a/Detail.c b/Detail.c index 2b2111cd..ae00bb49 100644 --- a/Detail.c +++ b/Detail.c @@ -30,6 +30,7 @@ #include "mdadm.h" #include "md_p.h" #include "md_u.h" +#include int Detail(char *dev, int brief, int export, int test, char *homehost) { @@ -56,6 +57,8 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) int max_disks = MD_SB_DISKS; /* just a default */ struct mdinfo info; struct mdinfo *sra; + char *member = NULL; + char *container = NULL; int rv = test ? 4 : 1; int avail_disks = 0; @@ -96,7 +99,21 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) stb.st_rdev = 0; rv = 0; - if (st) max_disks = st->max_devs; + if (st) + max_disks = st->max_devs; + + if (sra && is_subarray(sra->text_version) && + strchr(sra->text_version+1, '/')) { + /* This is a subarray of some container. + * We want the name of the container, and the member + */ + char *s = strchr(sra->text_version+1, '/'); + int dn; + *s++ = '\0'; + member = s; + dn = devname2devnum(sra->text_version+1); + container = map_dev(dev2major(dn), dev2minor(dn), 1); + } /* try to load a superblock */ for (d= 0; dsb) && - (disk.state & (1<=0 && st && st->ss->load_super(st, fd2, NULL) == 0) { st->ss->getinfo_super(st, &info); - if (info.array.ctime != array.ctime || - info.array.level != array.level) + if (array.raid_disks != 0 && /* container */ + (info.array.ctime != array.ctime || + info.array.level != array.level)) st->ss->free_super(st); } if (fd2 >= 0) close(fd2); @@ -132,14 +151,24 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) c = map_num(pers, array.level); if (export) { - if (c) - printf("MD_LEVEL=%s\n", c); - printf("MD_DEVICES=%d\n", array.raid_disks); - if (sra && sra->array.major_version < 0) - printf("MD_METADATA=%s\n", sra->text_version); - else - printf("MD_METADATA=%02d.%02d\n", - array.major_version, array.minor_version); + if (array.raid_disks) { + if (c) + printf("MD_LEVEL=%s\n", c); + printf("MD_DEVICES=%d\n", array.raid_disks); + } else { + printf("MD_LEVEL=container\n"); + printf("MD_DEVICES=%d\n", array.nr_disks); + } + if (container) { + printf("MD_CONTAINER=%s\n", container); + printf("MD_MEMBER=%s\n", member); + } else { + if (sra && sra->array.major_version < 0) + printf("MD_METADATA=%s\n", sra->text_version); + else + printf("MD_METADATA=%02d.%02d\n", + array.major_version, array.minor_version); + } if (st && st->sb) st->ss->export_detail_super(st); @@ -148,14 +177,24 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) if (brief) { mdu_bitmap_file_t bmf; - printf("ARRAY %s level=%s num-devices=%d", dev, - c?c:"-unknown-", - array.raid_disks ); - if (sra && sra->array.major_version < 0) - printf(" metadata=%s", sra->text_version); + if (array.raid_disks) + printf("ARRAY %s level=%s num-devices=%d", dev, + c?c:"-unknown-", + array.raid_disks ); else - printf(" metadata=%02d.%02d", - array.major_version, array.minor_version); + printf("ARRAY %s level=container num-devices=%d", + dev, array.nr_disks); + + if (container) { + printf(" container=%s", container); + printf(" member=%s", member); + } else { + if (sra && sra->array.major_version < 0) + printf(" metadata=%s", sra->text_version); + else + printf(" metadata=%02d.%02d", + array.major_version, array.minor_version); + } /* Only try GET_BITMAP_FILE for 0.90.01 and later */ if (vers >= 9001 && @@ -180,14 +219,19 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) printf("%s:\n", dev); + if (container) + printf(" Container : %s, member %s\n", container, member); + else { if (sra && sra->array.major_version < 0) printf(" Version : %s\n", sra->text_version); else printf(" Version : %02d.%02d\n", array.major_version, array.minor_version); + } atime = array.ctime; - printf(" Creation Time : %.24s\n", ctime(&atime)); + if (atime) + printf(" Creation Time : %.24s\n", ctime(&atime)); if (array.raid_disks == 0) c = "container"; printf(" Raid Level : %s\n", c?c:"-unknown-"); if (larray_size) @@ -206,9 +250,13 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) printf(" Used Dev Size : %d%s\n", array.size, human_size((long long)array.size<<10)); } - printf(" Raid Devices : %d\n", array.raid_disks); + if (array.raid_disks) + printf(" Raid Devices : %d\n", array.raid_disks); printf(" Total Devices : %d\n", array.nr_disks); - printf("Preferred Minor : %d\n", array.md_minor); + if (!container && + ((sra == NULL && array.major_version == 0) || + (sra && sra->array.major_version == 0))) + printf("Preferred Minor : %d\n", array.md_minor); if (sra == NULL || sra->array.major_version >= 0) printf(" Persistence : Superblock is %spersistent\n", array.not_persistent?"not ":""); @@ -222,17 +270,22 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) } else if (array.state & (1<percent < 0) ? "" : - (e->resync) ? ", resyncing": ", recovering", - larray_size ? "": ", Not Started"); - printf(" Active Devices : %d\n", array.active_disks); + if (atime) + printf(" Update Time : %.24s\n", ctime(&atime)); + if (array.raid_disks) + printf(" State : %s%s%s%s\n", + (array.state&(1<percent < 0) ? "" : + (e->resync) ? ", resyncing": ", recovering", + larray_size ? "": ", Not Started"); + if (array.raid_disks) + printf(" Active Devices : %d\n", array.active_disks); printf("Working Devices : %d\n", array.working_disks); - printf(" Failed Devices : %d\n", array.failed_disks); - printf(" Spare Devices : %d\n", array.spare_disks); + if (array.raid_disks) { + printf(" Failed Devices : %d\n", array.failed_disks); + printf(" Spare Devices : %d\n", array.spare_disks); + } printf("\n"); if (array.level == 5) { c = map_num(r5layout, array.layout); @@ -306,7 +359,45 @@ This is pretty boring if (st && st->sb) st->ss->detail_super(st, homehost); - printf(" Number Major Minor RaidDevice State\n"); + if (array.raid_disks == 0 && sra && sra->array.major_version == -1 + && sra->array.minor_version == -2 && sra->text_version[0] != '/') { + /* This looks like a container. Find any active arrays + * That claim to be a member. + */ + DIR *dir = opendir("/sys/block"); + struct dirent *de; + + printf(" Member Arrays :"); + + while (dir && (de = readdir(dir)) != NULL) { + char path[200]; + char vbuf[1024]; + int nlen = strlen(sra->sys_name); + int dn; + if (de->d_name[0] == '.') + continue; + sprintf(path, "/sys/block/%s/md/metadata_version", + de->d_name); + if (load_sys(path, vbuf) < 0) + continue; + if (strncmp(vbuf, "external:", 9) != 0 || + !is_subarray(sra->sys_name+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)); + } + if (dir) + closedir(dir); + printf("\n\n"); + } + + if (array.raid_disks) + printf(" Number Major Minor RaidDevice State\n"); + else + printf(" Number Major Minor RaidDevice\n"); } disks = malloc(max_disks * sizeof(mdu_disk_info_t)); for (d=0; dsb) st->ss->brief_detail_super(st); st->ss->free_super(st);