summaryrefslogtreecommitdiffstats
path: root/contrib/check_cpqarray.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/check_cpqarray.c')
-rw-r--r--contrib/check_cpqarray.c430
1 files changed, 430 insertions, 0 deletions
diff --git a/contrib/check_cpqarray.c b/contrib/check_cpqarray.c
new file mode 100644
index 00000000..badffeb4
--- /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
40const 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
52const 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
68extern char *optarg;
69extern int optind, opterr, optopt;
70
71int ctrls_found_num;
72int exit_code = 0;
73struct controller ctrls_found[8];
74
75#define DEBUG(x) fprintf(stderr, x)
76
77struct opts
78{
79 char debug;
80};
81
82struct slog_disk
83{
84 int status;
85 float pvalue;
86};
87
88struct controller
89{
90 char ctrl_devicename[20];
91 int num_logd_found;
92 struct slog_disk log_disk[16];
93};
94
95
96
97int 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
201int 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
229void 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
284int 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
343int 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
389void print_usage()
390{
391 printf("cpqarrayd [options]\n");
392 printf(" -h prints this text\n");
393 printf(" -d enables debugging\n");
394}
395
396
397int 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}