1 /* 2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * Redistribution of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistribution in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * Neither the name of Sun Microsystems, Inc. or the names of 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * This software is provided "AS IS," without a warranty of any kind. 20 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 23 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 24 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 25 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 26 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 27 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 28 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 29 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 30 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31 */ 32 33 #include <string.h> 34 #include <math.h> 35 36 #include <ipmitool/ipmi.h> 37 #include <ipmitool/helper.h> 38 #include <ipmitool/log.h> 39 #include <ipmitool/ipmi_intf.h> 40 #include <ipmitool/ipmi_sdr.h> 41 #include <ipmitool/ipmi_sel.h> 42 #include <ipmitool/ipmi_sensor.h> 43 44 extern int verbose; 45 void print_sensor_get_usage(); 46 void print_sensor_thresh_usage(); 47 48 // Macro's for Reading the current sensor Data. 49 #define SCANNING_DISABLED 0x40 50 #define READING_UNAVAILABLE 0x20 51 #define INVALID_THRESHOLD "Invalid Threshold data values. Cannot Set Threshold Data." 52 // static 53 int 54 ipmi_sensor_get_sensor_reading_factors( 55 struct ipmi_intf * intf, 56 struct sdr_record_full_sensor * sensor, 57 uint8_t reading) 58 { 59 struct ipmi_rq req; 60 struct ipmi_rs * rsp; 61 uint8_t req_data[2]; 62 63 char id[17]; 64 65 if (intf == NULL || sensor == NULL) 66 return -1; 67 68 memset(id, 0, sizeof(id)); 69 memcpy(id, sensor->id_string, 16); 70 71 req_data[0] = sensor->cmn.keys.sensor_num; 72 req_data[1] = reading; 73 74 memset(&req, 0, sizeof(req)); 75 req.msg.netfn = IPMI_NETFN_SE; 76 req.msg.lun = sensor->cmn.keys.lun; 77 req.msg.cmd = GET_SENSOR_FACTORS; 78 req.msg.data = req_data; 79 req.msg.data_len = sizeof(req_data); 80 81 rsp = intf->sendrecv(intf, &req); 82 83 if (rsp == NULL) { 84 lprintf(LOG_ERR, "Error updating reading factor for sensor %s (#%02x)", 85 id, sensor->cmn.keys.sensor_num); 86 return -1; 87 } else if (rsp->ccode) { 88 return -1; 89 } else { 90 /* Update SDR copy with updated Reading Factors for this reading */ 91 /* Note: 92 * The Format of the returned data is exactly as in the SDR definition (Little Endian Format), 93 * therefore we can use raw copy operation here. 94 * Note: rsp->data[0] would point to the next valid entry in the sampling table 95 */ 96 // BUGBUG: uses 'hardcoded' length information from SDR Definition 97 memcpy(&sensor->mtol, &rsp->data[1], sizeof(sensor->mtol)); 98 memcpy(&sensor->bacc, &rsp->data[3], sizeof(sensor->bacc)); 99 return 0; 100 } 101 102 } 103 104 static 105 struct ipmi_rs * 106 ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf, 107 uint8_t sensor, 108 uint8_t threshold, uint8_t setting, 109 uint8_t target, uint8_t lun, uint8_t channel) 110 { 111 struct ipmi_rq req; 112 static struct sensor_set_thresh_rq set_thresh_rq; 113 struct ipmi_rs *rsp; 114 uint8_t bridged_request = 0; 115 uint32_t save_addr; 116 uint32_t save_channel; 117 118 memset(&set_thresh_rq, 0, sizeof (set_thresh_rq)); 119 set_thresh_rq.sensor_num = sensor; 120 set_thresh_rq.set_mask = threshold; 121 if (threshold == UPPER_NON_RECOV_SPECIFIED) 122 set_thresh_rq.upper_non_recov = setting; 123 else if (threshold == UPPER_CRIT_SPECIFIED) 124 set_thresh_rq.upper_crit = setting; 125 else if (threshold == UPPER_NON_CRIT_SPECIFIED) 126 set_thresh_rq.upper_non_crit = setting; 127 else if (threshold == LOWER_NON_CRIT_SPECIFIED) 128 set_thresh_rq.lower_non_crit = setting; 129 else if (threshold == LOWER_CRIT_SPECIFIED) 130 set_thresh_rq.lower_crit = setting; 131 else if (threshold == LOWER_NON_RECOV_SPECIFIED) 132 set_thresh_rq.lower_non_recov = setting; 133 else 134 return NULL; 135 136 if (BRIDGE_TO_SENSOR(intf, target, channel)) { 137 bridged_request = 1; 138 save_addr = intf->target_addr; 139 intf->target_addr = target; 140 save_channel = intf->target_channel; 141 intf->target_channel = channel; 142 } 143 memset(&req, 0, sizeof (req)); 144 req.msg.netfn = IPMI_NETFN_SE; 145 req.msg.lun = lun; 146 req.msg.cmd = SET_SENSOR_THRESHOLDS; 147 req.msg.data = (uint8_t *) & set_thresh_rq; 148 req.msg.data_len = sizeof (set_thresh_rq); 149 150 rsp = intf->sendrecv(intf, &req); 151 if (bridged_request) { 152 intf->target_addr = save_addr; 153 intf->target_channel = save_channel; 154 } 155 return rsp; 156 } 157 158 static int 159 ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf, 160 struct sdr_record_common_sensor *sensor, 161 uint8_t sdr_record_type) 162 { 163 struct sensor_reading *sr; 164 165 sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3); 166 167 if (sr == NULL) { 168 return -1; 169 } 170 171 if (csv_output) { 172 /* NOT IMPLEMENTED */ 173 } else { 174 if (verbose == 0) { 175 /* output format 176 * id value units status thresholds.... 177 */ 178 printf("%-16s ", sr->s_id); 179 if (sr->s_reading_valid) { 180 if (sr->s_has_analog_value) { 181 /* don't show discrete component */ 182 printf("| %-10s | %-10s | %-6s", 183 sr->s_a_str, sr->s_a_units, "ok"); 184 } else { 185 printf("| 0x%-8x | %-10s | 0x%02x%02x", 186 sr->s_reading, "discrete", 187 sr->s_data2, sr->s_data3); 188 } 189 } else { 190 printf("| %-10s | %-10s | %-6s", 191 "na", "discrete", "na"); 192 } 193 printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", 194 "na", "na", "na", "na", "na", "na"); 195 196 printf("\n"); 197 } else { 198 printf("Sensor ID : %s (0x%x)\n", 199 sr->s_id, sensor->keys.sensor_num); 200 printf(" Entity ID : %d.%d\n", 201 sensor->entity.id, sensor->entity.instance); 202 printf(" Sensor Type (Discrete): %s\n", 203 ipmi_sdr_get_sensor_type_desc(sensor->sensor. 204 type)); 205 if( sr->s_reading_valid ) 206 { 207 if (sr->s_has_analog_value) { 208 printf(" Sensor Reading : %s %s\n", sr->s_a_str, sr->s_a_units); 209 } 210 ipmi_sdr_print_discrete_state("States Asserted", 211 sensor->sensor.type, 212 sensor->event_type, 213 sr->s_data2, 214 sr->s_data3); 215 printf("\n"); 216 } else { 217 printf(" Unable to read sensor: Device Not Present\n\n"); 218 } 219 } 220 } 221 222 return (sr->s_reading_valid ? 0 : -1 ); 223 } 224 225 static void 226 print_thresh_setting(struct sdr_record_full_sensor *full, 227 uint8_t thresh_is_avail, uint8_t setting, 228 const char *field_sep, 229 const char *analog_fmt, 230 const char *discrete_fmt, 231 const char *na_fmt) 232 { 233 printf("%s", field_sep); 234 if (!thresh_is_avail) { 235 printf(na_fmt, "na"); 236 return; 237 } 238 if (full && !UNITS_ARE_DISCRETE(&full->cmn)) { 239 printf(analog_fmt, sdr_convert_sensor_reading (full, setting)); 240 } else { 241 printf(discrete_fmt, setting); 242 } 243 } 244 245 static int 246 ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf, 247 struct sdr_record_common_sensor *sensor, 248 uint8_t sdr_record_type) 249 { 250 int thresh_available = 1; 251 struct ipmi_rs *rsp; 252 struct sensor_reading *sr; 253 254 sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3); 255 256 if (sr == NULL) { 257 return -1; 258 } 259 260 const char *thresh_status = ipmi_sdr_get_thresh_status(sr, "ns"); 261 262 /* 263 * Get sensor thresholds 264 */ 265 rsp = ipmi_sdr_get_sensor_thresholds(intf, 266 sensor->keys.sensor_num, sensor->keys.owner_id, 267 sensor->keys.lun, sensor->keys.channel); 268 269 if ((rsp == NULL) || (rsp->ccode > 0) || (rsp->data_len == 0)) 270 thresh_available = 0; 271 272 if (csv_output) { 273 /* NOT IMPLEMENTED */ 274 } else { 275 if (verbose == 0) { 276 /* output format 277 * id value units status thresholds.... 278 */ 279 printf("%-16s ", sr->s_id); 280 if (sr->s_reading_valid) { 281 if (sr->s_has_analog_value) 282 printf("| %-10.3f | %-10s | %-6s", 283 sr->s_a_val, sr->s_a_units, thresh_status); 284 else 285 printf("| 0x%-8x | %-10s | %-6s", 286 sr->s_reading, sr->s_a_units, thresh_status); 287 } else { 288 printf("| %-10s | %-10s | %-6s", 289 "na", sr->s_a_units, "na"); 290 } 291 if (thresh_available && sr->full) { 292 #define PTS(bit, dataidx) { \ 293 print_thresh_setting(sr->full, rsp->data[0] & (bit), \ 294 rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s"); \ 295 } 296 PTS(LOWER_NON_RECOV_SPECIFIED, 3); 297 PTS(LOWER_CRIT_SPECIFIED, 2); 298 PTS(LOWER_NON_CRIT_SPECIFIED, 1); 299 PTS(UPPER_NON_CRIT_SPECIFIED, 4); 300 PTS(UPPER_CRIT_SPECIFIED, 5); 301 PTS(UPPER_NON_RECOV_SPECIFIED, 6); 302 #undef PTS 303 } else { 304 printf 305 ("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", 306 "na", "na", "na", "na", "na", "na"); 307 } 308 309 printf("\n"); 310 } else { 311 printf("Sensor ID : %s (0x%x)\n", 312 sr->s_id, sensor->keys.sensor_num); 313 314 printf(" Entity ID : %d.%d\n", 315 sensor->entity.id, sensor->entity.instance); 316 317 printf(" Sensor Type (Threshold) : %s\n", 318 ipmi_sdr_get_sensor_type_desc(sensor->sensor. 319 type)); 320 321 printf(" Sensor Reading : "); 322 if (sr->s_reading_valid) { 323 if (sr->full) { 324 uint16_t raw_tol = __TO_TOL(sr->full->mtol); 325 if (sr->s_has_analog_value) { 326 double tol = 327 sdr_convert_sensor_tolerance(sr->full, 328 raw_tol); 329 printf("%.*f (+/- %.*f) %s\n", 330 (sr->s_a_val == (int) 331 sr->s_a_val) ? 0 : 3, 332 sr->s_a_val, 333 (tol == (int) tol) ? 0 : 3, tol, 334 sr->s_a_units); 335 } else { 336 printf("0x%x (+/- 0x%x) %s\n", 337 sr->s_reading, 338 raw_tol, 339 sr->s_a_units); 340 } 341 } else { 342 printf("0x%x %s\n", sr->s_reading, 343 sr->s_a_units); 344 } 345 printf(" Status : %s\n", thresh_status); 346 347 if (thresh_available) { 348 if (sr->full) { 349 #define PTS(bit, dataidx, str) { \ 350 print_thresh_setting(sr->full, rsp->data[0] & (bit), \ 351 rsp->data[(dataidx)], \ 352 (str), "%.3f\n", "0x%x\n", "%s\n"); \ 353 } 354 355 PTS(LOWER_NON_RECOV_SPECIFIED, 3, " Lower Non-Recoverable : "); 356 PTS(LOWER_CRIT_SPECIFIED, 2, " Lower Critical : "); 357 PTS(LOWER_NON_CRIT_SPECIFIED, 1, " Lower Non-Critical : "); 358 PTS(UPPER_NON_CRIT_SPECIFIED, 4, " Upper Non-Critical : "); 359 PTS(UPPER_CRIT_SPECIFIED, 5, " Upper Critical : "); 360 PTS(UPPER_NON_RECOV_SPECIFIED, 6, " Upper Non-Recoverable : "); 361 #undef PTS 362 363 } 364 ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, 365 sr->full ? sr->full->threshold.hysteresis.positive : 366 sr->compact->threshold.hysteresis.positive, 367 "Positive Hysteresis"); 368 369 ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, 370 sr->full ? sr->full->threshold.hysteresis.negative : 371 sr->compact->threshold.hysteresis.negative, 372 "Negative Hysteresis"); 373 } else { 374 printf(" Sensor Threshold Settings not available\n"); 375 } 376 } else { 377 printf(" Unable to read sensor: Device Not Present\n\n"); 378 } 379 380 ipmi_sdr_print_sensor_event_status(intf, 381 sensor->keys. 382 sensor_num, 383 sensor->sensor.type, 384 sensor->event_type, 385 ANALOG_SENSOR, 386 sensor->keys.owner_id, 387 sensor->keys.lun, 388 sensor->keys.channel); 389 ipmi_sdr_print_sensor_event_enable(intf, 390 sensor->keys. 391 sensor_num, 392 sensor->sensor.type, 393 sensor->event_type, 394 ANALOG_SENSOR, 395 sensor->keys.owner_id, 396 sensor->keys.lun, 397 sensor->keys.channel); 398 399 printf("\n"); 400 } 401 } 402 403 return (sr->s_reading_valid ? 0 : -1 ); 404 } 405 406 int 407 ipmi_sensor_print_fc(struct ipmi_intf *intf, 408 struct sdr_record_common_sensor *sensor, 409 uint8_t sdr_record_type) 410 { 411 if (IS_THRESHOLD_SENSOR(sensor)) 412 return ipmi_sensor_print_fc_threshold(intf, sensor, sdr_record_type); 413 else 414 return ipmi_sensor_print_fc_discrete(intf, sensor, sdr_record_type); 415 } 416 417 static int 418 ipmi_sensor_list(struct ipmi_intf *intf) 419 { 420 struct sdr_get_rs *header; 421 struct ipmi_sdr_iterator *itr; 422 int rc = 0; 423 424 lprintf(LOG_DEBUG, "Querying SDR for sensor list"); 425 426 itr = ipmi_sdr_start(intf, 0); 427 if (itr == NULL) { 428 lprintf(LOG_ERR, "Unable to open SDR for reading"); 429 return -1; 430 } 431 432 while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) { 433 uint8_t *rec; 434 435 rec = ipmi_sdr_get_record(intf, header, itr); 436 if (rec == NULL) { 437 lprintf(LOG_DEBUG, "rec == NULL"); 438 continue; 439 } 440 441 switch (header->type) { 442 case SDR_RECORD_TYPE_FULL_SENSOR: 443 case SDR_RECORD_TYPE_COMPACT_SENSOR: 444 ipmi_sensor_print_fc(intf, 445 (struct 446 sdr_record_common_sensor *) 447 rec, 448 header->type); 449 break; 450 } 451 free(rec); 452 rec = NULL; 453 454 /* fix for CR6604909: */ 455 /* mask failure of individual reads in sensor list command */ 456 /* rc = (r == 0) ? rc : r; */ 457 } 458 459 ipmi_sdr_end(intf, itr); 460 461 return rc; 462 } 463 464 static const struct valstr threshold_vals[] = { 465 {UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable"}, 466 {UPPER_CRIT_SPECIFIED, "Upper Critical"}, 467 {UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical"}, 468 {LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable"}, 469 {LOWER_CRIT_SPECIFIED, "Lower Critical"}, 470 {LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical"}, 471 {0x00, NULL}, 472 }; 473 474 static int 475 __ipmi_sensor_set_threshold(struct ipmi_intf *intf, 476 uint8_t num, uint8_t mask, uint8_t setting, 477 uint8_t target, uint8_t lun, uint8_t channel) 478 { 479 struct ipmi_rs *rsp; 480 481 rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting, 482 target, lun, channel); 483 484 if (rsp == NULL) { 485 lprintf(LOG_ERR, "Error setting threshold"); 486 return -1; 487 } 488 if (rsp->ccode > 0) { 489 lprintf(LOG_ERR, "Error setting threshold: %s", 490 val2str(rsp->ccode, completion_code_vals)); 491 return -1; 492 } 493 494 return 0; 495 } 496 497 static uint8_t 498 __ipmi_sensor_threshold_value_to_raw(struct sdr_record_full_sensor *full, double value) 499 { 500 if (!UNITS_ARE_DISCRETE(&full->cmn)) { /* Has an analog reading */ 501 /* Has an analog reading and supports mx+b */ 502 return sdr_convert_sensor_value_to_raw(full, value); 503 } 504 else { 505 /* Does not have an analog reading and/or does not support mx+b */ 506 if (value > 255) { 507 return 255; 508 } 509 else if (value < 0) { 510 return 0; 511 } 512 else { 513 return (uint8_t )value; 514 } 515 } 516 } 517 518 static int 519 ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv) 520 { 521 char *id, *thresh; 522 uint8_t settingMask = 0; 523 double setting1 = 0.0, setting2 = 0.0, setting3 = 0.0; 524 int allUpper = 0, allLower = 0; 525 int ret = 0; 526 struct ipmi_rs *rsp; 527 int i =0; 528 double val[10] = {0}; 529 530 struct sdr_record_list *sdr; 531 532 if (argc < 3 || strncmp(argv[0], "help", 4) == 0) { 533 print_sensor_thresh_usage(); 534 return 0; 535 } 536 537 id = argv[0]; 538 thresh = argv[1]; 539 540 if (strncmp(thresh, "upper", 5) == 0) { 541 if (argc < 5) { 542 lprintf(LOG_ERR, 543 "usage: sensor thresh <id> upper <unc> <ucr> <unr>"); 544 return -1; 545 } 546 allUpper = 1; 547 if (str2double(argv[2], &setting1) != 0) { 548 lprintf(LOG_ERR, "Given unc '%s' is invalid.", 549 argv[2]); 550 return (-1); 551 } 552 if (str2double(argv[3], &setting2) != 0) { 553 lprintf(LOG_ERR, "Given ucr '%s' is invalid.", 554 argv[3]); 555 return (-1); 556 } 557 if (str2double(argv[4], &setting3) != 0) { 558 lprintf(LOG_ERR, "Given unr '%s' is invalid.", 559 argv[4]); 560 return (-1); 561 } 562 } else if (strncmp(thresh, "lower", 5) == 0) { 563 if (argc < 5) { 564 lprintf(LOG_ERR, 565 "usage: sensor thresh <id> lower <lnr> <lcr> <lnc>"); 566 return -1; 567 } 568 allLower = 1; 569 if (str2double(argv[2], &setting1) != 0) { 570 lprintf(LOG_ERR, "Given lnc '%s' is invalid.", 571 argv[2]); 572 return (-1); 573 } 574 if (str2double(argv[3], &setting2) != 0) { 575 lprintf(LOG_ERR, "Given lcr '%s' is invalid.", 576 argv[3]); 577 return (-1); 578 } 579 if (str2double(argv[4], &setting3) != 0) { 580 lprintf(LOG_ERR, "Given lnr '%s' is invalid.", 581 argv[4]); 582 return (-1); 583 } 584 } else { 585 if (strncmp(thresh, "unr", 3) == 0) 586 settingMask = UPPER_NON_RECOV_SPECIFIED; 587 else if (strncmp(thresh, "ucr", 3) == 0) 588 settingMask = UPPER_CRIT_SPECIFIED; 589 else if (strncmp(thresh, "unc", 3) == 0) 590 settingMask = UPPER_NON_CRIT_SPECIFIED; 591 else if (strncmp(thresh, "lnc", 3) == 0) 592 settingMask = LOWER_NON_CRIT_SPECIFIED; 593 else if (strncmp(thresh, "lcr", 3) == 0) 594 settingMask = LOWER_CRIT_SPECIFIED; 595 else if (strncmp(thresh, "lnr", 3) == 0) 596 settingMask = LOWER_NON_RECOV_SPECIFIED; 597 else { 598 lprintf(LOG_ERR, 599 "Valid threshold '%s' for sensor '%s' not specified!", 600 thresh, id); 601 return -1; 602 } 603 if (str2double(argv[2], &setting1) != 0) { 604 lprintf(LOG_ERR, 605 "Given %s threshold value '%s' is invalid.", 606 thresh, argv[2]); 607 return (-1); 608 } 609 } 610 611 printf("Locating sensor record '%s'...\n", id); 612 613 /* lookup by sensor name */ 614 sdr = ipmi_sdr_find_sdr_byid(intf, id); 615 if (sdr == NULL) { 616 lprintf(LOG_ERR, "Sensor data record not found!"); 617 return -1; 618 } 619 620 if (sdr->type != SDR_RECORD_TYPE_FULL_SENSOR) { 621 lprintf(LOG_ERR, "Invalid sensor type %02x", sdr->type); 622 return -1; 623 } 624 625 if (!IS_THRESHOLD_SENSOR(sdr->record.common)) { 626 lprintf(LOG_ERR, "Invalid sensor event type %02x", sdr->record.common->event_type); 627 return -1; 628 } 629 630 631 if (allUpper) { 632 settingMask = UPPER_NON_CRIT_SPECIFIED; 633 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 634 sdr->record.full->id_string, 635 val2str(settingMask, threshold_vals), setting1); 636 ret = __ipmi_sensor_set_threshold(intf, 637 sdr->record.common->keys. 638 sensor_num, settingMask, 639 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), 640 sdr->record.common->keys.owner_id, 641 sdr->record.common->keys.lun, 642 sdr->record.common->keys.channel); 643 644 settingMask = UPPER_CRIT_SPECIFIED; 645 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 646 sdr->record.full->id_string, 647 val2str(settingMask, threshold_vals), setting2); 648 ret = __ipmi_sensor_set_threshold(intf, 649 sdr->record.common->keys. 650 sensor_num, settingMask, 651 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2), 652 sdr->record.common->keys.owner_id, 653 sdr->record.common->keys.lun, 654 sdr->record.common->keys.channel); 655 656 settingMask = UPPER_NON_RECOV_SPECIFIED; 657 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 658 sdr->record.full->id_string, 659 val2str(settingMask, threshold_vals), setting3); 660 ret = __ipmi_sensor_set_threshold(intf, 661 sdr->record.common->keys. 662 sensor_num, settingMask, 663 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3), 664 sdr->record.common->keys.owner_id, 665 sdr->record.common->keys.lun, 666 sdr->record.common->keys.channel); 667 } else if (allLower) { 668 settingMask = LOWER_NON_RECOV_SPECIFIED; 669 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 670 sdr->record.full->id_string, 671 val2str(settingMask, threshold_vals), setting1); 672 ret = __ipmi_sensor_set_threshold(intf, 673 sdr->record.common->keys. 674 sensor_num, settingMask, 675 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), 676 sdr->record.common->keys.owner_id, 677 sdr->record.common->keys.lun, 678 sdr->record.common->keys.channel); 679 680 settingMask = LOWER_CRIT_SPECIFIED; 681 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 682 sdr->record.full->id_string, 683 val2str(settingMask, threshold_vals), setting2); 684 ret = __ipmi_sensor_set_threshold(intf, 685 sdr->record.common->keys. 686 sensor_num, settingMask, 687 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2), 688 sdr->record.common->keys.owner_id, 689 sdr->record.common->keys.lun, 690 sdr->record.common->keys.channel); 691 692 settingMask = LOWER_NON_CRIT_SPECIFIED; 693 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 694 sdr->record.full->id_string, 695 val2str(settingMask, threshold_vals), setting3); 696 ret = __ipmi_sensor_set_threshold(intf, 697 sdr->record.common->keys. 698 sensor_num, settingMask, 699 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3), 700 sdr->record.common->keys.owner_id, 701 sdr->record.common->keys.lun, 702 sdr->record.common->keys.channel); 703 } else { 704 705 /* 706 * Current implementation doesn't check for the valid setting of upper non critical and other thresholds. 707 * In the below logic: 708 * Get all the current reading of the sensor i.e. unc, uc, lc,lnc. 709 * Validate the values given by the user. 710 * If the values are not correct, then popup with the Error message and return. 711 */ 712 /* 713 * Get current reading 714 */ 715 rsp = ipmi_sdr_get_sensor_reading_ipmb(intf, 716 sdr->record.common->keys.sensor_num, 717 sdr->record.common->keys.owner_id, 718 sdr->record.common->keys.lun,sdr->record.common->keys.channel); 719 rsp = ipmi_sdr_get_sensor_thresholds(intf, 720 sdr->record.common->keys.sensor_num, 721 sdr->record.common->keys.owner_id, 722 sdr->record.common->keys.lun, 723 sdr->record.common->keys.channel); 724 if ((rsp == NULL) || (rsp->ccode > 0)) { 725 lprintf(LOG_ERR, "Sensor data record not found!"); 726 return -1; 727 } 728 for(i=1;i<=6;i++) { 729 val[i] = sdr_convert_sensor_reading(sdr->record.full, rsp->data[i]); 730 if(val[i] < 0) 731 val[i] = 0; 732 } 733 /* Check for the valid Upper non recovarable Value.*/ 734 if( (settingMask & UPPER_NON_RECOV_SPECIFIED) ) { 735 736 if( (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) && 737 (( (rsp->data[0] & UPPER_CRIT_SPECIFIED) && ( setting1 <= val[5])) || 738 ( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) && ( setting1 <= val[4]))) ) 739 { 740 lprintf(LOG_ERR, INVALID_THRESHOLD); 741 return -1; 742 } 743 } else if( (settingMask & UPPER_CRIT_SPECIFIED) ) { /* Check for the valid Upper critical Value.*/ 744 if( (rsp->data[0] & UPPER_CRIT_SPECIFIED) && 745 (((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&& ( setting1 >= val[6])) || 746 ((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 <= val[4]))) ) 747 { 748 lprintf(LOG_ERR, INVALID_THRESHOLD); 749 return -1; 750 } 751 } else if( (settingMask & UPPER_NON_CRIT_SPECIFIED) ) { /* Check for the valid Upper non critical Value.*/ 752 if( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) && 753 (((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&&( setting1 >= val[6])) || 754 ((rsp->data[0] & UPPER_CRIT_SPECIFIED)&&( setting1 >= val[5])) || 755 ((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 <= val[1]))) ) 756 { 757 lprintf(LOG_ERR, INVALID_THRESHOLD); 758 return -1; 759 } 760 } else if( (settingMask & LOWER_NON_CRIT_SPECIFIED) ) { /* Check for the valid lower non critical Value.*/ 761 if( (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) && 762 (((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 <= val[2])) || 763 ((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))|| 764 ((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 >= val[4]))) ) 765 { 766 lprintf(LOG_ERR, INVALID_THRESHOLD); 767 return -1; 768 } 769 } else if( (settingMask & LOWER_CRIT_SPECIFIED) ) { /* Check for the valid lower critical Value.*/ 770 if( (rsp->data[0] & LOWER_CRIT_SPECIFIED) && 771 (((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) || 772 ((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))) ) 773 { 774 lprintf(LOG_ERR, INVALID_THRESHOLD); 775 return -1; 776 } 777 } else if( (settingMask & LOWER_NON_RECOV_SPECIFIED) ) { /* Check for the valid lower non recovarable Value.*/ 778 if( (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) && 779 (((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) || 780 ((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 >= val[2]))) ) 781 { 782 lprintf(LOG_ERR, INVALID_THRESHOLD); 783 return -1; 784 } 785 } else { /* None of this Then Return with error messages.*/ 786 lprintf(LOG_ERR, INVALID_THRESHOLD); 787 return -1; 788 } 789 790 791 printf("Setting sensor \"%s\" %s threshold to %.3f\n", 792 sdr->record.full->id_string, 793 val2str(settingMask, threshold_vals), setting1); 794 795 ret = __ipmi_sensor_set_threshold(intf, 796 sdr->record.common->keys. 797 sensor_num, settingMask, 798 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), 799 sdr->record.common->keys.owner_id, 800 sdr->record.common->keys.lun, 801 sdr->record.common->keys.channel); 802 } 803 804 return ret; 805 } 806 807 static int 808 ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv) 809 { 810 struct sdr_record_list *sdr; 811 int i, rc=0; 812 813 if (argc < 1 || strncmp(argv[0], "help", 4) == 0) { 814 lprintf(LOG_NOTICE, "sensor reading <id> ... [id]"); 815 lprintf(LOG_NOTICE, " id : name of desired sensor"); 816 return -1; 817 } 818 819 for (i = 0; i < argc; i++) { 820 sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]); 821 if (sdr == NULL) { 822 lprintf(LOG_ERR, "Sensor \"%s\" not found!", 823 argv[i]); 824 rc = -1; 825 continue; 826 } 827 828 switch (sdr->type) { 829 case SDR_RECORD_TYPE_FULL_SENSOR: 830 case SDR_RECORD_TYPE_COMPACT_SENSOR: 831 { 832 struct sensor_reading *sr; 833 struct sdr_record_common_sensor *sensor = sdr->record.common; 834 sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr->type, 3); 835 836 if (sr == NULL) { 837 rc = -1; 838 continue; 839 } 840 841 if (!sr->full) 842 continue; 843 844 if (!sr->s_reading_valid) 845 continue; 846 847 if (!sr->s_has_analog_value) { 848 lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]); 849 continue; 850 } 851 if (csv_output) 852 printf("%s,%s\n", argv[i], sr->s_a_str); 853 else 854 printf("%-16s | %s\n", argv[i], sr->s_a_str); 855 856 break; 857 } 858 default: 859 continue; 860 } 861 } 862 863 return rc; 864 } 865 866 static int 867 ipmi_sensor_get(struct ipmi_intf *intf, int argc, char **argv) 868 { 869 int i, v; 870 int rc = 0; 871 struct sdr_record_list *sdr; 872 873 if (argc < 1) { 874 lprintf(LOG_ERR, "Not enough parameters given."); 875 print_sensor_get_usage(); 876 return (-1); 877 } else if (strcmp(argv[0], "help") == 0) { 878 print_sensor_get_usage(); 879 return 0; 880 } 881 printf("Locating sensor record...\n"); 882 /* lookup by sensor name */ 883 for (i = 0; i < argc; i++) { 884 sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]); 885 if (sdr == NULL) { 886 lprintf(LOG_ERR, "Sensor data record \"%s\" not found!", 887 argv[i]); 888 rc = -1; 889 continue; 890 } 891 /* need to set verbose level to 1 */ 892 v = verbose; 893 verbose = 1; 894 switch (sdr->type) { 895 case SDR_RECORD_TYPE_FULL_SENSOR: 896 case SDR_RECORD_TYPE_COMPACT_SENSOR: 897 if (ipmi_sensor_print_fc(intf, 898 (struct sdr_record_common_sensor *) sdr->record.common, 899 sdr->type)) { 900 rc = -1; 901 } 902 break; 903 default: 904 if (ipmi_sdr_print_listentry(intf, sdr) < 0) { 905 rc = (-1); 906 } 907 break; 908 } 909 verbose = v; 910 sdr = NULL; 911 } 912 return rc; 913 } 914 915 int 916 ipmi_sensor_main(struct ipmi_intf *intf, int argc, char **argv) 917 { 918 int rc = 0; 919 920 if (argc == 0) { 921 rc = ipmi_sensor_list(intf); 922 } else if (strncmp(argv[0], "help", 4) == 0) { 923 lprintf(LOG_NOTICE, "Sensor Commands: list thresh get reading"); 924 } else if (strncmp(argv[0], "list", 4) == 0) { 925 rc = ipmi_sensor_list(intf); 926 } else if (strncmp(argv[0], "thresh", 5) == 0) { 927 rc = ipmi_sensor_set_threshold(intf, argc - 1, &argv[1]); 928 } else if (strncmp(argv[0], "get", 3) == 0) { 929 rc = ipmi_sensor_get(intf, argc - 1, &argv[1]); 930 } else if (strncmp(argv[0], "reading", 7) == 0) { 931 rc = ipmi_sensor_get_reading(intf, argc - 1, &argv[1]); 932 } else { 933 lprintf(LOG_ERR, "Invalid sensor command: %s", argv[0]); 934 rc = -1; 935 } 936 937 return rc; 938 } 939 940 /* print_sensor_get_usage - print usage for # ipmitool sensor get NAC; 941 * 942 * @returns: void 943 */ 944 void 945 print_sensor_get_usage() 946 { 947 lprintf(LOG_NOTICE, "sensor get <id> ... [id]"); 948 lprintf(LOG_NOTICE, " id : name of desired sensor"); 949 } 950 951 /* print_sensor_thresh_set_usage - print usage for # ipmitool sensor thresh; 952 * 953 * @returns: void 954 */ 955 void 956 print_sensor_thresh_usage() 957 { 958 lprintf(LOG_NOTICE, 959 "sensor thresh <id> <threshold> <setting>"); 960 lprintf(LOG_NOTICE, 961 " id : name of the sensor for which threshold is to be set"); 962 lprintf(LOG_NOTICE, 963 " threshold : which threshold to set"); 964 lprintf(LOG_NOTICE, 965 " unr = upper non-recoverable"); 966 lprintf(LOG_NOTICE, 967 " ucr = upper critical"); 968 lprintf(LOG_NOTICE, 969 " unc = upper non-critical"); 970 lprintf(LOG_NOTICE, 971 " lnc = lower non-critical"); 972 lprintf(LOG_NOTICE, 973 " lcr = lower critical"); 974 lprintf(LOG_NOTICE, 975 " lnr = lower non-recoverable"); 976 lprintf(LOG_NOTICE, 977 " setting : the value to set the threshold to"); 978 lprintf(LOG_NOTICE, 979 ""); 980 lprintf(LOG_NOTICE, 981 "sensor thresh <id> lower <lnr> <lcr> <lnc>"); 982 lprintf(LOG_NOTICE, 983 " Set all lower thresholds at the same time"); 984 lprintf(LOG_NOTICE, 985 ""); 986 lprintf(LOG_NOTICE, 987 "sensor thresh <id> upper <unc> <ucr> <unr>"); 988 lprintf(LOG_NOTICE, 989 " Set all upper thresholds at the same time"); 990 lprintf(LOG_NOTICE, ""); 991 } 992