]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Detail.c
Improve reporting of layout for raid10.
[thirdparty/mdadm.git] / Detail.c
index 22f0e5c0301d594f7a14fc0c0a085bd262ae5ac0..25b91b1e256b5cdf94fe9ff3d69a052de024f6cb 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -38,7 +38,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
         * GET_ARRAY_INFO and GET_DISK_INFO ioctl calls
         */
 
-       int fd = open(dev, O_RDONLY, 0);
+       int fd = open(dev, O_RDONLY);
        int vers;
        mdu_array_info_t array;
        mdu_disk_info_t *disks;
@@ -55,8 +55,8 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
        struct supertype *st = NULL;
        int max_disks = MD_SB_DISKS; /* just a default */
        struct mdinfo info;
+       struct mdinfo *sra;
 
-       void *super = NULL;
        int rv = test ? 4 : 1;
        int avail_disks = 0;
        char *avail;
@@ -89,7 +89,8 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                close(fd);
                return rv;
        }
-       st = super_by_version(array.major_version, array.minor_version);
+       sra = sysfs_read(fd, 0, GET_VERSION);
+       st = super_by_fd(fd);
 
        if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
                stb.st_rdev = 0;
@@ -109,19 +110,18 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                    disk.minor == 0)
                        continue;
                if ((dv=map_dev(disk.major, disk.minor, 1))) {
-                       if (!super && (disk.state & (1<<MD_DISK_ACTIVE))) {
+                       if ((!st || !st->sb) &&
+                           (disk.state & (1<<MD_DISK_ACTIVE))) {
                                /* try to read the superblock from this device
                                 * to get more info
                                 */
                                int fd2 = dev_open(dv, O_RDONLY);
                                if (fd2 >=0 && st &&
-                                   st->ss->load_super(st, fd2, &super, NULL) == 0) {
-                                       st->ss->getinfo_super(&info, super);
+                                   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) {
-                                               free(super);
-                                               super = NULL;
-                                       }
+                                           info.array.level != array.level)
+                                               st->ss->free_super(st);
                                }
                                if (fd2 >= 0) close(fd2);
                        }
@@ -135,19 +135,35 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                if (c)
                        printf("MD_LEVEL=%s\n", c);
                printf("MD_DEVICES=%d\n", array.raid_disks);
-               printf("MD_METADATA=%d.%d\n", array.major_version,
-                      array.minor_version);
-               if (super)
-                       st->ss->export_super(super);
+               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);
                goto out;
        }
 
-       if (brief)
-               printf("ARRAY %s level=%s metadata=%d.%d num-devices=%d", dev,
+       if (brief) {
+               mdu_bitmap_file_t bmf;
+               printf("ARRAY %s level=%s num-devices=%d", dev,
                       c?c:"-unknown-",
-                      array.major_version, array.minor_version,
                       array.raid_disks );
-       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 &&
+                   ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 &&
+                   bmf.pathname[0]) {
+                       printf(" bitmap=%s", bmf.pathname);
+               }
+       } else {
                mdu_bitmap_file_t bmf;
                unsigned long long larray_size;
                struct mdstat_ent *ms = mdstat_read(0, 0);
@@ -163,10 +179,16 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                        larray_size = 0;
 
                printf("%s:\n", dev);
-               printf("        Version : %02d.%02d.%02d\n",
-                      array.major_version, array.minor_version, array.patch_version);
+
+               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 (array.raid_disks == 0) c = "container";
                printf("     Raid Level : %s\n", c?c:"-unknown-");
                if (larray_size)
                        printf("     Array Size : %llu%s\n", (larray_size>>10), human_size(larray_size));
@@ -177,7 +199,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                                if (dsize > 0)
                                        printf("  Used Dev Size : %llu%s\n",
                                               dsize,
-                                        human_size((long long)array.size<<10));
+                                        human_size((long long)dsize<<10));
                                else
                                        printf("  Used Dev Size : unknown\n");
                        } else
@@ -187,8 +209,9 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                printf("   Raid Devices : %d\n", array.raid_disks);
                printf("  Total Devices : %d\n", array.nr_disks);
                printf("Preferred Minor : %d\n", array.md_minor);
-               printf("    Persistence : Superblock is %spersistent\n",
-                      array.not_persistent?"not ":"");
+               if (sra == NULL || sra->array.major_version >= 0)
+                       printf("    Persistence : Superblock is %spersistent\n",
+                              array.not_persistent?"not ":"");
                printf("\n");
                /* Only try GET_BITMAP_FILE for 0.90.01 and later */
                if (vers >= 9001 &&
@@ -216,9 +239,9 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                        printf("         Layout : %s\n", c?c:"-unknown-");
                }
                if (array.level == 10) {
-                       printf("         Layout : near=%d, %s=%d\n",
-                              array.layout&255, (array.layout&0x10000)?"offset":"far",
-                              (array.layout>>8)&255);
+                       printf("         Layout :");
+                       print_r10_layout(array.layout);
+                       printf("\n");
                }
                switch (array.level) {
                case 0:
@@ -226,7 +249,9 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                case 5:
                case 10:
                case 6:
-                       printf("     Chunk Size : %dK\n\n", array.chunk_size/1024);
+                       if (array.chunk_size)
+                               printf("     Chunk Size : %dK\n\n",
+                                      array.chunk_size/1024);
                        break;
                case -1:
                        printf("       Rounding : %dK\n\n", array.chunk_size/1024);
@@ -236,13 +261,14 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
 
                if (e && e->percent >= 0) {
                        printf(" Re%s Status : %d%% complete\n",
-                              (super && info.reshape_active)? "shape":"build",
+                              (st && st->sb && info.reshape_active)?
+                                 "shape":"build",
                               e->percent);
                        is_rebuilding = 1;
                }
                free_mdstat(ms);
 
-               if (super && info.reshape_active) {
+               if (st->sb && info.reshape_active) {
 #if 0
 This is pretty boring
                        printf("  Reshape pos'n : %llu%s\n", (unsigned long long) info.reshape_progress<<9,
@@ -277,8 +303,8 @@ This is pretty boring
                        printf("\n");
                } else if (e && e->percent >= 0)
                        printf("\n");
-               if (super && st)
-                       st->ss->detail_super(super, homehost);
+               if (st && st->sb)
+                       st->ss->detail_super(st, homehost);
 
                printf("    Number   Major   Minor   RaidDevice State\n");
        }
@@ -376,8 +402,9 @@ This is pretty boring
                if (!brief) printf("\n");
        }
        if (spares && brief) printf(" spares=%d", spares);
-       if (super && brief && st)
-               st->ss->brief_detail_super(super);
+       if (brief && st && st->sb)
+               st->ss->brief_detail_super(st);
+       st->ss->free_super(st);
 
        if (brief > 1 && devices) printf("\n   devices=%s", devices);
        if (brief) printf("\n");