123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857 |
- // SPDX-License-Identifier: GPL-3.0-or-later
- /*
- * netdata freeipmi.plugin
- * Copyright (C) 2017 Costa Tsaousis
- * GPL v3+
- *
- * Based on:
- * ipmimonitoring-sensors.c,v 1.51 2016/11/02 23:46:24 chu11 Exp
- * ipmimonitoring-sel.c,v 1.51 2016/11/02 23:46:24 chu11 Exp
- *
- * Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC.
- * Copyright (C) 2006-2007 The Regents of the University of California.
- * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
- * Written by Albert Chu <chu11@llnl.gov>
- * UCRL-CODE-222073
- */
- #include "libnetdata/libnetdata.h"
- #include "libnetdata/required_dummies.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
- #include <assert.h>
- #include <errno.h>
- #include <unistd.h>
- #include <sys/time.h>
- #define IPMI_PARSE_DEVICE_LAN_STR "lan"
- #define IPMI_PARSE_DEVICE_LAN_2_0_STR "lan_2_0"
- #define IPMI_PARSE_DEVICE_LAN_2_0_STR2 "lan20"
- #define IPMI_PARSE_DEVICE_LAN_2_0_STR3 "lan_20"
- #define IPMI_PARSE_DEVICE_LAN_2_0_STR4 "lan2_0"
- #define IPMI_PARSE_DEVICE_LAN_2_0_STR5 "lanplus"
- #define IPMI_PARSE_DEVICE_KCS_STR "kcs"
- #define IPMI_PARSE_DEVICE_SSIF_STR "ssif"
- #define IPMI_PARSE_DEVICE_OPENIPMI_STR "openipmi"
- #define IPMI_PARSE_DEVICE_OPENIPMI_STR2 "open"
- #define IPMI_PARSE_DEVICE_SUNBMC_STR "sunbmc"
- #define IPMI_PARSE_DEVICE_SUNBMC_STR2 "bmc"
- #define IPMI_PARSE_DEVICE_INTELDCMI_STR "inteldcmi"
- #include <ipmi_monitoring.h>
- #include <ipmi_monitoring_bitmasks.h>
- /* Communication Configuration - Initialize accordingly */
- /* Hostname, NULL for In-band communication, non-null for a hostname */
- char *hostname = NULL;
- /* In-band Communication Configuration */
- int driver_type = -1; // IPMI_MONITORING_DRIVER_TYPE_KCS; /* or -1 for default */
- int disable_auto_probe = 0; /* probe for in-band device */
- unsigned int driver_address = 0; /* not used if probing */
- unsigned int register_spacing = 0; /* not used if probing */
- char *driver_device = NULL; /* not used if probing */
- /* Out-of-band Communication Configuration */
- int protocol_version = -1; //IPMI_MONITORING_PROTOCOL_VERSION_1_5; /* or -1 for default */
- char *username = "foousername";
- char *password = "foopassword";
- unsigned char *ipmi_k_g = NULL;
- unsigned int ipmi_k_g_len = 0;
- int privilege_level = -1; // IPMI_MONITORING_PRIVILEGE_LEVEL_USER; /* or -1 for default */
- int authentication_type = -1; // IPMI_MONITORING_AUTHENTICATION_TYPE_MD5; /* or -1 for default */
- int cipher_suite_id = 0; /* or -1 for default */
- int session_timeout = 0; /* 0 for default */
- int retransmission_timeout = 0; /* 0 for default */
- /* Workarounds - specify workaround flags if necessary */
- unsigned int workaround_flags = 0;
- /* Initialize w/ record id numbers to only monitor specific record ids */
- unsigned int record_ids[] = {0};
- unsigned int record_ids_length = 0;
- /* Initialize w/ sensor types to only monitor specific sensor types
- * see ipmi_monitoring.h sensor types list.
- */
- unsigned int sensor_types[] = {0};
- unsigned int sensor_types_length = 0;
- /* Set to an appropriate alternate if desired */
- char *sdr_cache_directory = "/tmp";
- char *sensor_config_file = NULL;
- /* Set to 1 or 0 to enable these sensor reading flags
- * - See ipmi_monitoring.h for descriptions of these flags.
- */
- int reread_sdr_cache = 0;
- int ignore_non_interpretable_sensors = 0;
- int bridge_sensors = 0;
- int interpret_oem_data = 0;
- int shared_sensors = 0;
- int discrete_reading = 1;
- int ignore_scanning_disabled = 0;
- int assume_bmc_owner = 0;
- int entity_sensor_names = 0;
- /* Initialization flags
- *
- * Most commonly bitwise OR IPMI_MONITORING_FLAGS_DEBUG and/or
- * IPMI_MONITORING_FLAGS_DEBUG_IPMI_PACKETS for extra debugging
- * information.
- */
- unsigned int ipmimonitoring_init_flags = 0;
- int errnum;
- // ----------------------------------------------------------------------------
- // SEL only variables
- /* Initialize w/ date range to only monitoring specific date range */
- char *date_begin = NULL; /* use MM/DD/YYYY format */
- char *date_end = NULL; /* use MM/DD/YYYY format */
- int assume_system_event_record = 0;
- char *sel_config_file = NULL;
- // ----------------------------------------------------------------------------
- // functions common to sensors and SEL
- static void
- _init_ipmi_config (struct ipmi_monitoring_ipmi_config *ipmi_config)
- {
- fatal_assert(ipmi_config);
- ipmi_config->driver_type = driver_type;
- ipmi_config->disable_auto_probe = disable_auto_probe;
- ipmi_config->driver_address = driver_address;
- ipmi_config->register_spacing = register_spacing;
- ipmi_config->driver_device = driver_device;
- ipmi_config->protocol_version = protocol_version;
- ipmi_config->username = username;
- ipmi_config->password = password;
- ipmi_config->k_g = ipmi_k_g;
- ipmi_config->k_g_len = ipmi_k_g_len;
- ipmi_config->privilege_level = privilege_level;
- ipmi_config->authentication_type = authentication_type;
- ipmi_config->cipher_suite_id = cipher_suite_id;
- ipmi_config->session_timeout_len = session_timeout;
- ipmi_config->retransmission_timeout_len = retransmission_timeout;
- ipmi_config->workaround_flags = workaround_flags;
- }
- #ifdef NETDATA_COMMENTED
- static const char *
- _get_sensor_type_string (int sensor_type)
- {
- switch (sensor_type)
- {
- case IPMI_MONITORING_SENSOR_TYPE_RESERVED:
- return ("Reserved");
- case IPMI_MONITORING_SENSOR_TYPE_TEMPERATURE:
- return ("Temperature");
- case IPMI_MONITORING_SENSOR_TYPE_VOLTAGE:
- return ("Voltage");
- case IPMI_MONITORING_SENSOR_TYPE_CURRENT:
- return ("Current");
- case IPMI_MONITORING_SENSOR_TYPE_FAN:
- return ("Fan");
- case IPMI_MONITORING_SENSOR_TYPE_PHYSICAL_SECURITY:
- return ("Physical Security");
- case IPMI_MONITORING_SENSOR_TYPE_PLATFORM_SECURITY_VIOLATION_ATTEMPT:
- return ("Platform Security Violation Attempt");
- case IPMI_MONITORING_SENSOR_TYPE_PROCESSOR:
- return ("Processor");
- case IPMI_MONITORING_SENSOR_TYPE_POWER_SUPPLY:
- return ("Power Supply");
- case IPMI_MONITORING_SENSOR_TYPE_POWER_UNIT:
- return ("Power Unit");
- case IPMI_MONITORING_SENSOR_TYPE_COOLING_DEVICE:
- return ("Cooling Device");
- case IPMI_MONITORING_SENSOR_TYPE_OTHER_UNITS_BASED_SENSOR:
- return ("Other Units Based Sensor");
- case IPMI_MONITORING_SENSOR_TYPE_MEMORY:
- return ("Memory");
- case IPMI_MONITORING_SENSOR_TYPE_DRIVE_SLOT:
- return ("Drive Slot");
- case IPMI_MONITORING_SENSOR_TYPE_POST_MEMORY_RESIZE:
- return ("POST Memory Resize");
- case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS:
- return ("System Firmware Progress");
- case IPMI_MONITORING_SENSOR_TYPE_EVENT_LOGGING_DISABLED:
- return ("Event Logging Disabled");
- case IPMI_MONITORING_SENSOR_TYPE_WATCHDOG1:
- return ("Watchdog 1");
- case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_EVENT:
- return ("System Event");
- case IPMI_MONITORING_SENSOR_TYPE_CRITICAL_INTERRUPT:
- return ("Critical Interrupt");
- case IPMI_MONITORING_SENSOR_TYPE_BUTTON_SWITCH:
- return ("Button/Switch");
- case IPMI_MONITORING_SENSOR_TYPE_MODULE_BOARD:
- return ("Module/Board");
- case IPMI_MONITORING_SENSOR_TYPE_MICROCONTROLLER_COPROCESSOR:
- return ("Microcontroller/Coprocessor");
- case IPMI_MONITORING_SENSOR_TYPE_ADD_IN_CARD:
- return ("Add In Card");
- case IPMI_MONITORING_SENSOR_TYPE_CHASSIS:
- return ("Chassis");
- case IPMI_MONITORING_SENSOR_TYPE_CHIP_SET:
- return ("Chip Set");
- case IPMI_MONITORING_SENSOR_TYPE_OTHER_FRU:
- return ("Other Fru");
- case IPMI_MONITORING_SENSOR_TYPE_CABLE_INTERCONNECT:
- return ("Cable/Interconnect");
- case IPMI_MONITORING_SENSOR_TYPE_TERMINATOR:
- return ("Terminator");
- case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_BOOT_INITIATED:
- return ("System Boot Initiated");
- case IPMI_MONITORING_SENSOR_TYPE_BOOT_ERROR:
- return ("Boot Error");
- case IPMI_MONITORING_SENSOR_TYPE_OS_BOOT:
- return ("OS Boot");
- case IPMI_MONITORING_SENSOR_TYPE_OS_CRITICAL_STOP:
- return ("OS Critical Stop");
- case IPMI_MONITORING_SENSOR_TYPE_SLOT_CONNECTOR:
- return ("Slot/Connector");
- case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE:
- return ("System ACPI Power State");
- case IPMI_MONITORING_SENSOR_TYPE_WATCHDOG2:
- return ("Watchdog 2");
- case IPMI_MONITORING_SENSOR_TYPE_PLATFORM_ALERT:
- return ("Platform Alert");
- case IPMI_MONITORING_SENSOR_TYPE_ENTITY_PRESENCE:
- return ("Entity Presence");
- case IPMI_MONITORING_SENSOR_TYPE_MONITOR_ASIC_IC:
- return ("Monitor ASIC/IC");
- case IPMI_MONITORING_SENSOR_TYPE_LAN:
- return ("LAN");
- case IPMI_MONITORING_SENSOR_TYPE_MANAGEMENT_SUBSYSTEM_HEALTH:
- return ("Management Subsystem Health");
- case IPMI_MONITORING_SENSOR_TYPE_BATTERY:
- return ("Battery");
- case IPMI_MONITORING_SENSOR_TYPE_SESSION_AUDIT:
- return ("Session Audit");
- case IPMI_MONITORING_SENSOR_TYPE_VERSION_CHANGE:
- return ("Version Change");
- case IPMI_MONITORING_SENSOR_TYPE_FRU_STATE:
- return ("FRU State");
- }
- return ("Unrecognized");
- }
- #endif // NETDATA_COMMENTED
- // ----------------------------------------------------------------------------
- // BEGIN NETDATA CODE
- static int debug = 0;
- static int netdata_update_every = 5; // this is the minimum update frequency
- static int netdata_priority = 90000;
- static int netdata_do_sel = 1;
- static size_t netdata_sensors_updated = 0;
- static size_t netdata_sensors_collected = 0;
- static size_t netdata_sel_events = 0;
- static size_t netdata_sensors_states_nominal = 0;
- static size_t netdata_sensors_states_warning = 0;
- static size_t netdata_sensors_states_critical = 0;
- struct sensor {
- int record_id;
- int sensor_number;
- int sensor_type;
- int sensor_state;
- int sensor_units;
- char *sensor_name;
- int sensor_reading_type;
- union {
- uint8_t bool_value;
- uint32_t uint32_value;
- double double_value;
- } sensor_reading;
- int sent;
- int ignore;
- int exposed;
- int updated;
- struct sensor *next;
- } *sensors_root = NULL;
- static void netdata_mark_as_not_updated() {
- struct sensor *sn;
- for(sn = sensors_root; sn ;sn = sn->next)
- sn->updated = sn->sent = 0;
- netdata_sensors_updated = 0;
- netdata_sensors_collected = 0;
- netdata_sel_events = 0;
- netdata_sensors_states_nominal = 0;
- netdata_sensors_states_warning = 0;
- netdata_sensors_states_critical = 0;
- }
- static void send_chart_to_netdata_for_units(int units) {
- struct sensor *sn, *sn_stored;
- int dupfound, multiplier;
- switch(units) {
- case IPMI_MONITORING_SENSOR_UNITS_CELSIUS:
- printf("CHART ipmi.temperatures_c '' 'System Celsius Temperatures read by IPMI' 'Celsius' 'temperatures' 'ipmi.temperatures_c' 'line' %d %d\n"
- , netdata_priority + 10
- , netdata_update_every
- );
- break;
- case IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT:
- printf("CHART ipmi.temperatures_f '' 'System Fahrenheit Temperatures read by IPMI' 'Fahrenheit' 'temperatures' 'ipmi.temperatures_f' 'line' %d %d\n"
- , netdata_priority + 11
- , netdata_update_every
- );
- break;
- case IPMI_MONITORING_SENSOR_UNITS_VOLTS:
- printf("CHART ipmi.volts '' 'System Voltages read by IPMI' 'Volts' 'voltages' 'ipmi.voltages' 'line' %d %d\n"
- , netdata_priority + 12
- , netdata_update_every
- );
- break;
- case IPMI_MONITORING_SENSOR_UNITS_AMPS:
- printf("CHART ipmi.amps '' 'System Current read by IPMI' 'Amps' 'current' 'ipmi.amps' 'line' %d %d\n"
- , netdata_priority + 13
- , netdata_update_every
- );
- break;
- case IPMI_MONITORING_SENSOR_UNITS_RPM:
- printf("CHART ipmi.rpm '' 'System Fans read by IPMI' 'RPM' 'fans' 'ipmi.rpm' 'line' %d %d\n"
- , netdata_priority + 14
- , netdata_update_every
- );
- break;
- case IPMI_MONITORING_SENSOR_UNITS_WATTS:
- printf("CHART ipmi.watts '' 'System Power read by IPMI' 'Watts' 'power' 'ipmi.watts' 'line' %d %d\n"
- , netdata_priority + 5
- , netdata_update_every
- );
- break;
- case IPMI_MONITORING_SENSOR_UNITS_PERCENT:
- printf("CHART ipmi.percent '' 'System Metrics read by IPMI' '%%' 'other' 'ipmi.percent' 'line' %d %d\n"
- , netdata_priority + 15
- , netdata_update_every
- );
- break;
- default:
- for(sn = sensors_root; sn; sn = sn->next)
- if(sn->sensor_units == units)
- sn->ignore = 1;
- return;
- }
- for(sn = sensors_root; sn; sn = sn->next) {
- dupfound = 0;
- if(sn->sensor_units == units && sn->updated && !sn->ignore) {
- sn->exposed = 1;
- multiplier = 1;
- switch(sn->sensor_reading_type) {
- case IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE:
- multiplier = 1000;
- // fallthrough
- case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL:
- case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32:
- for (sn_stored = sensors_root; sn_stored; sn_stored = sn_stored->next) {
- if (sn_stored == sn) continue;
- // If the name is a duplicate, append the sensor number
- if ( !strcmp(sn_stored->sensor_name, sn->sensor_name) ) {
- dupfound = 1;
- printf("DIMENSION i%d_n%d_r%d '%s i%d' absolute 1 %d\n"
- , sn->sensor_number
- , sn->record_id
- , sn->sensor_reading_type
- , sn->sensor_name
- , sn->sensor_number
- , multiplier
- );
- break;
- }
- }
- // No duplicate name was found, display it just with Name
- if (!dupfound) {
- // display without ID
- printf("DIMENSION i%d_n%d_r%d '%s' absolute 1 %d\n"
- , sn->sensor_number
- , sn->record_id
- , sn->sensor_reading_type
- , sn->sensor_name
- , multiplier
- );
- }
- break;
- default:
- sn->ignore = 1;
- break;
- }
- }
- }
- }
- static void send_metrics_to_netdata_for_units(int units) {
- struct sensor *sn;
- switch(units) {
- case IPMI_MONITORING_SENSOR_UNITS_CELSIUS:
- printf("BEGIN ipmi.temperatures_c\n");
- break;
- case IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT:
- printf("BEGIN ipmi.temperatures_f\n");
- break;
- case IPMI_MONITORING_SENSOR_UNITS_VOLTS:
- printf("BEGIN ipmi.volts\n");
- break;
- case IPMI_MONITORING_SENSOR_UNITS_AMPS:
- printf("BEGIN ipmi.amps\n");
- break;
- case IPMI_MONITORING_SENSOR_UNITS_RPM:
- printf("BEGIN ipmi.rpm\n");
- break;
- case IPMI_MONITORING_SENSOR_UNITS_WATTS:
- printf("BEGIN ipmi.watts\n");
- break;
- case IPMI_MONITORING_SENSOR_UNITS_PERCENT:
- printf("BEGIN ipmi.percent\n");
- break;
- default:
- for(sn = sensors_root; sn; sn = sn->next)
- if(sn->sensor_units == units)
- sn->ignore = 1;
- return;
- }
- for(sn = sensors_root; sn; sn = sn->next) {
- if(sn->sensor_units == units && sn->updated && !sn->sent && !sn->ignore) {
- netdata_sensors_updated++;
- sn->sent = 1;
- switch(sn->sensor_reading_type) {
- case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL:
- printf("SET i%d_n%d_r%d = %u\n"
- , sn->sensor_number
- , sn->record_id
- , sn->sensor_reading_type
- , sn->sensor_reading.bool_value
- );
- break;
- case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32:
- printf("SET i%d_n%d_r%d = %u\n"
- , sn->sensor_number
- , sn->record_id
- , sn->sensor_reading_type
- , sn->sensor_reading.uint32_value
- );
- break;
- case IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE:
- printf("SET i%d_n%d_r%d = %lld\n"
- , sn->sensor_number
- , sn->record_id
- , sn->sensor_reading_type
- , (long long int)(sn->sensor_reading.double_value * 1000)
- );
- break;
- default:
- sn->ignore = 1;
- break;
- }
- }
- }
- printf("END\n");
- }
- static void send_metrics_to_netdata() {
- static int sel_chart_generated = 0, sensors_states_chart_generated = 0;
- struct sensor *sn;
- if(netdata_do_sel && !sel_chart_generated) {
- sel_chart_generated = 1;
- printf("CHART ipmi.events '' 'IPMI Events' 'events' 'events' ipmi.sel area %d %d\n"
- , netdata_priority + 2
- , netdata_update_every
- );
- printf("DIMENSION events '' absolute 1 1\n");
- }
- if(!sensors_states_chart_generated) {
- sensors_states_chart_generated = 1;
- printf("CHART ipmi.sensors_states '' 'IPMI Sensors State' 'sensors' 'states' ipmi.sensors_states line %d %d\n"
- , netdata_priority + 1
- , netdata_update_every
- );
- printf("DIMENSION nominal '' absolute 1 1\n");
- printf("DIMENSION critical '' absolute 1 1\n");
- printf("DIMENSION warning '' absolute 1 1\n");
- }
- // generate the CHART/DIMENSION lines, if we have to
- for(sn = sensors_root; sn; sn = sn->next)
- if(sn->updated && !sn->exposed && !sn->ignore)
- send_chart_to_netdata_for_units(sn->sensor_units);
- if(netdata_do_sel) {
- printf(
- "BEGIN ipmi.events\n"
- "SET events = %zu\n"
- "END\n"
- , netdata_sel_events
- );
- }
- printf(
- "BEGIN ipmi.sensors_states\n"
- "SET nominal = %zu\n"
- "SET warning = %zu\n"
- "SET critical = %zu\n"
- "END\n"
- , netdata_sensors_states_nominal
- , netdata_sensors_states_warning
- , netdata_sensors_states_critical
- );
- // send metrics to netdata
- for(sn = sensors_root; sn; sn = sn->next)
- if(sn->updated && sn->exposed && !sn->sent && !sn->ignore)
- send_metrics_to_netdata_for_units(sn->sensor_units);
- }
- static int *excluded_record_ids = NULL;
- size_t excluded_record_ids_length = 0;
- static void excluded_record_ids_parse(const char *s) {
- if(!s) return;
- while(*s) {
- while(*s && !isdigit(*s)) s++;
- if(isdigit(*s)) {
- char *e;
- unsigned long n = strtoul(s, &e, 10);
- s = e;
- if(n != 0) {
- excluded_record_ids = realloc(excluded_record_ids, (excluded_record_ids_length + 1) * sizeof(int));
- if(!excluded_record_ids) {
- fprintf(stderr, "freeipmi.plugin: failed to allocate memory. Exiting.");
- exit(1);
- }
- excluded_record_ids[excluded_record_ids_length++] = (int)n;
- }
- }
- }
- if(debug) {
- fprintf(stderr, "freeipmi.plugin: excluded record ids:");
- size_t i;
- for(i = 0; i < excluded_record_ids_length; i++) {
- fprintf(stderr, " %d", excluded_record_ids[i]);
- }
- fprintf(stderr, "\n");
- }
- }
- static int *excluded_status_record_ids = NULL;
- size_t excluded_status_record_ids_length = 0;
- static void excluded_status_record_ids_parse(const char *s) {
- if(!s) return;
- while(*s) {
- while(*s && !isdigit(*s)) s++;
- if(isdigit(*s)) {
- char *e;
- unsigned long n = strtoul(s, &e, 10);
- s = e;
- if(n != 0) {
- excluded_status_record_ids = realloc(excluded_status_record_ids, (excluded_status_record_ids_length + 1) * sizeof(int));
- if(!excluded_status_record_ids) {
- fprintf(stderr, "freeipmi.plugin: failed to allocate memory. Exiting.");
- exit(1);
- }
- excluded_status_record_ids[excluded_status_record_ids_length++] = (int)n;
- }
- }
- }
- if(debug) {
- fprintf(stderr, "freeipmi.plugin: excluded status record ids:");
- size_t i;
- for(i = 0; i < excluded_status_record_ids_length; i++) {
- fprintf(stderr, " %d", excluded_status_record_ids[i]);
- }
- fprintf(stderr, "\n");
- }
- }
- static int excluded_record_ids_check(int record_id) {
- size_t i;
- for(i = 0; i < excluded_record_ids_length; i++) {
- if(excluded_record_ids[i] == record_id)
- return 1;
- }
- return 0;
- }
- static int excluded_status_record_ids_check(int record_id) {
- size_t i;
- for(i = 0; i < excluded_status_record_ids_length; i++) {
- if(excluded_status_record_ids[i] == record_id)
- return 1;
- }
- return 0;
- }
- static void netdata_get_sensor(
- int record_id
- , int sensor_number
- , int sensor_type
- , int sensor_state
- , int sensor_units
- , int sensor_reading_type
- , char *sensor_name
- , void *sensor_reading
- ) {
- // find the sensor record
- struct sensor *sn;
- for(sn = sensors_root; sn ;sn = sn->next)
- if( sn->record_id == record_id &&
- sn->sensor_number == sensor_number &&
- sn->sensor_reading_type == sensor_reading_type &&
- sn->sensor_units == sensor_units &&
- !strcmp(sn->sensor_name, sensor_name)
- )
- break;
- if(!sn) {
- // not found, create it
- // check if it is excluded
- if(excluded_record_ids_check(record_id)) {
- if(debug) fprintf(stderr, "Sensor '%s' is excluded by excluded_record_ids_check()\n", sensor_name);
- return;
- }
- if(debug) fprintf(stderr, "Allocating new sensor data record for sensor '%s', id %d, number %d, type %d, state %d, units %d, reading_type %d\n", sensor_name, record_id, sensor_number, sensor_type, sensor_state, sensor_units, sensor_reading_type);
- sn = calloc(1, sizeof(struct sensor));
- if(!sn) {
- fatal("cannot allocate %zu bytes of memory.", sizeof(struct sensor));
- }
- sn->record_id = record_id;
- sn->sensor_number = sensor_number;
- sn->sensor_type = sensor_type;
- sn->sensor_state = sensor_state;
- sn->sensor_units = sensor_units;
- sn->sensor_reading_type = sensor_reading_type;
- sn->sensor_name = strdup(sensor_name);
- if(!sn->sensor_name) {
- fatal("cannot allocate %zu bytes of memory.", strlen(sensor_name));
- }
- sn->next = sensors_root;
- sensors_root = sn;
- }
- else {
- if(debug) fprintf(stderr, "Reusing sensor record for sensor '%s', id %d, number %d, type %d, state %d, units %d, reading_type %d\n", sensor_name, record_id, sensor_number, sensor_type, sensor_state, sensor_units, sensor_reading_type);
- }
- switch(sensor_reading_type) {
- case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL:
- sn->sensor_reading.bool_value = *((uint8_t *)sensor_reading);
- sn->updated = 1;
- netdata_sensors_collected++;
- break;
- case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32:
- sn->sensor_reading.uint32_value = *((uint32_t *)sensor_reading);
- sn->updated = 1;
- netdata_sensors_collected++;
- break;
- case IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE:
- sn->sensor_reading.double_value = *((double *)sensor_reading);
- sn->updated = 1;
- netdata_sensors_collected++;
- break;
- default:
- if(debug) fprintf(stderr, "Unknown reading type - Ignoring sensor record for sensor '%s', id %d, number %d, type %d, state %d, units %d, reading_type %d\n", sensor_name, record_id, sensor_number, sensor_type, sensor_state, sensor_units, sensor_reading_type);
- sn->ignore = 1;
- break;
- }
- // check if it is excluded
- if(excluded_status_record_ids_check(record_id)) {
- if(debug) fprintf(stderr, "Sensor '%s' is excluded for status check, by excluded_status_record_ids_check()\n", sensor_name);
- return;
- }
- switch(sensor_state) {
- case IPMI_MONITORING_STATE_NOMINAL:
- netdata_sensors_states_nominal++;
- break;
- case IPMI_MONITORING_STATE_WARNING:
- netdata_sensors_states_warning++;
- break;
- case IPMI_MONITORING_STATE_CRITICAL:
- netdata_sensors_states_critical++;
- break;
- default:
- break;
- }
- }
- static void netdata_get_sel(
- int record_id
- , int record_type_class
- , int sel_state
- ) {
- (void)record_id;
- (void)record_type_class;
- (void)sel_state;
- netdata_sel_events++;
- }
- // END NETDATA CODE
- // ----------------------------------------------------------------------------
- static int
- _ipmimonitoring_sensors (struct ipmi_monitoring_ipmi_config *ipmi_config)
- {
- ipmi_monitoring_ctx_t ctx = NULL;
- unsigned int sensor_reading_flags = 0;
- int i;
- int sensor_count;
- int rv = -1;
- if (!(ctx = ipmi_monitoring_ctx_create ())) {
- collector_error("ipmi_monitoring_ctx_create()");
- goto cleanup;
- }
- if (sdr_cache_directory)
- {
- if (ipmi_monitoring_ctx_sdr_cache_directory (ctx,
- sdr_cache_directory) < 0)
- {
- collector_error("ipmi_monitoring_ctx_sdr_cache_directory(): %s\n",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- /* Must call otherwise only default interpretations ever used */
- if (sensor_config_file)
- {
- if (ipmi_monitoring_ctx_sensor_config_file (ctx,
- sensor_config_file) < 0)
- {
- collector_error( "ipmi_monitoring_ctx_sensor_config_file(): %s\n",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- else
- {
- if (ipmi_monitoring_ctx_sensor_config_file (ctx, NULL) < 0)
- {
- collector_error( "ipmi_monitoring_ctx_sensor_config_file(): %s\n",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- if (reread_sdr_cache)
- sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_REREAD_SDR_CACHE;
- if (ignore_non_interpretable_sensors)
- sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_IGNORE_NON_INTERPRETABLE_SENSORS;
- if (bridge_sensors)
- sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_BRIDGE_SENSORS;
- if (interpret_oem_data)
- sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_INTERPRET_OEM_DATA;
- if (shared_sensors)
- sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_SHARED_SENSORS;
- if (discrete_reading)
- sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_DISCRETE_READING;
- if (ignore_scanning_disabled)
- sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_IGNORE_SCANNING_DISABLED;
- if (assume_bmc_owner)
- sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_ASSUME_BMC_OWNER;
- #ifdef IPMI_MONITORING_SENSOR_READING_FLAGS_ENTITY_SENSOR_NAMES
- if (entity_sensor_names)
- sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_ENTITY_SENSOR_NAMES;
- #endif // IPMI_MONITORING_SENSOR_READING_FLAGS_ENTITY_SENSOR_NAMES
- if (!record_ids_length && !sensor_types_length)
- {
- if ((sensor_count = ipmi_monitoring_sensor_readings_by_record_id (ctx,
- hostname,
- ipmi_config,
- sensor_reading_flags,
- NULL,
- 0,
- NULL,
- NULL)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_readings_by_record_id(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- else if (record_ids_length)
- {
- if ((sensor_count = ipmi_monitoring_sensor_readings_by_record_id (ctx,
- hostname,
- ipmi_config,
- sensor_reading_flags,
- record_ids,
- record_ids_length,
- NULL,
- NULL)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_readings_by_record_id(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- else
- {
- if ((sensor_count = ipmi_monitoring_sensor_readings_by_sensor_type (ctx,
- hostname,
- ipmi_config,
- sensor_reading_flags,
- sensor_types,
- sensor_types_length,
- NULL,
- NULL)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_readings_by_sensor_type(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- #ifdef NETDATA_COMMENTED
- printf ("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
- "Record ID",
- "Sensor Name",
- "Sensor Number",
- "Sensor Type",
- "Sensor State",
- "Sensor Reading",
- "Sensor Units",
- "Sensor Event/Reading Type Code",
- "Sensor Event Bitmask",
- "Sensor Event String");
- #endif // NETDATA_COMMENTED
- for (i = 0; i < sensor_count; i++, ipmi_monitoring_sensor_iterator_next (ctx))
- {
- int record_id, sensor_number, sensor_type, sensor_state, sensor_units,
- sensor_reading_type;
- #ifdef NETDATA_COMMENTED
- int sensor_bitmask_type, sensor_bitmask, event_reading_type_code;
- char **sensor_bitmask_strings = NULL;
- const char *sensor_type_str;
- const char *sensor_state_str;
- #endif // NETDATA_COMMENTED
- char *sensor_name = NULL;
- void *sensor_reading;
- if ((record_id = ipmi_monitoring_sensor_read_record_id (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_read_record_id(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((sensor_number = ipmi_monitoring_sensor_read_sensor_number (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_read_sensor_number(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((sensor_type = ipmi_monitoring_sensor_read_sensor_type (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_read_sensor_type(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if (!(sensor_name = ipmi_monitoring_sensor_read_sensor_name (ctx)))
- {
- collector_error( "ipmi_monitoring_sensor_read_sensor_name(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((sensor_state = ipmi_monitoring_sensor_read_sensor_state (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_read_sensor_state(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((sensor_units = ipmi_monitoring_sensor_read_sensor_units (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_read_sensor_units(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- #ifdef NETDATA_COMMENTED
- if ((sensor_bitmask_type = ipmi_monitoring_sensor_read_sensor_bitmask_type (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_read_sensor_bitmask_type(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((sensor_bitmask = ipmi_monitoring_sensor_read_sensor_bitmask (ctx)) < 0)
- {
- collector_error("ipmi_monitoring_sensor_read_sensor_bitmask(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- /* it's ok for this to be NULL, i.e. sensor_bitmask ==
- * IPMI_MONITORING_SENSOR_BITMASK_TYPE_UNKNOWN
- */
- sensor_bitmask_strings = ipmi_monitoring_sensor_read_sensor_bitmask_strings (ctx);
-
-
-
- #endif // NETDATA_COMMENTED
- if ((sensor_reading_type = ipmi_monitoring_sensor_read_sensor_reading_type (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_read_sensor_reading_type(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- sensor_reading = ipmi_monitoring_sensor_read_sensor_reading (ctx);
- #ifdef NETDATA_COMMENTED
- if ((event_reading_type_code = ipmi_monitoring_sensor_read_event_reading_type_code (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sensor_read_event_reading_type_code(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- #endif // NETDATA_COMMENTED
- netdata_get_sensor(
- record_id
- , sensor_number
- , sensor_type
- , sensor_state
- , sensor_units
- , sensor_reading_type
- , sensor_name
- , sensor_reading
- );
- #ifdef NETDATA_COMMENTED
- if (!strlen (sensor_name))
- sensor_name = "N/A";
- sensor_type_str = _get_sensor_type_string (sensor_type);
- printf ("%d, %s, %d, %s",
- record_id,
- sensor_name,
- sensor_number,
- sensor_type_str);
- if (sensor_state == IPMI_MONITORING_STATE_NOMINAL)
- sensor_state_str = "Nominal";
- else if (sensor_state == IPMI_MONITORING_STATE_WARNING)
- sensor_state_str = "Warning";
- else if (sensor_state == IPMI_MONITORING_STATE_CRITICAL)
- sensor_state_str = "Critical";
- else
- sensor_state_str = "N/A";
- printf (", %s", sensor_state_str);
- if (sensor_reading)
- {
- const char *sensor_units_str;
- if (sensor_reading_type == IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL)
- printf (", %s",
- (*((uint8_t *)sensor_reading) ? "true" : "false"));
- else if (sensor_reading_type == IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32)
- printf (", %u",
- *((uint32_t *)sensor_reading));
- else if (sensor_reading_type == IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE)
- printf (", %.2f",
- *((double *)sensor_reading));
- else
- printf (", N/A");
- if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_CELSIUS)
- sensor_units_str = "C";
- else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT)
- sensor_units_str = "F";
- else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_VOLTS)
- sensor_units_str = "V";
- else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_AMPS)
- sensor_units_str = "A";
- else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_RPM)
- sensor_units_str = "RPM";
- else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_WATTS)
- sensor_units_str = "W";
- else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_PERCENT)
- sensor_units_str = "%";
- else
- sensor_units_str = "N/A";
- printf (", %s", sensor_units_str);
- }
- else
- printf (", N/A, N/A");
- printf (", %Xh", event_reading_type_code);
- /* It is possible you may want to monitor specific event
- * conditions that may occur. If that is the case, you may want
- * to check out what specific bitmask type and bitmask events
- * occurred. See ipmi_monitoring_bitmasks.h for a list of
- * bitmasks and types.
- */
- if (sensor_bitmask_type != IPMI_MONITORING_SENSOR_BITMASK_TYPE_UNKNOWN)
- printf (", %Xh", sensor_bitmask);
- else
- printf (", N/A");
- if (sensor_bitmask_type != IPMI_MONITORING_SENSOR_BITMASK_TYPE_UNKNOWN
- && sensor_bitmask_strings)
- {
- unsigned int i = 0;
- printf (",");
- while (sensor_bitmask_strings[i])
- {
- printf (" ");
- printf ("'%s'",
- sensor_bitmask_strings[i]);
- i++;
- }
- }
- else
- printf (", N/A");
- printf ("\n");
- #endif // NETDATA_COMMENTED
- }
- rv = 0;
- cleanup:
- if (ctx)
- ipmi_monitoring_ctx_destroy (ctx);
- return (rv);
- }
- static int
- _ipmimonitoring_sel (struct ipmi_monitoring_ipmi_config *ipmi_config)
- {
- ipmi_monitoring_ctx_t ctx = NULL;
- unsigned int sel_flags = 0;
- int i;
- int sel_count;
- int rv = -1;
- if (!(ctx = ipmi_monitoring_ctx_create ()))
- {
- collector_error("ipmi_monitoring_ctx_create()");
- goto cleanup;
- }
- if (sdr_cache_directory)
- {
- if (ipmi_monitoring_ctx_sdr_cache_directory (ctx,
- sdr_cache_directory) < 0)
- {
- collector_error( "ipmi_monitoring_ctx_sdr_cache_directory(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- /* Must call otherwise only default interpretations ever used */
- if (sel_config_file)
- {
- if (ipmi_monitoring_ctx_sel_config_file (ctx,
- sel_config_file) < 0)
- {
- collector_error( "ipmi_monitoring_ctx_sel_config_file(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- else
- {
- if (ipmi_monitoring_ctx_sel_config_file (ctx, NULL) < 0)
- {
- collector_error( "ipmi_monitoring_ctx_sel_config_file(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- if (reread_sdr_cache)
- sel_flags |= IPMI_MONITORING_SEL_FLAGS_REREAD_SDR_CACHE;
- if (interpret_oem_data)
- sel_flags |= IPMI_MONITORING_SEL_FLAGS_INTERPRET_OEM_DATA;
- if (assume_system_event_record)
- sel_flags |= IPMI_MONITORING_SEL_FLAGS_ASSUME_SYSTEM_EVENT_RECORD;
- #ifdef IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES
- if (entity_sensor_names)
- sel_flags |= IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES;
- #endif // IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES
- if (record_ids_length)
- {
- if ((sel_count = ipmi_monitoring_sel_by_record_id (ctx,
- hostname,
- ipmi_config,
- sel_flags,
- record_ids,
- record_ids_length,
- NULL,
- NULL)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_by_record_id(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- else if (sensor_types_length)
- {
- if ((sel_count = ipmi_monitoring_sel_by_sensor_type (ctx,
- hostname,
- ipmi_config,
- sel_flags,
- sensor_types,
- sensor_types_length,
- NULL,
- NULL)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_by_sensor_type(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- else if (date_begin
- || date_end)
- {
- if ((sel_count = ipmi_monitoring_sel_by_date_range (ctx,
- hostname,
- ipmi_config,
- sel_flags,
- date_begin,
- date_end,
- NULL,
- NULL)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_by_sensor_type(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- else
- {
- if ((sel_count = ipmi_monitoring_sel_by_record_id (ctx,
- hostname,
- ipmi_config,
- sel_flags,
- NULL,
- 0,
- NULL,
- NULL)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_by_record_id(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- }
- #ifdef NETDATA_COMMENTED
- printf ("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
- "Record ID",
- "Record Type",
- "SEL State",
- "Timestamp",
- "Sensor Name",
- "Sensor Type",
- "Event Direction",
- "Event Type Code",
- "Event Data",
- "Event Offset",
- "Event Offset String");
- #endif // NETDATA_COMMENTED
- for (i = 0; i < sel_count; i++, ipmi_monitoring_sel_iterator_next (ctx))
- {
- int record_id, record_type, sel_state, record_type_class;
- #ifdef NETDATA_COMMENTED
- int sensor_type, sensor_number, event_direction,
- event_offset_type, event_offset, event_type_code, manufacturer_id;
- unsigned int timestamp, event_data1, event_data2, event_data3;
- char *event_offset_string = NULL;
- const char *sensor_type_str;
- const char *event_direction_str;
- const char *sel_state_str;
- char *sensor_name = NULL;
- unsigned char oem_data[64];
- int oem_data_len;
- unsigned int j;
- #endif // NETDATA_COMMENTED
- if ((record_id = ipmi_monitoring_sel_read_record_id (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_record_id(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((record_type = ipmi_monitoring_sel_read_record_type (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_record_type(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((record_type_class = ipmi_monitoring_sel_read_record_type_class (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_record_type_class(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((sel_state = ipmi_monitoring_sel_read_sel_state (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_sel_state(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- netdata_get_sel(
- record_id
- , record_type_class
- , sel_state
- );
- #ifdef NETDATA_COMMENTED
- if (sel_state == IPMI_MONITORING_STATE_NOMINAL)
- sel_state_str = "Nominal";
- else if (sel_state == IPMI_MONITORING_STATE_WARNING)
- sel_state_str = "Warning";
- else if (sel_state == IPMI_MONITORING_STATE_CRITICAL)
- sel_state_str = "Critical";
- else
- sel_state_str = "N/A";
- printf ("%d, %d, %s",
- record_id,
- record_type,
- sel_state_str);
- if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD
- || record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD)
- {
- if (ipmi_monitoring_sel_read_timestamp (ctx, ×tamp) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_timestamp(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- /* XXX: This should be converted to a nice date output using
- * your favorite timestamp -> string conversion functions.
- */
- printf (", %u", timestamp);
- }
- else
- printf (", N/A");
- if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD)
- {
- /* If you are integrating ipmimonitoring SEL into a monitoring application,
- * you may wish to count the number of times a specific error occurred
- * and report that to the monitoring application.
- *
- * In this particular case, you'll probably want to check out
- * what sensor type each SEL event is reporting, the
- * event offset type, and the specific event offset that occurred.
- *
- * See ipmi_monitoring_offsets.h for a list of event offsets
- * and types.
- */
- if (!(sensor_name = ipmi_monitoring_sel_read_sensor_name (ctx)))
- {
- collector_error( "ipmi_monitoring_sel_read_sensor_name(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((sensor_type = ipmi_monitoring_sel_read_sensor_type (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_sensor_type(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((sensor_number = ipmi_monitoring_sel_read_sensor_number (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_sensor_number(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((event_direction = ipmi_monitoring_sel_read_event_direction (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_event_direction(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((event_type_code = ipmi_monitoring_sel_read_event_type_code (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_event_type_code(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if (ipmi_monitoring_sel_read_event_data (ctx,
- &event_data1,
- &event_data2,
- &event_data3) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_event_data(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((event_offset_type = ipmi_monitoring_sel_read_event_offset_type (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_event_offset_type(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if ((event_offset = ipmi_monitoring_sel_read_event_offset (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_event_offset(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if (!(event_offset_string = ipmi_monitoring_sel_read_event_offset_string (ctx)))
- {
- collector_error( "ipmi_monitoring_sel_read_event_offset_string(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- if (!strlen (sensor_name))
- sensor_name = "N/A";
- sensor_type_str = _get_sensor_type_string (sensor_type);
- if (event_direction == IPMI_MONITORING_SEL_EVENT_DIRECTION_ASSERTION)
- event_direction_str = "Assertion";
- else
- event_direction_str = "Deassertion";
- printf (", %s, %s, %d, %s, %Xh, %Xh-%Xh-%Xh",
- sensor_name,
- sensor_type_str,
- sensor_number,
- event_direction_str,
- event_type_code,
- event_data1,
- event_data2,
- event_data3);
- if (event_offset_type != IPMI_MONITORING_EVENT_OFFSET_TYPE_UNKNOWN)
- printf (", %Xh", event_offset);
- else
- printf (", N/A");
- if (event_offset_type != IPMI_MONITORING_EVENT_OFFSET_TYPE_UNKNOWN)
- printf (", %s", event_offset_string);
- else
- printf (", N/A");
- }
- else if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD
- || record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_NON_TIMESTAMPED_OEM_RECORD)
- {
- if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD)
- {
- if ((manufacturer_id = ipmi_monitoring_sel_read_manufacturer_id (ctx)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_manufacturer_id(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- printf (", Manufacturer ID = %Xh", manufacturer_id);
- }
- if ((oem_data_len = ipmi_monitoring_sel_read_oem_data (ctx, oem_data, 1024)) < 0)
- {
- collector_error( "ipmi_monitoring_sel_read_oem_data(): %s",
- ipmi_monitoring_ctx_errormsg (ctx));
- goto cleanup;
- }
- printf (", OEM Data = ");
- for (j = 0; j < oem_data_len; j++)
- printf ("%02Xh ", oem_data[j]);
- }
- else
- printf (", N/A, N/A, N/A, N/A, N/A, N/A, N/A");
- printf ("\n");
- #endif // NETDATA_COMMENTED
- }
- rv = 0;
- cleanup:
- if (ctx)
- ipmi_monitoring_ctx_destroy (ctx);
- return (rv);
- }
- // ----------------------------------------------------------------------------
- // MAIN PROGRAM FOR NETDATA PLUGIN
- int ipmi_collect_data(struct ipmi_monitoring_ipmi_config *ipmi_config) {
- errno = 0;
- if (_ipmimonitoring_sensors(ipmi_config) < 0) return -1;
- if(netdata_do_sel) {
- if(_ipmimonitoring_sel(ipmi_config) < 0) return -2;
- }
- return 0;
- }
- int ipmi_detect_speed_secs(struct ipmi_monitoring_ipmi_config *ipmi_config) {
- int i, checks = 10;
- unsigned long long total = 0;
- for(i = 0 ; i < checks ; i++) {
- if(debug) fprintf(stderr, "freeipmi.plugin: checking data collection speed iteration %d of %d\n", i+1, checks);
- // measure the time a data collection needs
- unsigned long long start = now_realtime_usec();
- if(ipmi_collect_data(ipmi_config) < 0)
- fatal("freeipmi.plugin: data collection failed.");
- unsigned long long end = now_realtime_usec();
- if(debug) fprintf(stderr, "freeipmi.plugin: data collection speed was %llu usec\n", end - start);
- // add it to our total
- total += end - start;
- // wait the same time
- // to avoid flooding the IPMI processor with requests
- sleep_usec(end - start);
- }
- // so, we assume it needed 2x the time
- // we find the average in microseconds
- // and we round-up to the closest second
- return (int)(( total * 2 / checks / 1000000 ) + 1);
- }
- int parse_inband_driver_type (const char *str)
- {
- fatal_assert(str);
- if (strcasecmp (str, IPMI_PARSE_DEVICE_KCS_STR) == 0)
- return (IPMI_MONITORING_DRIVER_TYPE_KCS);
- else if (strcasecmp (str, IPMI_PARSE_DEVICE_SSIF_STR) == 0)
- return (IPMI_MONITORING_DRIVER_TYPE_SSIF);
- /* support "open" for those that might be used to
- * ipmitool.
- */
- else if (strcasecmp (str, IPMI_PARSE_DEVICE_OPENIPMI_STR) == 0
- || strcasecmp (str, IPMI_PARSE_DEVICE_OPENIPMI_STR2) == 0)
- return (IPMI_MONITORING_DRIVER_TYPE_OPENIPMI);
- /* support "bmc" for those that might be used to
- * ipmitool.
- */
- else if (strcasecmp (str, IPMI_PARSE_DEVICE_SUNBMC_STR) == 0
- || strcasecmp (str, IPMI_PARSE_DEVICE_SUNBMC_STR2) == 0)
- return (IPMI_MONITORING_DRIVER_TYPE_SUNBMC);
- return (-1);
- }
- int parse_outofband_driver_type (const char *str)
- {
- fatal_assert(str);
- if (strcasecmp (str, IPMI_PARSE_DEVICE_LAN_STR) == 0)
- return (IPMI_MONITORING_PROTOCOL_VERSION_1_5);
- /* support "lanplus" for those that might be used to ipmitool.
- * support typo variants to ease.
- */
- else if (strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR) == 0
- || strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR2) == 0
- || strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR3) == 0
- || strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR4) == 0
- || strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR5) == 0)
- return (IPMI_MONITORING_PROTOCOL_VERSION_2_0);
- return (-1);
- }
- int host_is_local(const char *host)
- {
- if (host && (!strcmp(host, "localhost") || !strcmp(host, "127.0.0.1") || !strcmp(host, "::1")))
- return (1);
- return (0);
- }
- int main (int argc, char **argv) {
- stderror = stderr;
- clocks_init();
- // ------------------------------------------------------------------------
- // initialization of netdata plugin
- program_name = "freeipmi.plugin";
- // disable syslog
- error_log_syslog = 0;
- // set errors flood protection to 100 logs per hour
- error_log_errors_per_period = 100;
- error_log_throttle_period = 3600;
- // ------------------------------------------------------------------------
- // parse command line parameters
- int i, freq = 0;
- for(i = 1; i < argc ; i++) {
- if(isdigit(*argv[i]) && !freq) {
- int n = str2i(argv[i]);
- if(n > 0 && n < 86400) {
- freq = n;
- continue;
- }
- }
- else if(strcmp("version", argv[i]) == 0 || strcmp("-version", argv[i]) == 0 || strcmp("--version", argv[i]) == 0 || strcmp("-v", argv[i]) == 0 || strcmp("-V", argv[i]) == 0) {
- printf("freeipmi.plugin %s\n", VERSION);
- exit(0);
- }
- else if(strcmp("debug", argv[i]) == 0) {
- debug = 1;
- continue;
- }
- else if(strcmp("sel", argv[i]) == 0) {
- netdata_do_sel = 1;
- continue;
- }
- else if(strcmp("no-sel", argv[i]) == 0) {
- netdata_do_sel = 0;
- continue;
- }
- else if(strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
- fprintf(stderr,
- "\n"
- " netdata freeipmi.plugin %s\n"
- " Copyright (C) 2016-2017 Costa Tsaousis <costa@tsaousis.gr>\n"
- " Released under GNU General Public License v3 or later.\n"
- " All rights reserved.\n"
- "\n"
- " This program is a data collector plugin for netdata.\n"
- "\n"
- " Available command line options:\n"
- "\n"
- " SECONDS data collection frequency\n"
- " minimum: %d\n"
- "\n"
- " debug enable verbose output\n"
- " default: disabled\n"
- "\n"
- " sel\n"
- " no-sel enable/disable SEL collection\n"
- " default: %s\n"
- "\n"
- " hostname HOST\n"
- " username USER\n"
- " password PASS connect to remote IPMI host\n"
- " default: local IPMI processor\n"
- "\n"
- " noauthcodecheck don't check the authentication codes returned\n"
- "\n"
- " driver-type IPMIDRIVER\n"
- " Specify the driver type to use instead of doing an auto selection. \n"
- " The currently available outofband drivers are LAN and LAN_2_0,\n"
- " which perform IPMI 1.5 and IPMI 2.0 respectively. \n"
- " The currently available inband drivers are KCS, SSIF, OPENIPMI and SUNBMC.\n"
- "\n"
- " sdr-cache-dir PATH directory for SDR cache files\n"
- " default: %s\n"
- "\n"
- " sensor-config-file FILE filename to read sensor configuration\n"
- " default: %s\n"
- "\n"
- " ignore N1,N2,N3,... sensor IDs to ignore\n"
- " default: none\n"
- "\n"
- " ignore-status N1,N2,N3,... sensor IDs to ignore status (nominal/warning/critical)\n"
- " default: none\n"
- "\n"
- " -v\n"
- " -V\n"
- " version print version and exit\n"
- "\n"
- " Linux kernel module for IPMI is CPU hungry.\n"
- " On Linux run this to lower kipmiN CPU utilization:\n"
- " # echo 10 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us\n"
- "\n"
- " or create: /etc/modprobe.d/ipmi.conf with these contents:\n"
- " options ipmi_si kipmid_max_busy_us=10\n"
- "\n"
- " For more information:\n"
- " https://github.com/netdata/netdata/tree/master/collectors/freeipmi.plugin\n"
- "\n"
- , VERSION
- , netdata_update_every
- , netdata_do_sel?"enabled":"disabled"
- , sdr_cache_directory?sdr_cache_directory:"system default"
- , sensor_config_file?sensor_config_file:"system default"
- );
- exit(1);
- }
- else if(i < argc && strcmp("hostname", argv[i]) == 0) {
- hostname = strdupz(argv[++i]);
- char *s = argv[i];
- // mask it be hidden from the process tree
- while(*s) *s++ = 'x';
- if(debug) fprintf(stderr, "freeipmi.plugin: hostname set to '%s'\n", hostname);
- continue;
- }
- else if(i < argc && strcmp("username", argv[i]) == 0) {
- username = strdupz(argv[++i]);
- char *s = argv[i];
- // mask it be hidden from the process tree
- while(*s) *s++ = 'x';
- if(debug) fprintf(stderr, "freeipmi.plugin: username set to '%s'\n", username);
- continue;
- }
- else if(i < argc && strcmp("password", argv[i]) == 0) {
- password = strdupz(argv[++i]);
- char *s = argv[i];
- // mask it be hidden from the process tree
- while(*s) *s++ = 'x';
- if(debug) fprintf(stderr, "freeipmi.plugin: password set to '%s'\n", password);
- continue;
- }
- else if(strcmp("driver-type", argv[i]) == 0) {
- if (hostname) {
- protocol_version=parse_outofband_driver_type(argv[++i]);
- if(debug) fprintf(stderr, "freeipmi.plugin: outband protocol version set to '%d'\n", protocol_version);
- }
- else {
- driver_type=parse_inband_driver_type(argv[++i]);
- if(debug) fprintf(stderr, "freeipmi.plugin: inband driver type set to '%d'\n", driver_type);
- }
- continue;
- } else if (i < argc && strcmp("noauthcodecheck", argv[i]) == 0) {
- if (!hostname || host_is_local(hostname)) {
- if (debug)
- fprintf(
- stderr,
- "freeipmi.plugin: noauthcodecheck workaround flag is ignored for inband configuration\n");
- } else if (protocol_version < 0 || protocol_version == IPMI_MONITORING_PROTOCOL_VERSION_1_5) {
- workaround_flags |= IPMI_MONITORING_WORKAROUND_FLAGS_PROTOCOL_VERSION_1_5_NO_AUTH_CODE_CHECK;
- if (debug)
- fprintf(stderr, "freeipmi.plugin: noauthcodecheck workaround flag enabled\n");
- } else {
- if (debug)
- fprintf(
- stderr,
- "freeipmi.plugin: noauthcodecheck workaround flag is ignored for protocol version 2.0\n");
- }
- continue;
- }
- else if(i < argc && strcmp("sdr-cache-dir", argv[i]) == 0) {
- sdr_cache_directory = argv[++i];
- if(debug) fprintf(stderr, "freeipmi.plugin: SDR cache directory set to '%s'\n", sdr_cache_directory);
- continue;
- }
- else if(i < argc && strcmp("sensor-config-file", argv[i]) == 0) {
- sensor_config_file = argv[++i];
- if(debug) fprintf(stderr, "freeipmi.plugin: sensor config file set to '%s'\n", sensor_config_file);
- continue;
- }
- else if(i < argc && strcmp("ignore", argv[i]) == 0) {
- excluded_record_ids_parse(argv[++i]);
- continue;
- }
- else if(i < argc && strcmp("ignore-status", argv[i]) == 0) {
- excluded_status_record_ids_parse(argv[++i]);
- continue;
- }
- collector_error("freeipmi.plugin: ignoring parameter '%s'", argv[i]);
- }
- errno = 0;
- if(freq >= netdata_update_every)
- netdata_update_every = freq;
- else if(freq)
- collector_error("update frequency %d seconds is too small for IPMI. Using %d.", freq, netdata_update_every);
- // ------------------------------------------------------------------------
- // initialize IPMI
- struct ipmi_monitoring_ipmi_config ipmi_config;
- if(debug) fprintf(stderr, "freeipmi.plugin: calling _init_ipmi_config()\n");
- _init_ipmi_config(&ipmi_config);
- if(debug) {
- fprintf(stderr, "freeipmi.plugin: calling ipmi_monitoring_init()\n");
- ipmimonitoring_init_flags|=IPMI_MONITORING_FLAGS_DEBUG|IPMI_MONITORING_FLAGS_DEBUG_IPMI_PACKETS;
- }
- if(ipmi_monitoring_init(ipmimonitoring_init_flags, &errnum) < 0)
- fatal("ipmi_monitoring_init: %s", ipmi_monitoring_ctx_strerror(errnum));
- if(debug) fprintf(stderr, "freeipmi.plugin: detecting IPMI minimum update frequency...\n");
- freq = ipmi_detect_speed_secs(&ipmi_config);
- if(debug) fprintf(stderr, "freeipmi.plugin: IPMI minimum update frequency was calculated to %d seconds.\n", freq);
- if(freq > netdata_update_every) {
- collector_info("enforcing minimum data collection frequency, calculated to %d seconds.", freq);
- netdata_update_every = freq;
- }
- // ------------------------------------------------------------------------
- // the main loop
- if(debug) fprintf(stderr, "freeipmi.plugin: starting data collection\n");
- time_t started_t = now_monotonic_sec();
- size_t iteration = 0;
- usec_t step = netdata_update_every * USEC_PER_SEC;
- heartbeat_t hb;
- heartbeat_init(&hb);
- for(iteration = 0; 1 ; iteration++) {
- usec_t dt = heartbeat_next(&hb, step);
- if(debug && iteration)
- fprintf(stderr, "freeipmi.plugin: iteration %zu, dt %llu usec, sensors collected %zu, sensors sent to netdata %zu \n"
- , iteration
- , dt
- , netdata_sensors_collected
- , netdata_sensors_updated
- );
- netdata_mark_as_not_updated();
- if(debug) fprintf(stderr, "freeipmi.plugin: calling ipmi_collect_data()\n");
- if(ipmi_collect_data(&ipmi_config) < 0)
- fatal("data collection failed.");
- if(debug) fprintf(stderr, "freeipmi.plugin: calling send_metrics_to_netdata()\n");
- send_metrics_to_netdata();
- fflush(stdout);
- // restart check (14400 seconds)
- if(now_monotonic_sec() - started_t > 14400) exit(0);
- }
- }
|