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 szy...@janc.net.pl // 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; }