diff options
author | Stanley Hopcroft <stanleyhopcroft@users.sourceforge.net> | 2005-01-27 04:46:08 (GMT) |
---|---|---|
committer | Stanley Hopcroft <stanleyhopcroft@users.sourceforge.net> | 2005-01-27 04:46:08 (GMT) |
commit | fce1f09f770fc5bbc6d323865af709ff515c803c (patch) | |
tree | 1e997a0bc1ace6217cc0dab87b65de52bca8be20 /contrib/check_cpqarray.c | |
parent | ccf789e017547e1f71b5945b2e1d85ce5b9cb8e4 (diff) | |
download | monitoring-plugins-fce1f09f770fc5bbc6d323865af709ff515c803c.tar.gz |
New /contrib plugin
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1112 f882894a-f735-0410-b71e-b25c423dba1c
Diffstat (limited to 'contrib/check_cpqarray.c')
-rw-r--r-- | contrib/check_cpqarray.c | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/contrib/check_cpqarray.c b/contrib/check_cpqarray.c new file mode 100644 index 0000000..badffeb --- /dev/null +++ b/contrib/check_cpqarray.c | |||
@@ -0,0 +1,430 @@ | |||
1 | /* | ||
2 | check_cpqarray, an extension for Netsaint / Nagios to check the | ||
3 | status of a Compaq SmartArray controller from the commandline. | ||
4 | Copyright (C) 2003 Guenther Mair | ||
5 | |||
6 | based on the work and using main parts of | ||
7 | |||
8 | CpqArray Deamon, a program to monitor and remotely configure a | ||
9 | SmartArray controller. | ||
10 | Copyright (C) 1999 Hugo Trippaers | ||
11 | |||
12 | This program is free software; you can redistribute it and/or modify | ||
13 | it under the terms of the GNU General Public License as published by | ||
14 | the Free Software Foundation; either version 2 of the License, or | ||
15 | (at your option) any later version. | ||
16 | |||
17 | This program is distributed in the hope that it will be useful, | ||
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | GNU General Public License for more details. | ||
21 | |||
22 | You should have received a copy of the GNU General Public License | ||
23 | along with this program; if not, write to the Free Software | ||
24 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | */ | ||
26 | |||
27 | #include <unistd.h> | ||
28 | #include <sys/ioctl.h> | ||
29 | #include <sys/utsname.h> | ||
30 | #include <stdio.h> | ||
31 | #include <fcntl.h> | ||
32 | #include <string.h> | ||
33 | #include <errno.h> | ||
34 | |||
35 | #include "/usr/src/linux/drivers/block/ida_ioctl.h" | ||
36 | #include "/usr/src/linux/drivers/block/ida_cmd.h" | ||
37 | #include "/usr/src/linux/drivers/block/cpqarray.h" | ||
38 | |||
39 | |||
40 | const char *controllers[] = | ||
41 | { | ||
42 | "/dev/ida/c0d0", | ||
43 | "/dev/ida/c1d0", | ||
44 | "/dev/ida/c2d0", | ||
45 | "/dev/ida/c3d0", | ||
46 | "/dev/ida/c4d0", | ||
47 | "/dev/ida/c5d0", | ||
48 | "/dev/ida/c6d0", | ||
49 | "/dev/ida/c7d0" | ||
50 | }; | ||
51 | |||
52 | const char *statusstr[] = { | ||
53 | "Logical drive /dev/ida/c%dd%d: OK\n", | ||
54 | "Logical drive /dev/ida/c%dd%d: FAILED\n", | ||
55 | "Logical drive /dev/ida/c%dd%d: not configured.\n", | ||
56 | "Logical drive /dev/ida/c%dd%d: using interim recovery mode, %3.2f%% done.\n", | ||
57 | "Logical drive /dev/ida/c%dd%d: ready for recovery operation.\n", | ||
58 | "Logical drive /dev/ida/c%dd%d: is currently recovering, %3.2f%% done.\n", | ||
59 | "Wrong physical drive was replaced.\n", | ||
60 | "A physical drive is not properly connected.\n", | ||
61 | "Hardware is overheating.\n", | ||
62 | "Hardware has overheated.\n", | ||
63 | "Logical drive /dev/ida/c%dd%d: currently expanding, %3.2f%% done.\n", | ||
64 | "Logical drive /dev/ida/c%dd%d: not yet available.\n", | ||
65 | "Logical drive /dev/ida/c%dd%d: queued for expansion.\n", | ||
66 | }; | ||
67 | |||
68 | extern char *optarg; | ||
69 | extern int optind, opterr, optopt; | ||
70 | |||
71 | int ctrls_found_num; | ||
72 | int exit_code = 0; | ||
73 | struct controller ctrls_found[8]; | ||
74 | |||
75 | #define DEBUG(x) fprintf(stderr, x) | ||
76 | |||
77 | struct opts | ||
78 | { | ||
79 | char debug; | ||
80 | }; | ||
81 | |||
82 | struct slog_disk | ||
83 | { | ||
84 | int status; | ||
85 | float pvalue; | ||
86 | }; | ||
87 | |||
88 | struct controller | ||
89 | { | ||
90 | char ctrl_devicename[20]; | ||
91 | int num_logd_found; | ||
92 | struct slog_disk log_disk[16]; | ||
93 | }; | ||
94 | |||
95 | |||
96 | |||
97 | int status_check (struct opts opts) | ||
98 | { | ||
99 | int devicefd; | ||
100 | int ctrl_cntr; | ||
101 | int logd_cntr; | ||
102 | ida_ioctl_t io, io2; | ||
103 | int status, nr_blks, blks_tr; | ||
104 | float pvalue; | ||
105 | int counter; | ||
106 | |||
107 | for ( ctrl_cntr=0; | ||
108 | ctrl_cntr < ctrls_found_num; | ||
109 | ctrl_cntr++) { | ||
110 | |||
111 | devicefd = open (controllers[ctrl_cntr], O_RDONLY); | ||
112 | |||
113 | for ( logd_cntr=0; | ||
114 | logd_cntr < ctrls_found[ctrl_cntr].num_logd_found; | ||
115 | logd_cntr++) { | ||
116 | |||
117 | memset (&io, 0, sizeof (io)); | ||
118 | |||
119 | io.cmd = SENSE_LOG_DRV_STAT; | ||
120 | io.unit = logd_cntr | UNITVALID; | ||
121 | |||
122 | if (ioctl (devicefd, IDAPASSTHRU, &io) < 0) | ||
123 | { | ||
124 | perror ("SENSE_LOG_DRV_STAT ioctl"); | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | status=io.c.sense_log_drv_stat.status; | ||
129 | |||
130 | if ((status == 3) || (status == 5) || (status == 7)) { | ||
131 | /* is a progress indicator required? | ||
132 | */ | ||
133 | memset (&io2, 0, sizeof (io)); | ||
134 | |||
135 | io2.cmd = ID_LOG_DRV; | ||
136 | io2.unit = logd_cntr | UNITVALID; | ||
137 | |||
138 | if (ioctl (devicefd, IDAPASSTHRU, &io2) < 0) | ||
139 | { | ||
140 | perror ("ID_LOG_DRV ioctl"); | ||
141 | /* return 0; no return this isn't fatal for now */ | ||
142 | } | ||
143 | else | ||
144 | { | ||
145 | nr_blks = io2.c.id_log_drv.nr_blks; | ||
146 | blks_tr = io.c.sense_log_drv_stat.blks_to_recover; | ||
147 | |||
148 | pvalue = ((float)(nr_blks - blks_tr)/(float)nr_blks) * 100; | ||
149 | } | ||
150 | } | ||
151 | else { | ||
152 | pvalue = 0.0; | ||
153 | } | ||
154 | |||
155 | if (opts.debug) { | ||
156 | fprintf(stdout, "DEBUG: Status of controller %d unit %d is %d\n", | ||
157 | ctrl_cntr, logd_cntr, status); | ||
158 | fprintf(stdout, "DEBUG: "); | ||
159 | fprintf(stdout, statusstr[status], | ||
160 | ctrl_cntr, logd_cntr, pvalue); | ||
161 | fprintf(stdout, "\n"); | ||
162 | } | ||
163 | |||
164 | printf(statusstr[status], ctrl_cntr, logd_cntr, pvalue); | ||
165 | |||
166 | switch(status) | ||
167 | { | ||
168 | case 1: | ||
169 | case 2: | ||
170 | case 6: | ||
171 | case 7: | ||
172 | case 9: | ||
173 | /* CRITICAL */ | ||
174 | exit_code = 2; | ||
175 | break; | ||
176 | case 3: | ||
177 | case 4: | ||
178 | case 5: | ||
179 | case 8: | ||
180 | case 10: | ||
181 | case 11: | ||
182 | case 12: | ||
183 | /* WARNING (only if not yet at CRITICAL LEVEL) */ | ||
184 | if (exit_code < 2) exit_code = 1; | ||
185 | break; | ||
186 | case 0: | ||
187 | default: | ||
188 | /* do nothing */ | ||
189 | break; | ||
190 | } | ||
191 | |||
192 | ctrls_found[ctrl_cntr].log_disk[logd_cntr].pvalue = pvalue; | ||
193 | ctrls_found[ctrl_cntr].log_disk[logd_cntr].status = status; | ||
194 | } | ||
195 | close (devicefd); | ||
196 | } | ||
197 | |||
198 | return 1; | ||
199 | } | ||
200 | |||
201 | int discover_controllers (struct opts opts) | ||
202 | { | ||
203 | int cntr; | ||
204 | int foundone = 0; | ||
205 | |||
206 | for (cntr = 0; cntr < 8; cntr++) | ||
207 | { | ||
208 | /* does this device exist ? */ | ||
209 | if ((access (controllers[cntr], R_OK | F_OK)) == 0) | ||
210 | { | ||
211 | /* it does :) */ | ||
212 | if (interrogate_controller (opts, cntr)) | ||
213 | { | ||
214 | foundone = 1; | ||
215 | if (opts.debug) | ||
216 | fprintf (stderr, "DEBUG: %s is a existing controller\n", | ||
217 | controllers[cntr]); | ||
218 | } | ||
219 | } | ||
220 | else if (opts.debug) | ||
221 | { | ||
222 | fprintf (stderr, "DEBUG: Device %s could not be opened\n", controllers[cntr]); | ||
223 | perror ("DEBUG: reason"); | ||
224 | } | ||
225 | } | ||
226 | return foundone; | ||
227 | } | ||
228 | |||
229 | void boardid2str (unsigned long board_id, char *name) | ||
230 | { | ||
231 | switch (board_id) | ||
232 | { | ||
233 | case 0x0040110E: /* IDA */ | ||
234 | strcpy (name, "Compaq IDA"); | ||
235 | break; | ||
236 | case 0x0140110E: /* IDA-2 */ | ||
237 | strcpy (name, "Compaq IDA-2"); | ||
238 | break; | ||
239 | case 0x1040110E: /* IAES */ | ||
240 | strcpy (name, "Compaq IAES"); | ||
241 | break; | ||
242 | case 0x2040110E: /* SMART */ | ||
243 | strcpy (name, "Compaq SMART"); | ||
244 | break; | ||
245 | case 0x3040110E: /* SMART-2/E */ | ||
246 | strcpy (name, "Compaq SMART-2/E"); | ||
247 | break; | ||
248 | case 0x40300E11: /* SMART-2/P or SMART-2DH */ | ||
249 | strcpy (name, "Compaq SMART-2/P (2DH)"); | ||
250 | break; | ||
251 | case 0x40310E11: /* SMART-2SL */ | ||
252 | strcpy (name, "Compaq SMART-2SL"); | ||
253 | break; | ||
254 | case 0x40320E11: /* SMART-3200 */ | ||
255 | strcpy (name, "Compaq SMART-3200"); | ||
256 | break; | ||
257 | case 0x40330E11: /* SMART-3100ES */ | ||
258 | strcpy (name, "Compaq SMART-3100ES"); | ||
259 | break; | ||
260 | case 0x40340E11: /* SMART-221 */ | ||
261 | strcpy (name, "Compaq SMART-221"); | ||
262 | break; | ||
263 | case 0x40400E11: /* Integrated Array */ | ||
264 | strcpy (name, "Compaq Integrated Array"); | ||
265 | break; | ||
266 | case 0x40500E11: /* Smart Array 4200 */ | ||
267 | strcpy (name, "Compaq Smart Array 4200"); | ||
268 | break; | ||
269 | case 0x40510E11: /* Smart Array 4250ES */ | ||
270 | strcpy (name, "Compaq Smart Array 4250ES"); | ||
271 | break; | ||
272 | case 0x40580E11: /* Smart Array 431 */ | ||
273 | strcpy (name, "Compaq Smart Array 431"); | ||
274 | break; | ||
275 | default: | ||
276 | /* | ||
277 | * Well, its a SMART-2 or better, don't know which | ||
278 | * kind. | ||
279 | */ | ||
280 | strcpy (name, "Unknown Controller Type"); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | int interrogate_controller (struct opts opts, int contrnum) | ||
285 | { | ||
286 | int devicefd; | ||
287 | ida_ioctl_t io; | ||
288 | char buffer[30]; | ||
289 | int foundone = 0; | ||
290 | int cntr; | ||
291 | |||
292 | devicefd = open (controllers[contrnum], O_RDONLY); | ||
293 | /* no checks, did that before */ | ||
294 | |||
295 | /* clear io */ | ||
296 | memset (&io, 0, sizeof (io)); | ||
297 | |||
298 | io.cmd = ID_CTLR; | ||
299 | |||
300 | if (ioctl (devicefd, IDAPASSTHRU, &io) < 0) | ||
301 | { | ||
302 | if (opts.debug) perror ("DEBUG: ioctl"); | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | boardid2str (io.c.id_ctlr.board_id, buffer); | ||
307 | |||
308 | strncpy (ctrls_found[ctrls_found_num].ctrl_devicename, | ||
309 | buffer, 20); | ||
310 | |||
311 | ctrls_found[ctrls_found_num].num_logd_found = 0; | ||
312 | |||
313 | for (cntr = 0; cntr < io.c.id_ctlr.nr_drvs; cntr++) | ||
314 | { | ||
315 | if (interrogate_logical (opts, devicefd, cntr)) | ||
316 | { | ||
317 | /* logical drive found, this could be used later one */ | ||
318 | foundone = 1; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | switch (ctrls_found[ctrls_found_num].num_logd_found) | ||
323 | { | ||
324 | case 0: | ||
325 | printf("Found a %s with no logical drives.\n", buffer); | ||
326 | break; | ||
327 | case 1: | ||
328 | printf("Found a %s with one Logical drive.\n", buffer, | ||
329 | ctrls_found[ctrls_found_num].num_logd_found); | ||
330 | break; | ||
331 | default: | ||
332 | printf("Found a %s with %d Logical drives.\n", buffer, | ||
333 | ctrls_found[ctrls_found_num].num_logd_found); | ||
334 | break; | ||
335 | } | ||
336 | |||
337 | ctrls_found_num++; | ||
338 | |||
339 | close (devicefd); | ||
340 | return 1; | ||
341 | } | ||
342 | |||
343 | int interrogate_logical (struct opts opts, int devicefd, int unit_nr) | ||
344 | { | ||
345 | ida_ioctl_t io; | ||
346 | ida_ioctl_t io2; | ||
347 | int nr_blks, blks_tr; | ||
348 | |||
349 | if (opts.debug) printf ("DEBUG: interrogating unit %d\n", unit_nr); | ||
350 | |||
351 | memset (&io, 0, sizeof (io)); | ||
352 | |||
353 | io.cmd = ID_LOG_DRV; | ||
354 | io.unit = unit_nr | UNITVALID; | ||
355 | |||
356 | if (ioctl (devicefd, IDAPASSTHRU, &io) < 0) | ||
357 | { | ||
358 | perror ("FATAL: ID_LOG_DRV ioctl"); | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | memset (&io2, 0, sizeof (io2)); | ||
363 | |||
364 | io2.cmd = SENSE_LOG_DRV_STAT; | ||
365 | io2.unit = unit_nr | UNITVALID; | ||
366 | |||
367 | if (ioctl (devicefd, IDAPASSTHRU, &io2) < 0) | ||
368 | { | ||
369 | perror ("FATAL: SENSE_LOG_DRV_STAT ioctl"); | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | ctrls_found[ctrls_found_num].num_logd_found++; | ||
374 | /* ctrls_found[ctrls_found_num].log_disk[unit_nr].status = | ||
375 | * io2.c.sense_log_drv_stat.status; | ||
376 | |||
377 | * nr_blks = io2.c.id_log_drv.nr_blks; | ||
378 | * blks_tr = io.c.sense_log_drv_stat.blks_to_recover; | ||
379 | * ctrls_found[ctrls_found_num].log_disk[unit_nr].pvalue = | ||
380 | * ((float)(nr_blks - blks_tr)/(float)nr_blks) * 100; | ||
381 | */ | ||
382 | ctrls_found[ctrls_found_num].log_disk[unit_nr].status = 0; | ||
383 | ctrls_found[ctrls_found_num].log_disk[unit_nr].pvalue = 0; | ||
384 | |||
385 | return 1; | ||
386 | } | ||
387 | |||
388 | |||
389 | void print_usage() | ||
390 | { | ||
391 | printf("cpqarrayd [options]\n"); | ||
392 | printf(" -h prints this text\n"); | ||
393 | printf(" -d enables debugging\n"); | ||
394 | } | ||
395 | |||
396 | |||
397 | int main(int argc, char *argv[]) | ||
398 | { | ||
399 | char option; | ||
400 | struct opts opts; /* commandline options */ | ||
401 | |||
402 | memset(&opts, 0, sizeof(struct opts)); | ||
403 | |||
404 | /* check options */ | ||
405 | while ((option = getopt (argc, argv, "dh:")) != EOF) | ||
406 | { | ||
407 | switch (option) | ||
408 | { | ||
409 | case 'd': | ||
410 | opts.debug = 1; | ||
411 | break; | ||
412 | case '?': | ||
413 | case 'h': | ||
414 | default: | ||
415 | print_usage(); | ||
416 | exit(0); | ||
417 | break; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | /* Check for existance of array controllers */ | ||
422 | if (!discover_controllers(opts)) { | ||
423 | printf("No array controller found!\n\n"); | ||
424 | exit(1); | ||
425 | } | ||
426 | |||
427 | status_check(opts); | ||
428 | |||
429 | return exit_code; | ||
430 | } | ||