]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Detail.c
Create: add support for RAID0 layouts.
[thirdparty/mdadm.git] / Detail.c
index ef2370ceefb0547df69e8414bf6950408a520c60..832485fe0fb5a10e9815abcb03c02be39b1cb9f6 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -56,7 +56,7 @@ int Detail(char *dev, struct context *c)
         */
        int fd = open(dev, O_RDONLY);
        mdu_array_info_t array;
-       mdu_disk_info_t *disks;
+       mdu_disk_info_t *disks = NULL;
        int next;
        int d;
        time_t atime;
@@ -80,13 +80,16 @@ int Detail(char *dev, struct context *c)
        char *avail = NULL;
        int external;
        int inactive;
+       int is_container = 0;
+       char *arrayst;
 
        if (fd < 0) {
                pr_err("cannot open %s: %s\n",
                        dev, strerror(errno));
                return rv;
        }
-       sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE);
+       sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS |
+                       GET_ARRAY_STATE | GET_STATE);
        if (!sra) {
                if (md_get_array_info(fd, &array)) {
                        pr_err("%s does not appear to be an md device\n", dev);
@@ -96,26 +99,30 @@ int Detail(char *dev, struct context *c)
        }
        external = (sra != NULL && sra->array.major_version == -1 &&
                    sra->array.minor_version == -2);
-       inactive = (sra->array_state == ARRAY_ACTIVE ||
-                   sra->array_state == ARRAY_CLEAR);
+       inactive = (sra != NULL && !md_array_is_active(sra));
        st = super_by_fd(fd, &subarray);
-       if (md_get_array_info(fd, &array) && errno == ENODEV) {
-               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);
+       if (md_get_array_info(fd, &array)) {
+               if (errno == ENODEV) {
+                       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;
+               } else {
+                       pr_err("cannot get array detail for %s: %s\n",
+                              dev, strerror(errno));
                        close(fd);
-                       sysfs_free(sra);
                        return rv;
                }
-               array = sra->array;
-       } else {
-               pr_err("cannot get array detail for %s: %s\n",
-                      dev, strerror(errno));
-               close(fd);
-               return rv;
        }
 
+       if (array.raid_disks == 0 && external)
+               is_container = 1;
        if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
                stb.st_rdev = 0;
        rv = 0;
@@ -225,7 +232,7 @@ int Detail(char *dev, struct context *c)
                                printf("MD_LEVEL=%s\n", str);
                        printf("MD_DEVICES=%d\n", array.raid_disks);
                } else {
-                       if (!inactive)
+                       if (is_container)
                                printf("MD_LEVEL=container\n");
                        printf("MD_DEVICES=%d\n", array.nr_disks);
                }
@@ -257,6 +264,7 @@ int Detail(char *dev, struct context *c)
 
                        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];
@@ -271,12 +279,13 @@ int Detail(char *dev, struct context *c)
                                print_escape(mp->path+8);
                                putchar('\n');
                        }
+                       map_free(map);
                }
-               if (sra) {
+               if (!c->no_devices && sra) {
                        struct mdinfo *mdi;
                        for (mdi  = sra->devs; mdi; mdi = mdi->next) {
                                char *path;
-                               char *sysdev = xstrdup(mdi->sys_name + 1);
+                               char *sysdev = xstrdup(mdi->sys_name);
                                char *cp;
 
                                path = map_dev(mdi->disk.major,
@@ -311,11 +320,10 @@ int Detail(char *dev, struct context *c)
        next = array.raid_disks * 2;
        if (inactive) {
                struct mdinfo *mdi;
-               if (sra != NULL)
-                       for (mdi = sra->devs; mdi; mdi = mdi->next) {
-                               disks[next++] = mdi->disk;
-                               disks[next - 1].number = -1;
-                       }
+               for (mdi = sra->devs; mdi; mdi = mdi->next) {
+                       disks[next++] = mdi->disk;
+                       disks[next - 1].number = -1;
+               }
        } else for (d = 0; d < max_disks; d++) {
                mdu_disk_info_t disk;
                disk.number = d;
@@ -355,13 +363,16 @@ int Detail(char *dev, struct context *c)
 
        if (c->brief) {
                mdu_bitmap_file_t bmf;
-               printf("%sARRAY %s", inactive ? "INACTIVE-":"", dev);
+               if (inactive && !is_container)
+                       printf("INACTIVE-ARRAY %s", dev);
+               else
+                       printf("ARRAY %s", dev);
                if (c->verbose > 0) {
                        if (array.raid_disks)
                                printf(" level=%s num-devices=%d",
                                       str ? str : "-unknown-",
                                       array.raid_disks);
-                       else if (!inactive)
+                       else if (is_container)
                                printf(" level=container num-devices=%d",
                                       array.nr_disks);
                        else
@@ -414,7 +425,7 @@ int Detail(char *dev, struct context *c)
                atime = array.ctime;
                if (atime)
                        printf("     Creation Time : %.24s\n", ctime(&atime));
-               if (array.raid_disks == 0 && external)
+               if (is_container)
                        str = "container";
                if (str)
                        printf("        Raid Level : %s\n", str);
@@ -475,9 +486,18 @@ int Detail(char *dev, struct context *c)
                        else
                                st = ", degraded";
 
+                       if (array.state & (1 << MD_SB_CLEAN)) {
+                               if ((array.level == 0) ||
+                                   (array.level == LEVEL_LINEAR))
+                                       arrayst = map_num(sysfs_array_states,
+                                                         sra->array_state);
+                               else
+                                       arrayst = "clean";
+                       } else
+                               arrayst = "active";
+
                        printf("             State : %s%s%s%s%s%s \n",
-                              (array.state & (1 << MD_SB_CLEAN)) ?
-                              "clean" : "active", st,
+                              arrayst, st,
                               (!e || (e->percent < 0 &&
                                       e->percent != RESYNC_PENDING &&
                                       e->percent != RESYNC_DELAYED)) ?
@@ -487,7 +507,7 @@ int Detail(char *dev, struct context *c)
                               " (DELAYED)": "",
                               (e && e->percent == RESYNC_PENDING) ?
                               " (PENDING)": "");
-               } else if (inactive) {
+               } else if (inactive && !is_container) {
                        printf("             State : inactive\n");
                }
                if (array.raid_disks)
@@ -505,6 +525,11 @@ int Detail(char *dev, struct context *c)
                        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",
@@ -553,7 +578,6 @@ int Detail(char *dev, struct context *c)
                        printf("    %7s Status : %d%% complete\n",
                               sync_action[e->resync], e->percent);
                }
-               free_mdstat(ms);
 
                if ((st && st->sb) && (info && info->reshape_active)) {
 #if 0
@@ -601,8 +625,10 @@ This is pretty boring
                        printf("\n");
                } else if (e && e->percent >= 0)
                        printf("\n");
+               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 &&
@@ -644,12 +670,17 @@ This is pretty boring
                        printf("\n\n");
                }
 
-               if (array.raid_disks)
-                       printf("    Number   Major   Minor   RaidDevice State\n");
-               else
-                       printf("    Number   Major   Minor   RaidDevice\n");
+               if (!c->no_devices) {
+                       if (array.raid_disks)
+                               printf("    Number   Major   Minor   RaidDevice State\n");
+                       else
+                               printf("    Number   Major   Minor   RaidDevice\n");
+               }
        }
-       free(info);
+
+       /* if --no_devices specified, not print component devices info */
+       if (c->no_devices)
+               goto skip_devices_state;
 
        for (d = 0; d < max_disks * 2; d++) {
                char *dv;
@@ -714,9 +745,9 @@ This is pretty boring
                        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_JOURNAL)))
-                           == 0) {
+                            ((1 << MD_DISK_ACTIVE) | (1 << MD_DISK_SYNC) |
+                             (1 << MD_DISK_REMOVED) | (1 << MD_DISK_FAULTY) |
+                             (1 << MD_DISK_JOURNAL))) == 0) {
                                printf(" spare");
                                if (disk.raid_disk < array.raid_disks &&
                                    disk.raid_disk >= 0)
@@ -736,10 +767,12 @@ This is pretty boring
                if (!c->brief)
                        printf("\n");
        }
+
+skip_devices_state:
        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);
 
@@ -755,8 +788,9 @@ This is pretty boring
            !enough(array.level, array.raid_disks, array.layout, 1, avail))
                rv = 2;
 
-       free(disks);
 out:
+       free(info);
+       free(disks);
        close(fd);
        free(subarray);
        free(avail);