]>
git.ipfire.org Git - thirdparty/mdadm.git/blob - Monitor.c
968e4b3e4a4fe844feba4941ccd85520d1461c19
2 * mdctl - manage Linux "md" devices aka RAID arrays.
4 * Copyright (C) 2001 Neil Brown <neilb@cse.unsw.edu.au>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Email: <neilb@cse.unsw.edu.au>
24 * School of Computer Science and Engineering
25 * The University of New South Wales
33 #include <sys/signal.h>
35 static void alert(char *event
, char *dev
, char *disc
, char *mailaddr
, char *cmd
);
37 int Monitor(int num_devs
, char *devlist
[],
38 char *mailaddr
, char *alert_cmd
,
43 * Every few seconds, scan every md device looking for changes
44 * When a change is found, log it, possibly run the alert command,
45 * and possibly send Email
47 * For each array, we record:
49 * active/working/failed/spare drives
50 * State of each device.
52 * If the update time changes, check out all the data again
53 * It is possible that we cannot get the state of each device
54 * due to bugs in the md kernel module.
56 * if active_drives decreases, generate a "Fail" event
57 * if active_drives increases, generate a "SpareActive" event
59 * if we detect an array with active<raid and spare==0
60 * we look at other arrays that have same spare-group
61 * If we find one with active==raid and spare>0,
62 * and if we can get_disk_info and find a name
63 * Then we hot-remove and hot-add to the other array
71 int active
, working
, failed
, spare
;
72 int devstate
[MD_SB_DISKS
];
77 mddev_ident_t mdlist
= NULL
;
80 mdlist
= conf_get_ident(config
, NULL
);
81 while (dnum
< num_devs
|| mdlist
) {
82 mddev_ident_t mdident
;
84 mdu_array_info_t array
;
89 char *event_disc
= NULL
;
91 dev
= devlist
[dnum
++];
92 mdident
= conf_get_ident(config
, dev
);
95 dev
= mdident
->devname
;
96 mdlist
= mdlist
->next
;
98 for (st
=statelist
; st
; st
=st
->next
)
99 if (strcmp(st
->devname
, dev
)==0)
102 st
=malloc(sizeof *st
);
105 st
->devname
= strdup(dev
);
107 st
->next
= statelist
;
111 fd
= open(dev
, O_RDONLY
);
114 fprintf(stderr
, Name
": cannot open %s: %s\n",
115 dev
, strerror(errno
));
119 if (ioctl(fd
, GET_ARRAY_INFO
, &array
)<0) {
121 fprintf(stderr
, Name
": cannot get array info for %s: %s\n",
122 dev
, strerror(errno
));
129 if (st
->utime
== array
.utime
&&
130 st
->failed
== array
.failed_disks
) {
137 if (st
->active
> array
.active_disks
)
139 else if (st
->working
> array
.working_disks
)
141 else if (st
->active
< array
.active_disks
)
142 event
= "ActiveSpare";
144 for (i
=0; i
<array
.raid_disks
+array
.spare_disks
; i
++) {
145 mdu_disk_info_t disc
;
147 if (ioctl(fd
, GET_DISK_INFO
, &disc
)>= 0) {
148 if (event
&& event_disc
== NULL
&&
149 st
->devstate
[i
] != disc
.state
) {
150 char * dv
= map_dev(disc
.major
, disc
.minor
);
152 event_disc
= strdup(dv
);
154 st
->devstate
[i
] = disc
.state
;
158 st
->active
= array
.active_disks
;
159 st
->working
= array
.working_disks
;
160 st
->spare
= array
.spare_disks
;
161 st
->failed
= array
.failed_disks
;
162 st
->utime
= array
.utime
;
164 alert(event
, dev
, event_disc
, mailaddr
, alert_cmd
);
172 static void alert(char *event
, char *dev
, char *disc
, char *mailaddr
, char *cmd
)
178 waitpid(pid
, NULL
, 0);
183 execl(cmd
, cmd
, event
, dev
, disc
, NULL
);
187 if (mailaddr
&& strncmp(event
, "Fail", 4)==0) {
188 FILE *mp
= popen(Sendmail
, "w");
191 gethostname(hname
, sizeof(hname
));
192 signal(SIGPIPE
, SIG_IGN
);
193 fprintf(mp
, "From: " Name
" monitoring <root>\n");
194 fprintf(mp
, "To: %s\n", mailaddr
);
195 fprintf(mp
, "Subject: %s event on %s:%s\n\n", event
, dev
, hname
);
197 fprintf(mp
, "This is an automatically generated mail message from " Name
"\n");
198 fprintf(mp
, "running on %s\n\n", hname
);
200 fprintf(mp
, "A %s event had been detected on md device %s.\n\n", event
, dev
);
203 fprintf(mp
, "It could be related to sub-device %s.\n\n", disc
);
205 fprintf(mp
, "Faithfully yours, etc.\n");
210 /* FIXME log the event to syslog maybe */