Hello All,
Since upstream seams to be no longer active on this one I went ahead and did
some maintenance work on arrayprobe.
I don't use arrayprobe and looked at it because it is RC for Squeeze so please
review (it's not one-liner) and (if brave enough:) test it.
Instead of just fix reported issue with tape I refactored some code to not used
dynamic memory, I hope this fix memory issues reported already and minimize
chance of similar bugs in the future. It also fixes some other bugs identified
during reviewing/coding (overwriting memory, leaks etc) and buffer overflow
bugs
reported.
As I mentioned before, I'm not able to test it myself so there might be (I'm
pretty sure of that :>) some bugs.
I can spend some more time on it if testers show up and report issues :)
Comments are welcome.
--
Szymon K. Janc
[email protected] // GG: 1383435
--- probe.c_orig 2011-01-18 00:33:37.817369726 +0100
+++ probe.c 2011-01-18 01:06:02.517370069 +0100
@@ -43,16 +43,16 @@
#include "config.h"
typedef struct _logdrv_state {
- int state;
- char *message;
- int severity;
+ int state;
+ const char *message;
+ int severity;
} logdrv_state;
typedef struct _logdrv {
- char *devicestr; /* filesystem device node eg. /dev/cciss/c0d0 */
- int type; /* type of controller eg. CCISS or IDA */
- int drvnum; /* number of this logical drive */
- logdrv_state state; /* current state of this logical drive */
+ char *devicestr; /* filesystem device node eg. /dev/cciss/c0d0 */
+ int type; /* type of controller eg. CCISS or IDA */
+ int drvnum; /* number of this logical drive */
+ logdrv_state state; /* current state of this logical drive */
} logdrv;
/* globals */
@@ -65,53 +65,38 @@ int verbose = 0;
/* defines */
#define CTTYPE_CCISS 1
#define CTTYPE_IDA 2
+#define MAX_LOGICAL_DRIVES 64
-int
-cciss_get_event (int device_fd, int reset_pointer, cciss_event_type * event)
+void allocation_failed(void)
{
- int result;
+ printf("WARNING Arrayprobe cannot allocate enough memory. Aborting.\n");
+ exit(1);
+}
+
+int cciss_get_event(int device_fd, int reset_pointer, cciss_event_type * event)
+{
+ int result;
IOCTL_Command_struct iocommand;
- unsigned char *buffer;
+ unsigned char buffer[512] = {0};
- iocommand.LUN_info.LunAddrBytes[0] = 0;
- iocommand.LUN_info.LunAddrBytes[1] = 0;
- iocommand.LUN_info.LunAddrBytes[2] = 0;
- iocommand.LUN_info.LunAddrBytes[3] = 0;
- iocommand.LUN_info.LunAddrBytes[4] = 0;
- iocommand.LUN_info.LunAddrBytes[5] = 0;
- iocommand.LUN_info.LunAddrBytes[6] = 0;
- iocommand.LUN_info.LunAddrBytes[7] = 0;
+ memset(&iocommand, 0, sizeof(iocommand));
iocommand.Request.Type.Type = TYPE_CMD;
iocommand.Request.Type.Attribute = ATTR_SIMPLE;
iocommand.Request.Type.Direction = XFER_READ;
- iocommand.Request.Timeout = 0; /* don't time out */
-
iocommand.Request.CDBLen = 13;
iocommand.Request.CDB[0] = 0xC0; /* CISS Read */
iocommand.Request.CDB[1] = 0xD0; /* Notify on Event */
- iocommand.Request.CDB[2] = 0x0; /* reserved, leave 0 */
- iocommand.Request.CDB[3] = 0x0; /* reserved, leave 0 */
- iocommand.Request.CDB[4] = 0x0;
- iocommand.Request.CDB[5] = 0x0;
- iocommand.Request.CDB[6] = 0x0;
iocommand.Request.CDB[7] = (reset_pointer) ? 0x7 : 0x3; /* bit 2 set = reset pointer, bit 0 set = synchronous mode */
- iocommand.Request.CDB[8] = 0x0;
- iocommand.Request.CDB[9] = 0x0;
iocommand.Request.CDB[10] = 0x2;
- iocommand.Request.CDB[11] = 0x0;
- iocommand.Request.CDB[12] = 0x0;
- buffer = (unsigned char *) malloc (512);
- memset (buffer, 0x0, 512);
iocommand.buf_size = 512;
iocommand.buf = buffer;
- result = ioctl (device_fd, CCISS_PASSTHRU, &iocommand);
- if (result < 0)
- {
- perror (" * ioctl failed");
+ result = ioctl(device_fd, CCISS_PASSTHRU, &iocommand);
+ if (result < 0) {
+ perror(" * ioctl failed");
return -1;
}
@@ -119,60 +104,41 @@ cciss_get_event (int device_fd, int rese
* overrun (1) should not happen anyway and
* underrun (2) is not a problem
*/
- if ((iocommand.error_info.CommandStatus != 1) && (iocommand.error_info.CommandStatus != 2) && (iocommand.error_info.CommandStatus != 0)) {
- printf (" * Command failed with Comnmand Status %d\n", iocommand.error_info.CommandStatus);
- return -1;
+ if (iocommand.error_info.CommandStatus > 2) {
+ printf(" * Command failed with Command Status %u\n",
+ iocommand.error_info.CommandStatus);
+ return -1;
}
- memcpy (event, buffer, 512);
+ memcpy(event, buffer, 512);
return 0;
}
-int
-cciss_get_logical_luns (int device_fd, cciss_report_logicallun_struct * logluns)
+int cciss_get_logical_luns(int device_fd,
+ cciss_report_logicallun_struct * logluns)
{
- int result;
IOCTL_Command_struct iocommand;
- unsigned char *buffer;
+ unsigned char buffer[128] = {0};
- iocommand.LUN_info.LunAddrBytes[0] = 0;
- iocommand.LUN_info.LunAddrBytes[1] = 0;
- iocommand.LUN_info.LunAddrBytes[2] = 0;
- iocommand.LUN_info.LunAddrBytes[3] = 0;
- iocommand.LUN_info.LunAddrBytes[4] = 0;
- iocommand.LUN_info.LunAddrBytes[5] = 0;
- iocommand.LUN_info.LunAddrBytes[6] = 0;
- iocommand.LUN_info.LunAddrBytes[7] = 0;
+ memset(&iocommand, 0, sizeof(iocommand));
iocommand.Request.Type.Type = TYPE_CMD;
iocommand.Request.Type.Attribute = ATTR_SIMPLE;
iocommand.Request.Type.Direction = XFER_READ;
- iocommand.Request.Timeout = 0; /* don't time out */
-
iocommand.Request.CDBLen = 12;
- iocommand.Request.CDB[0] = 0xC2; /* Report logical LUNs */
- iocommand.Request.CDB[1] = 0x0; /* reserved, leave 0 */
- iocommand.Request.CDB[2] = 0x0; /* reserved, leave 0 */
- iocommand.Request.CDB[3] = 0x0; /* reserved, leave 0 */
- iocommand.Request.CDB[4] = 0x0; /* reserved, leave 0 */
- iocommand.Request.CDB[5] = 0x0; /* reserved, leave 0 */
- iocommand.Request.CDB[6] = 0x0; /* byte 6-9 alloc length = 128 (0x80)*/
+ iocommand.Request.CDB[0] = 0xC2; /* Report logical LUNs */
+
+ iocommand.Request.CDB[6] = 0x0; /* byte 6-9 alloc length = 128 (0x80) */
iocommand.Request.CDB[7] = 0x0;
iocommand.Request.CDB[8] = 0x0;
iocommand.Request.CDB[9] = 0x80;
- iocommand.Request.CDB[10] = 0x0; /* reserved, leave 0 */
- iocommand.Request.CDB[11] = 0x0; /* control ? */
- buffer = (unsigned char *) malloc (128);
- memset (buffer, 0x0, 128);
iocommand.buf_size = 128;
iocommand.buf = buffer;
- result = ioctl (device_fd, CCISS_PASSTHRU, &iocommand);
- if (result < 0)
- {
- perror (" * ioctl failed");
+ if (ioctl(device_fd, CCISS_PASSTHRU, &iocommand) < 0) {
+ perror(" * ioctl failed");
return -1;
}
@@ -180,64 +146,56 @@ cciss_get_logical_luns (int device_fd, c
* overrun (1) should not happen anyway and
* underrun (2) is not a problem
*/
- if ((iocommand.error_info.CommandStatus != 1) && (iocommand.error_info.CommandStatus != 2) && (iocommand.error_info.CommandStatus != 0)) {
- printf (" * Command failed with Comnmand Status %d\n", iocommand.error_info.CommandStatus);
- return -1;
+ if (iocommand.error_info.CommandStatus > 2) {
+ printf(" * Command failed with Command Status %d\n",
+ iocommand.error_info.CommandStatus);
+ return -1;
}
-
- memcpy (logluns, buffer, 128);
+
+ memcpy(logluns, buffer, 128);
return 0;
}
-int
-cciss_simulate_get_event (int device_fd, int reset_pointer,
- cciss_event_type * event)
+int cciss_simulate_get_event(int device_fd, int reset_pointer,
+ cciss_event_type * event)
{
- unsigned char *buffer;
+ unsigned char buffer[512];
- buffer = (unsigned char *) malloc (512);
- if ((read (device_fd, buffer, 512)) < 0)
- {
- perror ("reading from file");
+ if ((read(device_fd, buffer, 512)) < 0) {
+ perror("reading from file");
return -1;
}
- memcpy (event, buffer, 512);
+ memcpy(event, buffer, 512);
return 0;
}
-void
-cciss_print_event (cciss_event_type event)
+void cciss_print_event(cciss_event_type event)
{
int prevstate, newstate;
-
- printf ("Event code %d/%d/%d",
- event.class.class, event.class.subclass, event.class.detail);
- if (event.tag == 0)
- {
- printf ("\n");
- }
- else
- {
- printf (" with tag %d\n", event.tag);
- }
-
- if (event.time.month != 0)
- {
- printf ("at %d-%d-%d %02d:%02d:%02d\n",
- event.time.day,
- event.time.month,
+
+ printf("Event code %u/%u/%u", event.class.class, event.class.subclass,
+ event.class.detail);
+
+ if (event.tag != 0)
+ printf(" with tag %u", event.tag);
+
+ printf("\n");
+
+ if (event.time.month != 0) {
+ printf("at %u-%u-%u %02u:%02u:%02u\n",
+ event.time.day,
+ event.time.month,
event.time.year,
event.time.seconds / 3600,
event.time.seconds % 3600 / 60,
event.time.seconds % 60);
- }
- else if (event.timestamp != 0)
- {
- printf ("at %d seconds since last power cycle or controler reset\n", event.timestamp);
+ } else if (event.timestamp != 0) {
+ printf("at %u seconds since last power cycle or controller reset\n",
+ event.timestamp);
}
- printf ("with message: %s\n", event.mesgstring);
-
+ printf("with message: %s\n", event.mesgstring);
+
/* printf ("on device %02X %02X %02X %02X %02X %02X %02X %02X\n",
* event.deviceaddr.LunAddrBytes[0],
* event.deviceaddr.LunAddrBytes[1],
@@ -248,57 +206,50 @@ cciss_print_event (cciss_event_type even
* event.deviceaddr.LunAddrBytes[6],
* event.deviceaddr.LunAddrBytes[7]);
*/
-
- if (CompareEvent(event, 5,0,0)) {
+ if (CompareEvent(event, 5, 0, 0)) {
prevstate = event.detail.logstatchange.previouslogicaldrivestate;
newstate = event.detail.logstatchange.newlogicaldrivestate;
- printf ("logical drive %d, changed from state %d to %d\n",
- event.detail.logstatchange.logicaldrivenumber,
- prevstate,
- newstate);
- printf ("state %d: %s\n",
- prevstate,
- logicaldrivestatusstr[prevstate]);
- printf ("state %d: %s\n",
- newstate,
- logicaldrivestatusstr[newstate]);
- }
- else if (CompareEvent(event, 4,0,0)) {
- printf ("physical drive %d has failed with failurecode %d.\n",
+
+ printf("logical drive %u, changed from state %d to %d\n",
+ event.detail.logstatchange.logicaldrivenumber,
+ prevstate, newstate);
+ printf("state %u: %s\n", prevstate, logicaldrivestatusstr[prevstate]);
+ printf("state %u: %s\n", newstate, logicaldrivestatusstr[newstate]);
+ } else if (CompareEvent(event, 4, 0, 0)) {
+ printf("physical drive %u has failed with failure code %u.\n",
event.detail.phystatchange.physicaldrivenumber,
event.detail.phystatchange.failurereason);
- if (event.detail.phystatchange.configureddriveflag != 0) {
+
+ if (event.detail.phystatchange.configureddriveflag != 0)
printf("this drive is part of a logical drive\n");
- }
- if (event.detail.phystatchange.sparedriveflag != 0) {
+
+ if (event.detail.phystatchange.sparedriveflag != 0)
printf ("this drive is a hot-spare for a logical drive\n");
- }
-
}
+
+ printf("\n");
}
-int
-cciss_get_num_logicalluns(cciss_report_logicallun_struct logluns) {
- int listlength = 0;
+int cciss_get_num_logicalluns(cciss_report_logicallun_struct logluns)
+{
+ int listlength = 0;
- listlength |= (0xff & (unsigned int)(logluns.LUNlist_len[0])) << 24;
- listlength |= (0xff & (unsigned int)(logluns.LUNlist_len[1])) << 16;
- listlength |= (0xff & (unsigned int)(logluns.LUNlist_len[2])) << 8;
- listlength |= (0xff & (unsigned int)(logluns.LUNlist_len[3]));
- return listlength / 8;
-}
+ listlength |= (0xff & (unsigned int)(logluns.LUNlist_len[0])) << 24;
+ listlength |= (0xff & (unsigned int)(logluns.LUNlist_len[1])) << 16;
+ listlength |= (0xff & (unsigned int)(logluns.LUNlist_len[2])) << 8;
+ listlength |= (0xff & (unsigned int)(logluns.LUNlist_len[3]));
-void
-cciss_print_logicalluns(cciss_report_logicallun_struct logluns) {
- printf ("Number of logical volumes (%02X %02X %02X %02X) : %d\n",
- logluns.LUNlist_len[0],
- logluns.LUNlist_len[1],
- logluns.LUNlist_len[2],
- logluns.LUNlist_len[3],
- cciss_get_num_logicalluns(logluns));
-}
+ listlength /= 8;
+ if (listlength > MAX_LOGICAL_DRIVES){
+ printf("maximum number of ida logical cciss exceeded. Limiting to %u (from %u)\n",
+ MAX_LOGICAL_DRIVES, listlength);
+ listlength = MAX_LOGICAL_DRIVES;
+ }
+
+ return listlength;
+}
/* get the drivestates for logical drives attached to this controller
* result:
@@ -306,291 +257,286 @@ cciss_print_logicalluns(cciss_report_log
* 0 no logical drives detected
* <0 error while trying to get states, see log message
*/
-int
-cciss_get_drivestates (char *device, logdrv *logdrvs, int maxlogdrvs)
+int cciss_get_drivestates(char *device, logdrv * logdrvs)
{
- int fd;
- cciss_report_logicallun_struct logluns;
- int num_logical_drives;
- int counter;
- int result;
- cciss_event_type event;
- int first_time;
-
- fd = open(device, O_RDWR);
- if (fd < 0) {
- log ("failed to open device %s: %s\n", device, strerror(errno));
- return -1;
- }
-
- log ("Retrieving logical drive information from controller %s\n", device);
- if (cciss_get_logical_luns(fd, &logluns) < 0) {
- log ("Retrieval of cciss logical lun data failed (%d)\n", result);
- return -1;
- }
-
- if (verbose) {
- cciss_print_logicalluns(logluns);
- }
- num_logical_drives = cciss_get_num_logicalluns(logluns);
-
- log ("Controller %s reports %d logical drives\n", device, num_logical_drives);
-
- for (counter = 0; counter < num_logical_drives; counter++) {
- logdrvs[counter].devicestr = (char *)malloc(strlen(device)+1);
- strcpy(logdrvs[counter].devicestr, device);
- logdrvs[counter].type = CTTYPE_CCISS;
- logdrvs[counter].drvnum = counter;
- logdrvs[counter].state.state = 0;
- log ("Logical drive %d found on controller %s\n", counter, device);
- }
-
- first_time = 1;
- do
- {
- result = cciss_get_event (fd, first_time, &event);
- if (CompareEvent(event, 5,0,0)) {
- /* i'm only interested in logical drive state for now */
- int drivenum = event.detail.logstatchange.logicaldrivenumber;
- logdrvs[drivenum].state.state = event.detail.logstatchange.newlogicaldrivestate;
- logdrvs[drivenum].state.severity = logicaldrivestatusseverity[event.detail.logstatchange.newlogicaldrivestate];
- logdrvs[drivenum].state.message = (char *)malloc(strlen(logicaldrivestatusstr[event.detail.logstatchange.newlogicaldrivestate] + 1));
- strcpy (logdrvs[drivenum].state.message, logicaldrivestatusstr[event.detail.logstatchange.newlogicaldrivestate]);
- }
- if (verbose) {
- cciss_print_event (event);
- printf ("\n");
- }
- first_time = 0;
- }
- while (event.class.class != 0);
-
- return num_logical_drives;
-}
-
-int
-ida_get_num_logicalluns (int devicefd)
-{
- ida_ioctl_t io;
- char buffer[30];
- int cntr;
-
-
- /* clear io */
- memset (&io, 0, sizeof (io));
-
- io.cmd = ID_CTLR;
-
- if (ioctl (devicefd, IDAPASSTHRU, &io) < 0)
- {
- log ("Error in ida ioctl: %s\n", strerror(errno));
- return -1;
- }
-
- //boardid2str (io.c.id_ctlr.board_id, buffer);
-
- return io.c.id_ctlr.nr_drvs;
-}
-
-int
-ida_get_drivestate(int devicefd, int logicaldrv)
-{
- ida_ioctl_t io;
- ida_ioctl_t io2;
- int nr_blks, blks_tr;
-
- memset (&io, 0, sizeof (io));
-
- io.cmd = ID_LOG_DRV;
- io.unit = logicaldrv | UNITVALID;
-
- if (ioctl (devicefd, IDAPASSTHRU, &io) < 0)
- {
- log ("FATAL: ID_LOG_DRV ioctl failed: %s", strerror(errno));
- return -1;
- }
-
- memset (&io2, 0, sizeof (io2));
-
- io2.cmd = SENSE_LOG_DRV_STAT;
- io2.unit = logicaldrv | UNITVALID;
-
- if (ioctl (devicefd, IDAPASSTHRU, &io2) < 0)
- {
- log ("FATAL: SENSE_LOG_DRV_STAT ioctl failed: %s", strerror(errno));
- return -1;
- }
-
- return io2.c.sense_log_drv_stat.status;
-}
-
-int
-ida_get_drivestates (char *device, logdrv *logdrvs, int maxlogdrvs)
-{
- int fd;
- int num_logical_drives;
- int counter;
- int result;
-
- fd = open(device, O_RDWR);
- if (fd < 0) {
- log ("failed to open device %s: %s\n", device, strerror(errno));
- return -1;
- }
-
- num_logical_drives = ida_get_num_logicalluns(fd);
- if (num_logical_drives < 0) {
- log ("ioctl failed to retrieve number of logical drives\n", NULL);
- return -1;
- }
-
- for (counter = 0; counter < num_logical_drives; counter++) {
- result = ida_get_drivestate (fd, counter);
- if (result < 0) {
- log ("Error while retrieving state information (%d)\n", result);
- result = 0; /* we should set this to a critical state */
- }
- logdrvs[counter].devicestr = (char *)malloc(strlen(device)+1);
- strcpy(logdrvs[counter].devicestr, device);
- logdrvs[counter].type = CTTYPE_IDA;
- logdrvs[counter].drvnum = counter;
- logdrvs[counter].state.state = result;
- logdrvs[counter].state.severity = logicaldrivestatusseverity[result];
- logdrvs[counter].state.message = (char *)malloc(strlen(logicaldrivestatusstr[result] + 1));
- strcpy(logdrvs[counter].state.message, logicaldrivestatusstr[result]);
- log ("Logical drive %d found on controller %s\n", counter, device);
- }
+ int fd;
+ cciss_report_logicallun_struct logluns;
+ int num_logical_drives;
+ int counter;
+ int result;
+ cciss_event_type event;
+ int first_time;
+
+ fd = open(device, O_RDWR);
+ if (fd < 0) {
+ log("failed to open device %s: %s\n", device, strerror(errno));
+ return -1;
+ }
+
+ log("Retrieving logical drive information from controller %s\n", device);
+
+ if (cciss_get_logical_luns(fd, &logluns) < 0) {
+ log("Retrieval of cciss logical lun data failed (%s)\n", device);
+ close(fd);
+ return -1;
+ }
+
+ num_logical_drives = cciss_get_num_logicalluns(logluns);
+
+ log("Number of logical volumes (%02X %02X %02X %02X) : %d\n",
+ logluns.LUNlist_len[0], logluns.LUNlist_len[1],
+ logluns.LUNlist_len[2], logluns.LUNlist_len[3],
+ num_logical_drives);
- return num_logical_drives;
-}
+ log("Controller %s reports %d logical drives\n", device, num_logical_drives);
+
+ for (counter = 0; counter < num_logical_drives; counter++) {
+ logdrvs[counter].devicestr = malloc(strlen(device) + 1);
+ if (! logdrvs[counter].devicestr)
+ allocation_failed();
+
+ strcpy(logdrvs[counter].devicestr, device);
+
+ logdrvs[counter].type = CTTYPE_CCISS;
+ logdrvs[counter].drvnum = counter;
+ logdrvs[counter].state.state = 0;
+
+ log("Logical drive %d found on controller %s\n", counter, device);
+ }
+
+ first_time = 1;
+ do {
+ if (cciss_get_event(fd, first_time, &event) < 0) {
+ log("Retrieval of cciss event failed (%s)\n", device);
+ close(fd);
+ return -1;
+ }
+
+ if (CompareEvent(event, 5, 0, 0)) {
+ /* i'm only interested in logical drive state for now */
+ int drivenum = event.detail.logstatchange.logicaldrivenumber;
+ logdrvs[drivenum].state.state = event.detail.logstatchange.newlogicaldrivestate;
+ logdrvs[drivenum].state.severity = logicaldrivestatusseverity[event.detail.logstatchange.newlogicaldrivestate];
+ logdrvs[drivenum].state.message = logicaldrivestatusstr[event.detail. logstatchange.newlogicaldrivestate];
+ }
+ if (verbose)
+ cciss_print_event(event);
+
+ first_time = 0;
+ }
+ while (event.class.class != 0);
+
+ close(fd);
+ return num_logical_drives;
+}
-int
-main (int argc, char *argv[])
+int ida_get_num_logicalluns(int devicefd)
{
- cciss_event_type event;
- logdrv_state *states;
- int fd, option;
- int simulate = 0;
+ ida_ioctl_t io;
+
+ /* clear io */
+ memset(&io, 0, sizeof(io));
+
+ io.cmd = ID_CTLR;
+
+ if (ioctl(devicefd, IDAPASSTHRU, &io) < 0) {
+ log("Error in ida ioctl: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (io.c.id_ctlr.nr_drvs > MAX_LOGICAL_DRIVES) {
+ printf("maximum number of ida logical luns exceeded. Limiting to %u (from %u)\n",
+ MAX_LOGICAL_DRIVES, io.c.id_ctlr.nr_drvs);
+ return MAX_LOGICAL_DRIVES;
+ } else
+ return io.c.id_ctlr.nr_drvs;
+}
+
+int ida_get_drivestate(int devicefd, int logicaldrv)
+{
+ ida_ioctl_t io;
+
+ memset(&io, 0, sizeof(io));
+
+ io.cmd = ID_LOG_DRV;
+ io.unit = logicaldrv | UNITVALID;
+
+ if (ioctl(devicefd, IDAPASSTHRU, &io) < 0) {
+ log("FATAL: ID_LOG_DRV ioctl failed: %s", strerror(errno));
+ return -1;
+ }
+
+ memset(&io, 0, sizeof(io));
+
+ io.cmd = SENSE_LOG_DRV_STAT;
+ io.unit = logicaldrv | UNITVALID;
+
+ if (ioctl(devicefd, IDAPASSTHRU, &io) < 0) {
+ log("FATAL: SENSE_LOG_DRV_STAT ioctl failed: %s", strerror(errno));
+ return -1;
+ }
+
+ return io.c.sense_log_drv_stat.status;
+}
+
+int ida_get_drivestates(char *device, logdrv * logdrvs, int cur_logical)
+{
+ int fd;
+ int num_logical_drives;
+ int counter;
+ int result;
+
+ fd = open(device, O_RDWR);
+ if (fd < 0) {
+ log("failed to open device %s: %s\n", device, strerror(errno));
+ return -1;
+ }
+
+ num_logical_drives = ida_get_num_logicalluns(fd);
+ if (num_logical_drives < 0) {
+ log("ioctl failed to retrieve number of logical drives (%s)\n", device);
+ close(fd);
+ return -1;
+ }
+
+ for (counter = cur_logical; counter < num_logical_drives; counter++) {
+ result = ida_get_drivestate(fd, counter);
+ if (result < 0) {
+ log("Error while retrieving state information (%d)\n", result);
+ result = 0; /* TODO we should set this to a critical state */
+ }
+
+ logdrvs[counter].devicestr = malloc(strlen(device) + 1);
+ if (! logdrvs[counter].devicestr)
+ allocation_failed();
+
+ strcpy(logdrvs[counter].devicestr, device);
+ logdrvs[counter].type = CTTYPE_IDA;
+ logdrvs[counter].drvnum = counter;
+ logdrvs[counter].state.state = result;
+ logdrvs[counter].state.severity = logicaldrivestatusseverity[result];
+ logdrvs[counter].state.message = logicaldrivestatusstr[result];
+
+ log("Logical drive %d found on controller %s\n", counter, device);
+ }
+
+ return num_logical_drives;
+}
+
+int main(int argc, char *argv[])
+{
+ int option;
char *filename = NULL;
int report_mode = 0;
int num_logical_drives = 0;
int reset_event_pointer = 1;
int result;
- int ida_device = 0; /* only for use with -f , used to determine protocol to use */
- int max_logical = 64; /* hardcoded */
- int cur_logical = 0; /* number of drives detected */
- logdrv *logdrvs = (logdrv *)malloc(sizeof(logdrv)*max_logical);
- int worst_disk;
- int worst_sev = SEV_NORMAL;
+ int ida_device = 0; /* only for use with -f , used to determine protocol to use */
+ int cur_logical = 0; /* number of drives detected */
+ logdrv logdrvs[MAX_LOGICAL_DRIVES] = {{0}};
+ int worst_disk = 0;
+ int worst_sev = SEV_NORMAL;
int cntr;
- while ((option = getopt (argc, argv, "f:srhoi")) != EOF)
- {
- switch (option)
- {
+ while ((option = getopt(argc, argv, "f:srhoi")) != EOF) {
+ switch (option) {
case 'f':
- filename = (char *) malloc (strlen (optarg) + 1);
- strncpy (filename, optarg, strlen (optarg) + 1);
- break;
- case 's':
- simulate = 1;
+ filename = malloc(strlen(optarg) + 1);
+ if (! filename)
+ allocation_failed();
+
+ strncpy(filename, optarg, strlen(optarg) + 1);
break;
case 'r':
report_mode = 1;
verbose = 1;
break;
case 'o':
- reset_event_pointer = 0;
- break;
+ reset_event_pointer = 0;
+ break;
case 'i':
- ida_device = 1;
- break;
+ ida_device = 1;
+ break;
case 'h':
default:
- printf ("Usage: ccissprobe [-f filename] [-s]\n");
- printf (" -f <device> : device to open\n");
- /* printf (" -s : simultion mode (use with -f)\n"); */
- printf (" -r : report (verbose) mode\n");
- printf (" -o : only read new events (since last run, CCISS devices only)\n");
- printf (" -i : force ida ioctls. (use with -f if the device is supported by the ida driver)\n");
- exit (1);
+ printf("Usage: ccissprobe [-f filename] [-s]\n");
+ printf(" -f <device> : device to open\n");
+ printf(" -r : report (verbose) mode\n");
+ printf(" -o : only read new events (since last run, CCISS devices only)\n");
+ printf(" -i : force ida ioctls. (use with -f if the device is supported by the ida driver)\n");
+ exit(1);
}
}
- /* prepare structures */
- logdrvs = (logdrv *)malloc(sizeof(logdrv)*max_logical);
-
/* If a device is supplied on the commandline use that device,
* otherwise scan for devices in all known places
*/
- if (filename != NULL)
- {
- if (ida_device) {
- result = ida_get_drivestates(filename, logdrvs, max_logical);
- if (result > 0) {
- cur_logical += result;
- }
- }
- else {
- result = cciss_get_drivestates(filename, logdrvs, max_logical);
- if (result > 0) {
- cur_logical += result;
- }
- }
- }
- else {
- /* if nothing is supplied on the commandline check the first cciss controller and the first ida controller */
- result = cciss_get_drivestates("/dev/cciss/c0d0", logdrvs, max_logical);
- if (result > 0) {
- cur_logical += result;
- }
- result = ida_get_drivestates("/dev/ida/c0d0", logdrvs, max_logical);
- if (result > 0) {
- cur_logical += result;
- }
+ if (filename != NULL) {
+ if (ida_device)
+ result = ida_get_drivestates(filename, logdrvs, 0);
+ else
+ result = cciss_get_drivestates(filename, logdrvs);
+
+ if (result > 0)
+ cur_logical = result;
+ } else {
+ /* if nothing is supplied on the commandline check the first cciss controller and the first ida controller */
+ result = cciss_get_drivestates("/dev/cciss/c0d0", logdrvs);
+ if (result > 0)
+ cur_logical = result;
+
+ result = ida_get_drivestates("/dev/ida/c0d0", logdrvs, cur_logical);
+ if (result > 0)
+ cur_logical += result;
}
if (cur_logical == 0) {
- /* no logical drives found, this is bad */
- printf ("CRITICAL no logical drives detected\n");
- return (2);
+ /* no logical drives found, this is bad */
+ printf("CRITICAL no logical drives detected\n");
+ return (2);
}
+ if ( cur_logical > MAX_LOGICAL_DRIVES) {
+ log("maximum number of logical cciss exceeded. Limiting to %u (from %u)\n",
+ MAX_LOGICAL_DRIVES, cur_logical);
+ cur_logical = MAX_LOGICAL_DRIVES;
+ }
+
+
+
/* Nagios part
* nagios wants only one line with a status, so we print the worst situation we can find
* and exit with a corresponding return code
- */
+ */
num_logical_drives = 0;
- for (cntr = 0; cntr<cur_logical; cntr++) {
- if (logdrvs[cntr].state.state != 0) {
- if (logdrvs[cntr].state.severity > worst_sev) {
- worst_sev = logdrvs[cntr].state.severity;
- worst_disk = cntr;
- }
- }
- if (verbose) {
- printf ("Logical drive %d on controller %s has state %d\n",
- logdrvs[cntr].drvnum,
- logdrvs[cntr].devicestr,
- logdrvs[cntr].state.state);
- }
+ for (cntr = 0; cntr < cur_logical; cntr++) {
+ if (logdrvs[cntr].state.state != 0) {
+ if (logdrvs[cntr].state.severity > worst_sev) {
+ worst_sev = logdrvs[cntr].state.severity;
+ worst_disk = cntr;
+ }
+ }
+
+ log("Logical drive %d on controller %s has state %d\n",
+ logdrvs[cntr].drvnum,
+ logdrvs[cntr].devicestr,
+ logdrvs[cntr].state.state);
}
if (worst_sev == SEV_CRITICAL) {
- printf ("CRITICAL Arrayprobe Logical drive %d on %s: %s\n",
- logdrvs[worst_disk].drvnum,
- logdrvs[worst_disk].devicestr,
- logdrvs[worst_disk].state.message);
- return 2;
- }
- else if (worst_sev == SEV_WARNING) {
- printf ("WARNING Arrayprobe Logical drive %d on %s: %s\n",
- logdrvs[worst_disk].drvnum,
- logdrvs[worst_disk].devicestr,
- logdrvs[worst_disk].state.message);
- return 1;
+ printf("CRITICAL Arrayprobe Logical drive %d on %s: %s\n",
+ logdrvs[worst_disk].drvnum,
+ logdrvs[worst_disk].devicestr,
+ logdrvs[worst_disk].state.message);
+ return 2;
+ } else if (worst_sev == SEV_WARNING) {
+ printf("WARNING Arrayprobe Logical drive %d on %s: %s\n",
+ logdrvs[worst_disk].drvnum,
+ logdrvs[worst_disk].devicestr,
+ logdrvs[worst_disk].state.message);
+ return 1;
}
- printf ("OK Arrayprobe All controllers ok\n");
+ printf("OK Arrayprobe All controllers ok\n");
return 0;
}