/* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include #include #include #include #include #include #include #include extern int verbose; void print_sensor_get_usage(); void print_sensor_thresh_usage(); // Macro's for Reading the current sensor Data. #define SCANNING_DISABLED 0x40 #define READING_UNAVAILABLE 0x20 #define INVALID_THRESHOLD "Invalid Threshold data values. Cannot Set Threshold Data." // static int ipmi_sensor_get_sensor_reading_factors( struct ipmi_intf * intf, struct sdr_record_full_sensor * sensor, uint8_t reading) { struct ipmi_rq req; struct ipmi_rs * rsp; uint8_t req_data[2]; char id[17]; if (intf == NULL || sensor == NULL) return -1; memset(id, 0, sizeof(id)); memcpy(id, sensor->id_string, 16); req_data[0] = sensor->cmn.keys.sensor_num; req_data[1] = reading; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.lun = sensor->cmn.keys.lun; req.msg.cmd = GET_SENSOR_FACTORS; req.msg.data = req_data; req.msg.data_len = sizeof(req_data); rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { lprintf(LOG_ERR, "Error updating reading factor for sensor %s (#%02x)", id, sensor->cmn.keys.sensor_num); return -1; } else if (rsp->ccode) { return -1; } else { /* Update SDR copy with updated Reading Factors for this reading */ /* Note: * The Format of the returned data is exactly as in the SDR definition (Little Endian Format), * therefore we can use raw copy operation here. * Note: rsp->data[0] would point to the next valid entry in the sampling table */ // BUGBUG: uses 'hardcoded' length information from SDR Definition memcpy(&sensor->mtol, &rsp->data[1], sizeof(sensor->mtol)); memcpy(&sensor->bacc, &rsp->data[3], sizeof(sensor->bacc)); return 0; } } static struct ipmi_rs * ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf, uint8_t sensor, uint8_t threshold, uint8_t setting, uint8_t target, uint8_t lun, uint8_t channel) { struct ipmi_rq req; static struct sensor_set_thresh_rq set_thresh_rq; struct ipmi_rs *rsp; uint8_t bridged_request = 0; uint32_t save_addr; uint32_t save_channel; memset(&set_thresh_rq, 0, sizeof (set_thresh_rq)); set_thresh_rq.sensor_num = sensor; set_thresh_rq.set_mask = threshold; if (threshold == UPPER_NON_RECOV_SPECIFIED) set_thresh_rq.upper_non_recov = setting; else if (threshold == UPPER_CRIT_SPECIFIED) set_thresh_rq.upper_crit = setting; else if (threshold == UPPER_NON_CRIT_SPECIFIED) set_thresh_rq.upper_non_crit = setting; else if (threshold == LOWER_NON_CRIT_SPECIFIED) set_thresh_rq.lower_non_crit = setting; else if (threshold == LOWER_CRIT_SPECIFIED) set_thresh_rq.lower_crit = setting; else if (threshold == LOWER_NON_RECOV_SPECIFIED) set_thresh_rq.lower_non_recov = setting; else return NULL; if (BRIDGE_TO_SENSOR(intf, target, channel)) { bridged_request = 1; save_addr = intf->target_addr; intf->target_addr = target; save_channel = intf->target_channel; intf->target_channel = channel; } memset(&req, 0, sizeof (req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.lun = lun; req.msg.cmd = SET_SENSOR_THRESHOLDS; req.msg.data = (uint8_t *) & set_thresh_rq; req.msg.data_len = sizeof (set_thresh_rq); rsp = intf->sendrecv(intf, &req); if (bridged_request) { intf->target_addr = save_addr; intf->target_channel = save_channel; } return rsp; } static int ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf, struct sdr_record_common_sensor *sensor, uint8_t sdr_record_type) { struct sensor_reading *sr; sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3); if (sr == NULL) { return -1; } if (csv_output) { /* NOT IMPLEMENTED */ } else { if (verbose == 0) { /* output format * id value units status thresholds.... */ printf("%-16s ", sr->s_id); if (sr->s_reading_valid) { if (sr->s_has_analog_value) { /* don't show discrete component */ printf("| %-10s | %-10s | %-6s", sr->s_a_str, sr->s_a_units, "ok"); } else { printf("| 0x%-8x | %-10s | 0x%02x%02x", sr->s_reading, "discrete", sr->s_data2, sr->s_data3); } } else { printf("| %-10s | %-10s | %-6s", "na", "discrete", "na"); } printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", "na", "na", "na", "na", "na", "na"); printf("\n"); } else { printf("Sensor ID : %s (0x%x)\n", sr->s_id, sensor->keys.sensor_num); printf(" Entity ID : %d.%d\n", sensor->entity.id, sensor->entity.instance); printf(" Sensor Type (Discrete): %s\n", ipmi_sdr_get_sensor_type_desc(sensor->sensor. type)); if( sr->s_reading_valid ) { if (sr->s_has_analog_value) { printf(" Sensor Reading : %s %s\n", sr->s_a_str, sr->s_a_units); } ipmi_sdr_print_discrete_state("States Asserted", sensor->sensor.type, sensor->event_type, sr->s_data2, sr->s_data3); printf("\n"); } else { printf(" Unable to read sensor: Device Not Present\n\n"); } } } return (sr->s_reading_valid ? 0 : -1 ); } static void print_thresh_setting(struct sdr_record_full_sensor *full, uint8_t thresh_is_avail, uint8_t setting, const char *field_sep, const char *analog_fmt, const char *discrete_fmt, const char *na_fmt) { printf("%s", field_sep); if (!thresh_is_avail) { printf(na_fmt, "na"); return; } if (full && !UNITS_ARE_DISCRETE(&full->cmn)) { printf(analog_fmt, sdr_convert_sensor_reading (full, setting)); } else { printf(discrete_fmt, setting); } } static int ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf, struct sdr_record_common_sensor *sensor, uint8_t sdr_record_type) { int thresh_available = 1; struct ipmi_rs *rsp; struct sensor_reading *sr; sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3); if (sr == NULL) { return -1; } const char *thresh_status = ipmi_sdr_get_thresh_status(sr, "ns"); /* * Get sensor thresholds */ rsp = ipmi_sdr_get_sensor_thresholds(intf, sensor->keys.sensor_num, sensor->keys.owner_id, sensor->keys.lun, sensor->keys.channel); if ((rsp == NULL) || (rsp->ccode > 0) || (rsp->data_len == 0)) thresh_available = 0; if (csv_output) { /* NOT IMPLEMENTED */ } else { if (verbose == 0) { /* output format * id value units status thresholds.... */ printf("%-16s ", sr->s_id); if (sr->s_reading_valid) { if (sr->s_has_analog_value) printf("| %-10.3f | %-10s | %-6s", sr->s_a_val, sr->s_a_units, thresh_status); else printf("| 0x%-8x | %-10s | %-6s", sr->s_reading, sr->s_a_units, thresh_status); } else { printf("| %-10s | %-10s | %-6s", "na", sr->s_a_units, "na"); } if (thresh_available && sr->full) { #define PTS(bit, dataidx) { \ print_thresh_setting(sr->full, rsp->data[0] & (bit), \ rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s"); \ } PTS(LOWER_NON_RECOV_SPECIFIED, 3); PTS(LOWER_CRIT_SPECIFIED, 2); PTS(LOWER_NON_CRIT_SPECIFIED, 1); PTS(UPPER_NON_CRIT_SPECIFIED, 4); PTS(UPPER_CRIT_SPECIFIED, 5); PTS(UPPER_NON_RECOV_SPECIFIED, 6); #undef PTS } else { printf ("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", "na", "na", "na", "na", "na", "na"); } printf("\n"); } else { printf("Sensor ID : %s (0x%x)\n", sr->s_id, sensor->keys.sensor_num); printf(" Entity ID : %d.%d\n", sensor->entity.id, sensor->entity.instance); printf(" Sensor Type (Threshold) : %s\n", ipmi_sdr_get_sensor_type_desc(sensor->sensor. type)); printf(" Sensor Reading : "); if (sr->s_reading_valid) { if (sr->full) { uint16_t raw_tol = __TO_TOL(sr->full->mtol); if (sr->s_has_analog_value) { double tol = sdr_convert_sensor_tolerance(sr->full, raw_tol); printf("%.*f (+/- %.*f) %s\n", (sr->s_a_val == (int) sr->s_a_val) ? 0 : 3, sr->s_a_val, (tol == (int) tol) ? 0 : 3, tol, sr->s_a_units); } else { printf("0x%x (+/- 0x%x) %s\n", sr->s_reading, raw_tol, sr->s_a_units); } } else { printf("0x%x %s\n", sr->s_reading, sr->s_a_units); } printf(" Status : %s\n", thresh_status); if (thresh_available) { if (sr->full) { #define PTS(bit, dataidx, str) { \ print_thresh_setting(sr->full, rsp->data[0] & (bit), \ rsp->data[(dataidx)], \ (str), "%.3f\n", "0x%x\n", "%s\n"); \ } PTS(LOWER_NON_RECOV_SPECIFIED, 3, " Lower Non-Recoverable : "); PTS(LOWER_CRIT_SPECIFIED, 2, " Lower Critical : "); PTS(LOWER_NON_CRIT_SPECIFIED, 1, " Lower Non-Critical : "); PTS(UPPER_NON_CRIT_SPECIFIED, 4, " Upper Non-Critical : "); PTS(UPPER_CRIT_SPECIFIED, 5, " Upper Critical : "); PTS(UPPER_NON_RECOV_SPECIFIED, 6, " Upper Non-Recoverable : "); #undef PTS } ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, sr->full ? sr->full->threshold.hysteresis.positive : sr->compact->threshold.hysteresis.positive, "Positive Hysteresis"); ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, sr->full ? sr->full->threshold.hysteresis.negative : sr->compact->threshold.hysteresis.negative, "Negative Hysteresis"); } else { printf(" Sensor Threshold Settings not available\n"); } } else { printf(" Unable to read sensor: Device Not Present\n\n"); } ipmi_sdr_print_sensor_event_status(intf, sensor->keys. sensor_num, sensor->sensor.type, sensor->event_type, ANALOG_SENSOR, sensor->keys.owner_id, sensor->keys.lun, sensor->keys.channel); ipmi_sdr_print_sensor_event_enable(intf, sensor->keys. sensor_num, sensor->sensor.type, sensor->event_type, ANALOG_SENSOR, sensor->keys.owner_id, sensor->keys.lun, sensor->keys.channel); printf("\n"); } } return (sr->s_reading_valid ? 0 : -1 ); } int ipmi_sensor_print_fc(struct ipmi_intf *intf, struct sdr_record_common_sensor *sensor, uint8_t sdr_record_type) { if (IS_THRESHOLD_SENSOR(sensor)) return ipmi_sensor_print_fc_threshold(intf, sensor, sdr_record_type); else return ipmi_sensor_print_fc_discrete(intf, sensor, sdr_record_type); } static int ipmi_sensor_list(struct ipmi_intf *intf) { struct sdr_get_rs *header; struct ipmi_sdr_iterator *itr; int rc = 0; lprintf(LOG_DEBUG, "Querying SDR for sensor list"); itr = ipmi_sdr_start(intf, 0); if (itr == NULL) { lprintf(LOG_ERR, "Unable to open SDR for reading"); return -1; } while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) { uint8_t *rec; rec = ipmi_sdr_get_record(intf, header, itr); if (rec == NULL) { lprintf(LOG_DEBUG, "rec == NULL"); continue; } switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: case SDR_RECORD_TYPE_COMPACT_SENSOR: ipmi_sensor_print_fc(intf, (struct sdr_record_common_sensor *) rec, header->type); break; } free(rec); rec = NULL; /* fix for CR6604909: */ /* mask failure of individual reads in sensor list command */ /* rc = (r == 0) ? rc : r; */ } ipmi_sdr_end(intf, itr); return rc; } static const struct valstr threshold_vals[] = { {UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable"}, {UPPER_CRIT_SPECIFIED, "Upper Critical"}, {UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical"}, {LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable"}, {LOWER_CRIT_SPECIFIED, "Lower Critical"}, {LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical"}, {0x00, NULL}, }; static int __ipmi_sensor_set_threshold(struct ipmi_intf *intf, uint8_t num, uint8_t mask, uint8_t setting, uint8_t target, uint8_t lun, uint8_t channel) { struct ipmi_rs *rsp; rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting, target, lun, channel); if (rsp == NULL) { lprintf(LOG_ERR, "Error setting threshold"); return -1; } if (rsp->ccode > 0) { lprintf(LOG_ERR, "Error setting threshold: %s", val2str(rsp->ccode, completion_code_vals)); return -1; } return 0; } static uint8_t __ipmi_sensor_threshold_value_to_raw(struct sdr_record_full_sensor *full, double value) { if (!UNITS_ARE_DISCRETE(&full->cmn)) { /* Has an analog reading */ /* Has an analog reading and supports mx+b */ return sdr_convert_sensor_value_to_raw(full, value); } else { /* Does not have an analog reading and/or does not support mx+b */ if (value > 255) { return 255; } else if (value < 0) { return 0; } else { return (uint8_t )value; } } } static int ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv) { char *id, *thresh; uint8_t settingMask = 0; double setting1 = 0.0, setting2 = 0.0, setting3 = 0.0; int allUpper = 0, allLower = 0; int ret = 0; struct ipmi_rs *rsp; int i =0; double val[10] = {0}; struct sdr_record_list *sdr; if (argc < 3 || strncmp(argv[0], "help", 4) == 0) { print_sensor_thresh_usage(); return 0; } id = argv[0]; thresh = argv[1]; if (strncmp(thresh, "upper", 5) == 0) { if (argc < 5) { lprintf(LOG_ERR, "usage: sensor thresh upper "); return -1; } allUpper = 1; if (str2double(argv[2], &setting1) != 0) { lprintf(LOG_ERR, "Given unc '%s' is invalid.", argv[2]); return (-1); } if (str2double(argv[3], &setting2) != 0) { lprintf(LOG_ERR, "Given ucr '%s' is invalid.", argv[3]); return (-1); } if (str2double(argv[4], &setting3) != 0) { lprintf(LOG_ERR, "Given unr '%s' is invalid.", argv[4]); return (-1); } } else if (strncmp(thresh, "lower", 5) == 0) { if (argc < 5) { lprintf(LOG_ERR, "usage: sensor thresh lower "); return -1; } allLower = 1; if (str2double(argv[2], &setting1) != 0) { lprintf(LOG_ERR, "Given lnc '%s' is invalid.", argv[2]); return (-1); } if (str2double(argv[3], &setting2) != 0) { lprintf(LOG_ERR, "Given lcr '%s' is invalid.", argv[3]); return (-1); } if (str2double(argv[4], &setting3) != 0) { lprintf(LOG_ERR, "Given lnr '%s' is invalid.", argv[4]); return (-1); } } else { if (strncmp(thresh, "unr", 3) == 0) settingMask = UPPER_NON_RECOV_SPECIFIED; else if (strncmp(thresh, "ucr", 3) == 0) settingMask = UPPER_CRIT_SPECIFIED; else if (strncmp(thresh, "unc", 3) == 0) settingMask = UPPER_NON_CRIT_SPECIFIED; else if (strncmp(thresh, "lnc", 3) == 0) settingMask = LOWER_NON_CRIT_SPECIFIED; else if (strncmp(thresh, "lcr", 3) == 0) settingMask = LOWER_CRIT_SPECIFIED; else if (strncmp(thresh, "lnr", 3) == 0) settingMask = LOWER_NON_RECOV_SPECIFIED; else { lprintf(LOG_ERR, "Valid threshold '%s' for sensor '%s' not specified!", thresh, id); return -1; } if (str2double(argv[2], &setting1) != 0) { lprintf(LOG_ERR, "Given %s threshold value '%s' is invalid.", thresh, argv[2]); return (-1); } } printf("Locating sensor record '%s'...\n", id); /* lookup by sensor name */ sdr = ipmi_sdr_find_sdr_byid(intf, id); if (sdr == NULL) { lprintf(LOG_ERR, "Sensor data record not found!"); return -1; } if (sdr->type != SDR_RECORD_TYPE_FULL_SENSOR) { lprintf(LOG_ERR, "Invalid sensor type %02x", sdr->type); return -1; } if (!IS_THRESHOLD_SENSOR(sdr->record.common)) { lprintf(LOG_ERR, "Invalid sensor event type %02x", sdr->record.common->event_type); return -1; } if (allUpper) { settingMask = UPPER_NON_CRIT_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting1); ret = __ipmi_sensor_set_threshold(intf, sdr->record.common->keys. sensor_num, settingMask, __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), sdr->record.common->keys.owner_id, sdr->record.common->keys.lun, sdr->record.common->keys.channel); settingMask = UPPER_CRIT_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting2); ret = __ipmi_sensor_set_threshold(intf, sdr->record.common->keys. sensor_num, settingMask, __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2), sdr->record.common->keys.owner_id, sdr->record.common->keys.lun, sdr->record.common->keys.channel); settingMask = UPPER_NON_RECOV_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting3); ret = __ipmi_sensor_set_threshold(intf, sdr->record.common->keys. sensor_num, settingMask, __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3), sdr->record.common->keys.owner_id, sdr->record.common->keys.lun, sdr->record.common->keys.channel); } else if (allLower) { settingMask = LOWER_NON_RECOV_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting1); ret = __ipmi_sensor_set_threshold(intf, sdr->record.common->keys. sensor_num, settingMask, __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), sdr->record.common->keys.owner_id, sdr->record.common->keys.lun, sdr->record.common->keys.channel); settingMask = LOWER_CRIT_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting2); ret = __ipmi_sensor_set_threshold(intf, sdr->record.common->keys. sensor_num, settingMask, __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2), sdr->record.common->keys.owner_id, sdr->record.common->keys.lun, sdr->record.common->keys.channel); settingMask = LOWER_NON_CRIT_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting3); ret = __ipmi_sensor_set_threshold(intf, sdr->record.common->keys. sensor_num, settingMask, __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3), sdr->record.common->keys.owner_id, sdr->record.common->keys.lun, sdr->record.common->keys.channel); } else { /* * Current implementation doesn't check for the valid setting of upper non critical and other thresholds. * In the below logic: * Get all the current reading of the sensor i.e. unc, uc, lc,lnc. * Validate the values given by the user. * If the values are not correct, then popup with the Error message and return. */ /* * Get current reading */ rsp = ipmi_sdr_get_sensor_reading_ipmb(intf, sdr->record.common->keys.sensor_num, sdr->record.common->keys.owner_id, sdr->record.common->keys.lun,sdr->record.common->keys.channel); rsp = ipmi_sdr_get_sensor_thresholds(intf, sdr->record.common->keys.sensor_num, sdr->record.common->keys.owner_id, sdr->record.common->keys.lun, sdr->record.common->keys.channel); if ((rsp == NULL) || (rsp->ccode > 0)) { lprintf(LOG_ERR, "Sensor data record not found!"); return -1; } for(i=1;i<=6;i++) { val[i] = sdr_convert_sensor_reading(sdr->record.full, rsp->data[i]); if(val[i] < 0) val[i] = 0; } /* Check for the valid Upper non recovarable Value.*/ if( (settingMask & UPPER_NON_RECOV_SPECIFIED) ) { if( (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) && (( (rsp->data[0] & UPPER_CRIT_SPECIFIED) && ( setting1 <= val[5])) || ( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) && ( setting1 <= val[4]))) ) { lprintf(LOG_ERR, INVALID_THRESHOLD); return -1; } } else if( (settingMask & UPPER_CRIT_SPECIFIED) ) { /* Check for the valid Upper critical Value.*/ if( (rsp->data[0] & UPPER_CRIT_SPECIFIED) && (((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&& ( setting1 >= val[6])) || ((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 <= val[4]))) ) { lprintf(LOG_ERR, INVALID_THRESHOLD); return -1; } } else if( (settingMask & UPPER_NON_CRIT_SPECIFIED) ) { /* Check for the valid Upper non critical Value.*/ if( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) && (((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&&( setting1 >= val[6])) || ((rsp->data[0] & UPPER_CRIT_SPECIFIED)&&( setting1 >= val[5])) || ((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 <= val[1]))) ) { lprintf(LOG_ERR, INVALID_THRESHOLD); return -1; } } else if( (settingMask & LOWER_NON_CRIT_SPECIFIED) ) { /* Check for the valid lower non critical Value.*/ if( (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) && (((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 <= val[2])) || ((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))|| ((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 >= val[4]))) ) { lprintf(LOG_ERR, INVALID_THRESHOLD); return -1; } } else if( (settingMask & LOWER_CRIT_SPECIFIED) ) { /* Check for the valid lower critical Value.*/ if( (rsp->data[0] & LOWER_CRIT_SPECIFIED) && (((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) || ((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))) ) { lprintf(LOG_ERR, INVALID_THRESHOLD); return -1; } } else if( (settingMask & LOWER_NON_RECOV_SPECIFIED) ) { /* Check for the valid lower non recovarable Value.*/ if( (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) && (((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) || ((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 >= val[2]))) ) { lprintf(LOG_ERR, INVALID_THRESHOLD); return -1; } } else { /* None of this Then Return with error messages.*/ lprintf(LOG_ERR, INVALID_THRESHOLD); return -1; } printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting1); ret = __ipmi_sensor_set_threshold(intf, sdr->record.common->keys. sensor_num, settingMask, __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), sdr->record.common->keys.owner_id, sdr->record.common->keys.lun, sdr->record.common->keys.channel); } return ret; } static int ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv) { struct sdr_record_list *sdr; int i, rc=0; if (argc < 1 || strncmp(argv[0], "help", 4) == 0) { lprintf(LOG_NOTICE, "sensor reading ... [id]"); lprintf(LOG_NOTICE, " id : name of desired sensor"); return -1; } for (i = 0; i < argc; i++) { sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]); if (sdr == NULL) { lprintf(LOG_ERR, "Sensor \"%s\" not found!", argv[i]); rc = -1; continue; } switch (sdr->type) { case SDR_RECORD_TYPE_FULL_SENSOR: case SDR_RECORD_TYPE_COMPACT_SENSOR: { struct sensor_reading *sr; struct sdr_record_common_sensor *sensor = sdr->record.common; sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr->type, 3); if (sr == NULL) { rc = -1; continue; } if (!sr->full) continue; if (!sr->s_reading_valid) continue; if (!sr->s_has_analog_value) { lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]); continue; } if (csv_output) printf("%s,%s\n", argv[i], sr->s_a_str); else printf("%-16s | %s\n", argv[i], sr->s_a_str); break; } default: continue; } } return rc; } static int ipmi_sensor_get(struct ipmi_intf *intf, int argc, char **argv) { int i, v; int rc = 0; struct sdr_record_list *sdr; if (argc < 1) { lprintf(LOG_ERR, "Not enough parameters given."); print_sensor_get_usage(); return (-1); } else if (strcmp(argv[0], "help") == 0) { print_sensor_get_usage(); return 0; } printf("Locating sensor record...\n"); /* lookup by sensor name */ for (i = 0; i < argc; i++) { sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]); if (sdr == NULL) { lprintf(LOG_ERR, "Sensor data record \"%s\" not found!", argv[i]); rc = -1; continue; } /* need to set verbose level to 1 */ v = verbose; verbose = 1; switch (sdr->type) { case SDR_RECORD_TYPE_FULL_SENSOR: case SDR_RECORD_TYPE_COMPACT_SENSOR: if (ipmi_sensor_print_fc(intf, (struct sdr_record_common_sensor *) sdr->record.common, sdr->type)) { rc = -1; } break; default: if (ipmi_sdr_print_listentry(intf, sdr) < 0) { rc = (-1); } break; } verbose = v; sdr = NULL; } return rc; } int ipmi_sensor_main(struct ipmi_intf *intf, int argc, char **argv) { int rc = 0; if (argc == 0) { rc = ipmi_sensor_list(intf); } else if (strncmp(argv[0], "help", 4) == 0) { lprintf(LOG_NOTICE, "Sensor Commands: list thresh get reading"); } else if (strncmp(argv[0], "list", 4) == 0) { rc = ipmi_sensor_list(intf); } else if (strncmp(argv[0], "thresh", 5) == 0) { rc = ipmi_sensor_set_threshold(intf, argc - 1, &argv[1]); } else if (strncmp(argv[0], "get", 3) == 0) { rc = ipmi_sensor_get(intf, argc - 1, &argv[1]); } else if (strncmp(argv[0], "reading", 7) == 0) { rc = ipmi_sensor_get_reading(intf, argc - 1, &argv[1]); } else { lprintf(LOG_ERR, "Invalid sensor command: %s", argv[0]); rc = -1; } return rc; } /* print_sensor_get_usage - print usage for # ipmitool sensor get NAC; * * @returns: void */ void print_sensor_get_usage() { lprintf(LOG_NOTICE, "sensor get ... [id]"); lprintf(LOG_NOTICE, " id : name of desired sensor"); } /* print_sensor_thresh_set_usage - print usage for # ipmitool sensor thresh; * * @returns: void */ void print_sensor_thresh_usage() { lprintf(LOG_NOTICE, "sensor thresh "); lprintf(LOG_NOTICE, " id : name of the sensor for which threshold is to be set"); lprintf(LOG_NOTICE, " threshold : which threshold to set"); lprintf(LOG_NOTICE, " unr = upper non-recoverable"); lprintf(LOG_NOTICE, " ucr = upper critical"); lprintf(LOG_NOTICE, " unc = upper non-critical"); lprintf(LOG_NOTICE, " lnc = lower non-critical"); lprintf(LOG_NOTICE, " lcr = lower critical"); lprintf(LOG_NOTICE, " lnr = lower non-recoverable"); lprintf(LOG_NOTICE, " setting : the value to set the threshold to"); lprintf(LOG_NOTICE, ""); lprintf(LOG_NOTICE, "sensor thresh lower "); lprintf(LOG_NOTICE, " Set all lower thresholds at the same time"); lprintf(LOG_NOTICE, ""); lprintf(LOG_NOTICE, "sensor thresh upper "); lprintf(LOG_NOTICE, " Set all upper thresholds at the same time"); lprintf(LOG_NOTICE, ""); }