]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Monitor.c
Improve partition table code.
[thirdparty/mdadm.git] / Monitor.c
index e0a9d2a614a464816cfea126f21e3cd71982f954..b0802f868043474a14e807f8005de3ca04d387aa 100644 (file)
--- a/Monitor.c
+++ b/Monitor.c
@@ -1,7 +1,7 @@
 /*
  * mdadm - manage Linux "md" devices aka RAID arrays.
  *
- * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
  *
  *
  *    This program is free software; you can redistribute it and/or modify
  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *    Author: Neil Brown
- *    Email: <neilb@cse.unsw.edu.au>
- *    Paper: Neil Brown
- *           School of Computer Science and Engineering
- *           The University of New South Wales
- *           Sydney, 2052
- *           Australia
+ *    Email: <neilb@suse.de>
  */
 
 #include       "mdadm.h"
 static void alert(char *event, char *dev, char *disc, char *mailaddr, char *mailfrom,
                  char *cmd, int dosyslog);
 
-static char *percentalerts[] = {
-       "RebuildStarted",
-       "Rebuild20",
-       "Rebuild40",
-       "Rebuild60",
-       "Rebuild80",
-};
-
 /* The largest number of disks current arrays can manage is 384
  * This really should be dynamically, but that will have to wait
  * At least it isn't MD_SB_DISKS.
@@ -54,7 +41,7 @@ static char *percentalerts[] = {
 int Monitor(mddev_dev_t devlist,
            char *mailaddr, char *alert_cmd,
            int period, int daemonise, int scan, int oneshot,
-           int dosyslog, int test, char* pidfile)
+           int dosyslog, int test, char* pidfile, int increments)
 {
        /*
         * Every few seconds, scan every md device looking for changes
@@ -82,8 +69,8 @@ int Monitor(mddev_dev_t devlist,
         *      An active device had a reverse transition
         *    RebuildStarted
         *      percent went from -1 to +ve
-        *    Rebuild20 Rebuild40 Rebuild60 Rebuild80
-        *      percent went from below to not-below that number
+        *    RebuildNN
+        *      percent went from below to not-below NN%
         *    DeviceDisappeared
         *      Couldn't access a device which was previously visible
         *
@@ -165,10 +152,21 @@ int Monitor(mddev_dev_t devlist,
        if (devlist == NULL) {
                mddev_ident_t mdlist = conf_get_ident(NULL);
                for (; mdlist; mdlist=mdlist->next) {
-                       struct state *st = malloc(sizeof *st);
+                       struct state *st;
+                       if (mdlist->devname == NULL)
+                               continue;
+                       if (strcasecmp(mdlist->devname, "<ignore>") == 0)
+                               continue;
+                       st = malloc(sizeof *st);
                        if (st == NULL)
                                continue;
-                       st->devname = strdup(mdlist->devname);
+                       if (mdlist->devname[0] == '/')
+                               st->devname = strdup(mdlist->devname);
+                       else {
+                               st->devname = malloc(8+strlen(mdlist->devname)+1);
+                               strcpy(strcpy(st->devname, "/dev/md/"),
+                                      mdlist->devname);
+                       }
                        st->utime = 0;
                        st->next = statelist;
                        st->err = 0;
@@ -273,6 +271,10 @@ int Monitor(mddev_dev_t devlist,
                                        mse = mse2;
                                }
 
+                       if (array.utime == 0)
+                               /* external arrays don't update utime */
+                               array.utime = time(0);
+
                        if (st->utime == array.utime &&
                            st->failed == array.failed_disks &&
                            st->working == array.working_disks &&
@@ -301,9 +303,17 @@ int Monitor(mddev_dev_t devlist,
                        if (mse &&
                            st->percent >= 0 &&
                            mse->percent >= 0 &&
-                           (mse->percent / 20) > (st->percent / 20))
-                               alert(percentalerts[mse->percent/20],
+                           (mse->percent / increments) > (st->percent / increments)) {
+                               char percentalert[15]; // "RebuildNN" (10 chars) or "RebuildStarted" (15 chars)
+
+                               if((mse->percent / increments) == 0)
+                                       snprintf(percentalert, sizeof(percentalert), "RebuildStarted");
+                               else
+                                       snprintf(percentalert, sizeof(percentalert), "Rebuild%02d", mse->percent);
+
+                               alert(percentalert,
                                      dev, NULL, mailaddr, mailfrom, alert_cmd, dosyslog);
+                       }
 
                        if (mse &&
                            mse->percent == -1 &&
@@ -571,7 +581,7 @@ static void alert(char *event, char *dev, char *disc, char *mailaddr, char *mail
                                        n=fwrite(buf, 1, n, mp); /* yes, i don't care about the result */
                                fclose(mdstat);
                        }
-                       fclose(mp);
+                       pclose(mp);
                }
 
        }
@@ -613,10 +623,7 @@ int Wait(char *dev)
                        strerror(errno));
                return 2;
        }
-       if (major(stb.st_rdev) == MD_MAJOR)
-               devnum = minor(stb.st_rdev);
-       else
-               devnum = -1-(minor(stb.st_rdev)/64);
+       devnum = stat2devnum(&stb);
 
        while(1) {
                struct mdstat_ent *ms = mdstat_read(1, 0);
@@ -627,6 +634,13 @@ int Wait(char *dev)
                                break;
 
                if (!e || e->percent < 0) {
+                       if (e && e->metadata_version &&
+                           strncmp(e->metadata_version, "external:", 9) == 0) {
+                               if (is_subarray(&e->metadata_version[9]))
+                                       ping_monitor(&e->metadata_version[9]);
+                               else
+                                       ping_monitor(devnum2devname(devnum));
+                       }
                        free_mdstat(ms);
                        return rv;
                }