]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Monitor.c
mdadm-1.2.0
[thirdparty/mdadm.git] / Monitor.c
index 32181e45ed63100c672e5dc32ddcbd84f6400f29..da73af6f3a7a5b18718771421b64336f530d8e55 100644 (file)
--- a/Monitor.c
+++ b/Monitor.c
@@ -45,7 +45,7 @@ static char *percentalerts[] = {
 
 int Monitor(mddev_dev_t devlist,
            char *mailaddr, char *alert_cmd,
-           int period, int scan,
+           int period, int daemonise, int scan,
            char *config)
 {
        /*
@@ -105,12 +105,39 @@ int Monitor(mddev_dev_t devlist,
        int finished = 0;
        struct mdstat_ent *mdstat = NULL;
 
-       if (!mailaddr && scan)
+       if (!mailaddr) {
                mailaddr = conf_get_mailaddr(config);
-       if (!alert_cmd && scan)
+               if (mailaddr && ! scan)
+                       fprintf(stderr, Name ": Monitor using email address \"%s\" from config file\n",
+                              mailaddr);
+       }
+       if (!alert_cmd) {
                alert_cmd = conf_get_program(config);
-       if (scan && !mailaddr && !alert_cmd)
-               return 0;
+               if (alert_cmd && ! scan)
+                       fprintf(stderr, Name ": Monitor using program \"%s\" from config file\n",
+                              alert_cmd);
+       }
+       if (scan && !mailaddr && !alert_cmd) {
+               fprintf(stderr, Name ": No mail address or alert command - not monitoring.\n");
+               return 1;
+       }
+
+       if (daemonise) {
+               int pid = fork();
+               if (pid > 0) {
+                       printf("%d\n", pid);
+                       return 0;
+               }
+               if (pid < 0) {
+                       perror("daemonise");
+                       return 1;
+               }
+               close(0);
+               open("/dev/null", 3);
+               dup2(0,1);
+               dup2(0,2);
+               setsid();
+       }
 
        if (devlist == NULL) {
                mddev_ident_t mdlist = conf_get_ident(config, NULL);
@@ -121,7 +148,7 @@ int Monitor(mddev_dev_t devlist,
                        st->devname = strdup(mdlist->devname);
                        st->utime = 0;
                        st->next = statelist;
-                       st->err = 1;
+                       st->err = 0;
                        st->devnum = -1;
                        st->percent = -2;
                        if (mdlist->spare_group)
@@ -139,7 +166,7 @@ int Monitor(mddev_dev_t devlist,
                        st->devname = strdup(dv->devname);
                        st->utime = 0;
                        st->next = statelist;
-                       st->err = 1;
+                       st->err = 0;
                        st->devnum = -1;
                        st->percent = -2;
                        st->spare_group = NULL;
@@ -182,6 +209,14 @@ int Monitor(mddev_dev_t devlist,
                                close(fd);
                                continue;
                        }
+                       if (array.level != 1 && array.level != 5 && array.level != -4) {
+                               if (!st->err)
+                                       alert("DeviceDisappeared", dev, "Wrong-Level",
+                                             mailaddr, alert_cmd);
+                               st->err = 1;
+                               close(fd);
+                               continue;
+                       }
                        if (st->devnum < 0) {
                                struct stat stb;
                                if (fstat(fd, &stb) == 0 &&
@@ -229,7 +264,7 @@ int Monitor(mddev_dev_t devlist,
                                if (ioctl(fd, GET_DISK_INFO, &disc)>= 0) {
                                        newstate = disc.state;
                                        dv = map_dev(disc.major, disc.minor);
-                               } else if (mse && i < strlen(mse->pattern))
+                               } else if (mse &&  mse->pattern && i < strlen(mse->pattern))
                                        switch(mse->pattern[i]) {
                                        case 'U': newstate = 6 /* ACTIVE/SYNC */; break;
                                        case '_': newstate = 0; break;
@@ -271,7 +306,11 @@ int Monitor(mddev_dev_t devlist,
                if (scan) {
                        struct mdstat_ent *mse;
                        for (mse=mdstat; mse; mse=mse->next) 
-                               if (mse->devnum > 0) {
+                               if (mse->devnum >= 0 &&
+                                   (strcmp(mse->level, "raid1")==0 ||
+                                    strcmp(mse->level, "raid5")==0 ||
+                                    strcmp(mse->level, "multipath")==0)
+                                       ) {
                                        struct state *st = malloc(sizeof *st);
                                        if (st == NULL)
                                                continue;
@@ -378,7 +417,7 @@ static void alert(char *event, char *dev, char *disc, char *mailaddr, char *cmd)
                        fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev);
 
                        if (disc)
-                               fprintf(mp, "It could be related to sub-device %s.\n\n", disc);
+                               fprintf(mp, "It could be related to component device %s.\n\n", disc);
 
                        fprintf(mp, "Faithfully yours, etc.\n");
                        fclose(mp);