]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Fix for segfault when reading /proc/mdstat
authorNeil Brown <neilb@suse.de>
Mon, 28 Apr 2008 06:29:12 +0000 (16:29 +1000)
committerNeil Brown <neilb@suse.de>
Mon, 28 Apr 2008 06:29:12 +0000 (16:29 +1000)
Some kernel versions don't put a space between 'active' and '(auto-read-only)'
in /proc/mdstat.  This causes a parsing problem leaving 'level' set to
NULL which causes a crash.

So synthesise a space there if it is missing, and check for 'level' to
be NULL and don't de-ref if it is.

ChangeLog
Incremental.c
Monitor.c
config.c

index fa4fed4551bc2aa79dd5b44ccc4b5dcddd337114..fdf720d24cacf2d8b057314c596184c4c2b715e6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Changes Prior to this release
+    -   Avoid segfault when parsing /proc/mdstat with auto-read-only
+       arrays.
+
 Changes Prior to 2.6.4 release
     -   Make "--create --auto=mdp" work for non-standard device names.
     -   Fix restarting of a 'reshape' if it was stopped in the middle.
index ab37ef0ca9a79a5b30971db6d20b2d2572869871..4c6a2a7949a3d5dd222795a782b7aaa4734bdb46 100644 (file)
@@ -332,6 +332,7 @@ int Incremental(char *devname, int verbose, int runstop,
                struct supertype *st2;
                sra = sysfs_read(mdfd, devnum, (GET_VERSION | GET_DEVS |
                                                GET_STATE));
+
                if (sra->array.major_version != st->ss->major ||
                    sra->array.minor_version != st->minor_version) {
                        if (verbose >= 0)
index 6b0c760b94e45f5c64dd08c35ffc1aa1732709fc..54193f5c1fa51c1c1537164d167d83d774d4033f 100644 (file)
--- a/Monitor.c
+++ b/Monitor.c
@@ -403,6 +403,7 @@ int Monitor(mddev_dev_t devlist,
                        struct mdstat_ent *mse;
                        for (mse=mdstat; mse; mse=mse->next)
                                if (mse->devnum != INT_MAX &&
+                                   mse->level &&
                                    (strcmp(mse->level, "raid0")!=0 &&
                                     strcmp(mse->level, "linear")!=0)
                                        ) {
index 29eadc5927c06816593f0f7c9d1d744a27a1e7a5..121b3373554076212b844823847bce18e7d96eff 100644 (file)
--- a/config.c
+++ b/config.c
@@ -161,11 +161,24 @@ char *conf_word(FILE *file, int allow_key)
                                        word[len++] = c;
                                }
                                c = getc(file);
+                               /* Hack for broken kernels (2.6.14-.24) that put
+                                *        "active(auto-read-only)"
+                                * in /proc/mdstat instead of
+                                *        "active (auto-read-only)"
+                                */
+                               if (c == '(' && len >= 6
+                                   && strncmp(word+len-6, "active", 6) == 0)
+                                       c = ' ';
                        }
                }
                if (c != EOF) ungetc(c, file);
        }
        word[len] = 0;
+
+       /* Further HACK for broken kernels.. 2.6.14-2.6.24 */
+       if (strcmp(word, "auto-read-only)") == 0)
+               strcpy(word, "(auto-read-only)");
+
 /*    printf("word is <%s>\n", word); */
        if (!wordfound) {
                free(word);