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
6 based on the work and using main parts of
8 CpqArray Deamon, a program to monitor and remotely configure a
10 Copyright (C) 1999 Hugo Trippaers
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.
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.
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
28 #include <sys/ioctl.h>
29 #include <sys/utsname.h>
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"
40 const char *controllers
[] =
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",
69 extern int optind
, opterr
, optopt
;
73 struct controller ctrls_found
[8];
75 #define DEBUG(x) fprintf(stderr, x)
90 char ctrl_devicename
[20];
92 struct slog_disk log_disk
[16];
97 int status_check (struct opts opts
)
103 int status
, nr_blks
, blks_tr
;
108 ctrl_cntr
< ctrls_found_num
;
111 devicefd
= open (controllers
[ctrl_cntr
], O_RDONLY
);
114 logd_cntr
< ctrls_found
[ctrl_cntr
].num_logd_found
;
117 memset (&io
, 0, sizeof (io
));
119 io
.cmd
= SENSE_LOG_DRV_STAT
;
120 io
.unit
= logd_cntr
| UNITVALID
;
122 if (ioctl (devicefd
, IDAPASSTHRU
, &io
) < 0)
124 perror ("SENSE_LOG_DRV_STAT ioctl");
128 status
=io
.c
.sense_log_drv_stat
.status
;
130 if ((status
== 3) || (status
== 5) || (status
== 7)) {
131 /* is a progress indicator required?
133 memset (&io2
, 0, sizeof (io
));
135 io2
.cmd
= ID_LOG_DRV
;
136 io2
.unit
= logd_cntr
| UNITVALID
;
138 if (ioctl (devicefd
, IDAPASSTHRU
, &io2
) < 0)
140 perror ("ID_LOG_DRV ioctl");
141 /* return 0; no return this isn't fatal for now */
145 nr_blks
= io2
.c
.id_log_drv
.nr_blks
;
146 blks_tr
= io
.c
.sense_log_drv_stat
.blks_to_recover
;
148 pvalue
= ((float)(nr_blks
- blks_tr
)/(float)nr_blks
) * 100;
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");
164 printf(statusstr
[status
], ctrl_cntr
, logd_cntr
, pvalue
);
183 /* WARNING (only if not yet at CRITICAL LEVEL) */
184 if (exit_code
< 2) exit_code
= 1;
192 ctrls_found
[ctrl_cntr
].log_disk
[logd_cntr
].pvalue
= pvalue
;
193 ctrls_found
[ctrl_cntr
].log_disk
[logd_cntr
].status
= status
;
201 int discover_controllers (struct opts opts
)
206 for (cntr
= 0; cntr
< 8; cntr
++)
208 /* does this device exist ? */
209 if ((access (controllers
[cntr
], R_OK
| F_OK
)) == 0)
212 if (interrogate_controller (opts
, cntr
))
216 fprintf (stderr
, "DEBUG: %s is a existing controller\n",
222 fprintf (stderr
, "DEBUG: Device %s could not be opened\n", controllers
[cntr
]);
223 perror ("DEBUG: reason");
229 void boardid2str (unsigned long board_id
, char *name
)
233 case 0x0040110E: /* IDA */
234 strcpy (name
, "Compaq IDA");
236 case 0x0140110E: /* IDA-2 */
237 strcpy (name
, "Compaq IDA-2");
239 case 0x1040110E: /* IAES */
240 strcpy (name
, "Compaq IAES");
242 case 0x2040110E: /* SMART */
243 strcpy (name
, "Compaq SMART");
245 case 0x3040110E: /* SMART-2/E */
246 strcpy (name
, "Compaq SMART-2/E");
248 case 0x40300E11: /* SMART-2/P or SMART-2DH */
249 strcpy (name
, "Compaq SMART-2/P (2DH)");
251 case 0x40310E11: /* SMART-2SL */
252 strcpy (name
, "Compaq SMART-2SL");
254 case 0x40320E11: /* SMART-3200 */
255 strcpy (name
, "Compaq SMART-3200");
257 case 0x40330E11: /* SMART-3100ES */
258 strcpy (name
, "Compaq SMART-3100ES");
260 case 0x40340E11: /* SMART-221 */
261 strcpy (name
, "Compaq SMART-221");
263 case 0x40400E11: /* Integrated Array */
264 strcpy (name
, "Compaq Integrated Array");
266 case 0x40500E11: /* Smart Array 4200 */
267 strcpy (name
, "Compaq Smart Array 4200");
269 case 0x40510E11: /* Smart Array 4250ES */
270 strcpy (name
, "Compaq Smart Array 4250ES");
272 case 0x40580E11: /* Smart Array 431 */
273 strcpy (name
, "Compaq Smart Array 431");
277 * Well, its a SMART-2 or better, don't know which
280 strcpy (name
, "Unknown Controller Type");
284 int interrogate_controller (struct opts opts
, int contrnum
)
292 devicefd
= open (controllers
[contrnum
], O_RDONLY
);
293 /* no checks, did that before */
296 memset (&io
, 0, sizeof (io
));
300 if (ioctl (devicefd
, IDAPASSTHRU
, &io
) < 0)
302 if (opts
.debug
) perror ("DEBUG: ioctl");
306 boardid2str (io
.c
.id_ctlr
.board_id
, buffer
);
308 strncpy (ctrls_found
[ctrls_found_num
].ctrl_devicename
,
311 ctrls_found
[ctrls_found_num
].num_logd_found
= 0;
313 for (cntr
= 0; cntr
< io
.c
.id_ctlr
.nr_drvs
; cntr
++)
315 if (interrogate_logical (opts
, devicefd
, cntr
))
317 /* logical drive found, this could be used later one */
322 switch (ctrls_found
[ctrls_found_num
].num_logd_found
)
325 printf("Found a %s with no logical drives.\n", buffer
);
328 printf("Found a %s with one Logical drive.\n", buffer
,
329 ctrls_found
[ctrls_found_num
].num_logd_found
);
332 printf("Found a %s with %d Logical drives.\n", buffer
,
333 ctrls_found
[ctrls_found_num
].num_logd_found
);
343 int interrogate_logical (struct opts opts
, int devicefd
, int unit_nr
)
347 int nr_blks
, blks_tr
;
349 if (opts
.debug
) printf ("DEBUG: interrogating unit %d\n", unit_nr
);
351 memset (&io
, 0, sizeof (io
));
354 io
.unit
= unit_nr
| UNITVALID
;
356 if (ioctl (devicefd
, IDAPASSTHRU
, &io
) < 0)
358 perror ("FATAL: ID_LOG_DRV ioctl");
362 memset (&io2
, 0, sizeof (io2
));
364 io2
.cmd
= SENSE_LOG_DRV_STAT
;
365 io2
.unit
= unit_nr
| UNITVALID
;
367 if (ioctl (devicefd
, IDAPASSTHRU
, &io2
) < 0)
369 perror ("FATAL: SENSE_LOG_DRV_STAT ioctl");
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;
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;
382 ctrls_found
[ctrls_found_num
].log_disk
[unit_nr
].status
= 0;
383 ctrls_found
[ctrls_found_num
].log_disk
[unit_nr
].pvalue
= 0;
391 printf("cpqarrayd [options]\n");
392 printf(" -h prints this text\n");
393 printf(" -d enables debugging\n");
397 int main(int argc
, char *argv
[])
400 struct opts opts
; /* commandline options */
402 memset(&opts
, 0, sizeof(struct opts
));
405 while ((option
= getopt (argc
, argv
, "dh:")) != EOF
)
421 /* Check for existance of array controllers */
422 if (!discover_controllers(opts
)) {
423 printf("No array controller found!\n\n");