]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Detail.c
Grow: fix resize of array component size to > 32bits
[thirdparty/mdadm.git] / Detail.c
index 33b3a18d094482ff48fa5a5e8a8238eb8a610d35..c4fcad9620ba30aa2db22251dc9a9a5a6af1c29c 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -1,7 +1,7 @@
 /*
  * mdadm - manage Linux "md" devices aka RAID arrays.
  *
- * Copyright (C) 2001-2012 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2001-2013 Neil Brown <neilb@suse.de>
  *
  *
  *    This program is free software; you can redistribute it and/or modify
 #include       "md_u.h"
 #include       <dirent.h>
 
+static int cmpstringp(const void *p1, const void *p2)
+{
+       return strcmp(* (char * const *) p1, * (char * const *) p2);
+}
+
+static int add_device(const char *dev, char ***p_devices,
+                     int *p_max_devices, int n_devices)
+{
+       if (n_devices + 1 >= *p_max_devices) {
+               *p_max_devices += 16;
+               *p_devices = xrealloc(*p_devices, *p_max_devices *
+                                     sizeof(**p_devices));
+               if (!*p_devices) {
+                       *p_max_devices = 0;
+                       return 0;
+               }
+       };
+       (*p_devices)[n_devices] = xstrdup(dev);
+       return n_devices + 1;
+}
+
 int Detail(char *dev, struct context *c)
 {
        /*
@@ -42,7 +63,8 @@ int Detail(char *dev, struct context *c)
        int d;
        time_t atime;
        char *str;
-       char *devices = NULL;
+       char **devices = NULL;
+       int max_devices = 0, n_devices = 0;
        int spares = 0;
        struct stat stb;
        int is_26 = get_linux_version() >= 2006000;
@@ -87,7 +109,7 @@ int Detail(char *dev, struct context *c)
        st = super_by_fd(fd, &subarray);
        if (ioctl(fd, GET_ARRAY_INFO, &array) == 0) {
                inactive = 0;
-       } else if (errno == ENODEV) {
+       } else if (errno == ENODEV && sra) {
                array = sra->array;
                inactive = 1;
        } else {
@@ -251,6 +273,25 @@ int Detail(char *dev, struct context *c)
                                putchar('\n');
                        }
                }
+               if (sra) {
+                       struct mdinfo *mdi;
+                       for (mdi  = sra->devs; mdi; mdi = mdi->next) {
+                               char *path =
+                                       map_dev(mdi->disk.major,
+                                               mdi->disk.minor, 0);
+
+                               if (mdi->disk.raid_disk >= 0)
+                                       printf("MD_DEVICE_%s_ROLE=%d\n",
+                                              mdi->sys_name+4,
+                                              mdi->disk.raid_disk);
+                               else
+                                       printf("MD_DEVICE_%s_ROLE=spare\n",
+                                              mdi->sys_name+4);
+                               if (path)
+                                       printf("MD_DEVICE_%s_DEV=%s\n",
+                                              mdi->sys_name+4, path);
+                       }
+               }
                goto out;
        }
 
@@ -424,8 +465,8 @@ int Detail(char *dev, struct context *c)
                               (!e || (e->percent < 0 && e->percent != RESYNC_PENDING &&
                               e->percent != RESYNC_DELAYED)) ? "" : sync_action[e->resync],
                               larray_size ? "": ", Not Started",
-                              e->percent == RESYNC_DELAYED ? " (DELAYED)": "",
-                              e->percent == RESYNC_PENDING ? " (PENDING)": "");
+                              (e && e->percent == RESYNC_DELAYED) ? " (DELAYED)": "",
+                              (e && e->percent == RESYNC_PENDING) ? " (PENDING)": "");
                } else if (inactive) {
                        printf("          State : inactive\n");
                }
@@ -635,14 +676,11 @@ This is pretty boring
                        rv |= 1;
                dv=map_dev_preferred(disk.major, disk.minor, 0, c->prefer);
                if (dv != NULL) {
-                       if (c->brief) {
-                               if (devices) {
-                                       devices = xrealloc(devices,
-                                                         strlen(devices)+1+strlen(dv)+1);
-                                       strcat(strcat(devices,","),dv);
-                               } else
-                                       devices = xstrdup(dv);
-                       } else
+                       if (c->brief)
+                               n_devices = add_device(dv, &devices,
+                                                      &max_devices,
+                                                      n_devices);
+                       else
                                printf("   %s", dv);
                }
                if (!c->brief) printf("\n");
@@ -653,7 +691,12 @@ This is pretty boring
        if (st)
                st->ss->free_super(st);
 
-       if (c->brief && c->verbose > 0 && devices) printf("\n   devices=%s", devices);
+       if (c->brief && c->verbose > 0 && devices) {
+               qsort(devices, n_devices, sizeof(*devices), cmpstringp);
+               printf("\n   devices=%s", devices[0]);
+               for (d = 1; d < n_devices; d++)
+                       printf(",%s", devices[d]);
+       }
        if (c->brief)
                printf("\n");
        if (c->test &&
@@ -666,6 +709,9 @@ out:
        close(fd);
        free(subarray);
        free(avail);
+       for (d = 0; d < n_devices; d++)
+               free(devices[d]);
+       free(devices);
        sysfs_free(sra);
        return rv;
 }