]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Detail.c
Coverity: Resource leak: close fd before return
[thirdparty/mdadm.git] / Detail.c
index ef2370ceefb0547df69e8414bf6950408a520c60..b3e857a7e2c934a06ff43451cde56f186f539ec5 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -80,13 +80,15 @@ int Detail(char *dev, struct context *c)
        char *avail = NULL;
        int external;
        int inactive;
+       int is_container = 0;
 
        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 +98,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 +231,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 +263,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,6 +278,7 @@ int Detail(char *dev, struct context *c)
                                print_escape(mp->path+8);
                                putchar('\n');
                        }
+                       map_free(map);
                }
                if (sra) {
                        struct mdinfo *mdi;
@@ -311,11 +319,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 +362,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 +424,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);
@@ -487,7 +497,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)
@@ -553,7 +563,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,6 +610,8 @@ 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);
 
@@ -714,9 +725,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)