2 * netdata freeipmi.plugin
3 * Copyright (C) 2017 Costa Tsaousis
7 * ipmimonitoring-sensors.c,v 1.51 2016/11/02 23:46:24 chu11 Exp
8 * ipmimonitoring-sel.c,v 1.51 2016/11/02 23:46:24 chu11 Exp
10 * Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC.
11 * Copyright (C) 2006-2007 The Regents of the University of California.
12 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
13 * Written by Albert Chu <chu11@llnl.gov>
30 #include <ipmi_monitoring.h>
31 #include <ipmi_monitoring_bitmasks.h>
33 /* Communication Configuration - Initialize accordingly */
35 /* Hostname, NULL for In-band communication, non-null for a hostname */
36 char *hostname = NULL;
38 /* In-band Communication Configuration */
39 int driver_type = -1; // IPMI_MONITORING_DRIVER_TYPE_KCS; /* or -1 for default */
40 int disable_auto_probe = 0; /* probe for in-band device */
41 unsigned int driver_address = 0; /* not used if probing */
42 unsigned int register_spacing = 0; /* not used if probing */
43 char *driver_device = NULL; /* not used if probing */
45 /* Out-of-band Communication Configuration */
46 int protocol_version = -1; //IPMI_MONITORING_PROTOCOL_VERSION_1_5; /* or -1 for default */
47 char *username = "foousername";
48 char *password = "foopassword";
49 unsigned char *k_g = NULL;
50 unsigned int k_g_len = 0;
51 int privilege_level = -1; // IPMI_MONITORING_PRIVILEGE_LEVEL_USER; /* or -1 for default */
52 int authentication_type = -1; // IPMI_MONITORING_AUTHENTICATION_TYPE_MD5; /* or -1 for default */
53 int cipher_suite_id = 0; /* or -1 for default */
54 int session_timeout = 0; /* 0 for default */
55 int retransmission_timeout = 0; /* 0 for default */
57 /* Workarounds - specify workaround flags if necessary */
58 unsigned int workaround_flags = 0;
60 /* Initialize w/ record id numbers to only monitor specific record ids */
61 unsigned int record_ids[] = {0};
62 unsigned int record_ids_length = 0;
64 /* Initialize w/ sensor types to only monitor specific sensor types
65 * see ipmi_monitoring.h sensor types list.
67 unsigned int sensor_types[] = {0};
68 unsigned int sensor_types_length = 0;
70 /* Set to an appropriate alternate if desired */
71 char *sdr_cache_directory = "/tmp";
72 char *sensor_config_file = NULL;
74 /* Set to 1 or 0 to enable these sensor reading flags
75 * - See ipmi_monitoring.h for descriptions of these flags.
77 int reread_sdr_cache = 0;
78 int ignore_non_interpretable_sensors = 1;
79 int bridge_sensors = 0;
80 int interpret_oem_data = 0;
81 int shared_sensors = 0;
82 int discrete_reading = 0;
83 int ignore_scanning_disabled = 0;
84 int assume_bmc_owner = 0;
85 int entity_sensor_names = 0;
87 /* Initialization flags
89 * Most commonly bitwise OR IPMI_MONITORING_FLAGS_DEBUG and/or
90 * IPMI_MONITORING_FLAGS_DEBUG_IPMI_PACKETS for extra debugging
93 unsigned int ipmimonitoring_init_flags = 0;
97 // ----------------------------------------------------------------------------
100 /* Initialize w/ date range to only monitoring specific date range */
101 char *date_begin = NULL; /* use MM/DD/YYYY format */
102 char *date_end = NULL; /* use MM/DD/YYYY format */
104 int assume_system_event_record = 0;
106 char *sel_config_file = NULL;
109 // ----------------------------------------------------------------------------
110 // functions common to sensors and SEL
113 _init_ipmi_config (struct ipmi_monitoring_ipmi_config *ipmi_config)
115 assert (ipmi_config);
117 ipmi_config->driver_type = driver_type;
118 ipmi_config->disable_auto_probe = disable_auto_probe;
119 ipmi_config->driver_address = driver_address;
120 ipmi_config->register_spacing = register_spacing;
121 ipmi_config->driver_device = driver_device;
123 ipmi_config->protocol_version = protocol_version;
124 ipmi_config->username = username;
125 ipmi_config->password = password;
126 ipmi_config->k_g = k_g;
127 ipmi_config->k_g_len = k_g_len;
128 ipmi_config->privilege_level = privilege_level;
129 ipmi_config->authentication_type = authentication_type;
130 ipmi_config->cipher_suite_id = cipher_suite_id;
131 ipmi_config->session_timeout_len = session_timeout;
132 ipmi_config->retransmission_timeout_len = retransmission_timeout;
134 ipmi_config->workaround_flags = workaround_flags;
137 #ifdef NETDATA_COMMENTED
139 _get_sensor_type_string (int sensor_type)
143 case IPMI_MONITORING_SENSOR_TYPE_RESERVED:
145 case IPMI_MONITORING_SENSOR_TYPE_TEMPERATURE:
146 return ("Temperature");
147 case IPMI_MONITORING_SENSOR_TYPE_VOLTAGE:
149 case IPMI_MONITORING_SENSOR_TYPE_CURRENT:
151 case IPMI_MONITORING_SENSOR_TYPE_FAN:
153 case IPMI_MONITORING_SENSOR_TYPE_PHYSICAL_SECURITY:
154 return ("Physical Security");
155 case IPMI_MONITORING_SENSOR_TYPE_PLATFORM_SECURITY_VIOLATION_ATTEMPT:
156 return ("Platform Security Violation Attempt");
157 case IPMI_MONITORING_SENSOR_TYPE_PROCESSOR:
158 return ("Processor");
159 case IPMI_MONITORING_SENSOR_TYPE_POWER_SUPPLY:
160 return ("Power Supply");
161 case IPMI_MONITORING_SENSOR_TYPE_POWER_UNIT:
162 return ("Power Unit");
163 case IPMI_MONITORING_SENSOR_TYPE_COOLING_DEVICE:
164 return ("Cooling Device");
165 case IPMI_MONITORING_SENSOR_TYPE_OTHER_UNITS_BASED_SENSOR:
166 return ("Other Units Based Sensor");
167 case IPMI_MONITORING_SENSOR_TYPE_MEMORY:
169 case IPMI_MONITORING_SENSOR_TYPE_DRIVE_SLOT:
170 return ("Drive Slot");
171 case IPMI_MONITORING_SENSOR_TYPE_POST_MEMORY_RESIZE:
172 return ("POST Memory Resize");
173 case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS:
174 return ("System Firmware Progress");
175 case IPMI_MONITORING_SENSOR_TYPE_EVENT_LOGGING_DISABLED:
176 return ("Event Logging Disabled");
177 case IPMI_MONITORING_SENSOR_TYPE_WATCHDOG1:
178 return ("Watchdog 1");
179 case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_EVENT:
180 return ("System Event");
181 case IPMI_MONITORING_SENSOR_TYPE_CRITICAL_INTERRUPT:
182 return ("Critical Interrupt");
183 case IPMI_MONITORING_SENSOR_TYPE_BUTTON_SWITCH:
184 return ("Button/Switch");
185 case IPMI_MONITORING_SENSOR_TYPE_MODULE_BOARD:
186 return ("Module/Board");
187 case IPMI_MONITORING_SENSOR_TYPE_MICROCONTROLLER_COPROCESSOR:
188 return ("Microcontroller/Coprocessor");
189 case IPMI_MONITORING_SENSOR_TYPE_ADD_IN_CARD:
190 return ("Add In Card");
191 case IPMI_MONITORING_SENSOR_TYPE_CHASSIS:
193 case IPMI_MONITORING_SENSOR_TYPE_CHIP_SET:
195 case IPMI_MONITORING_SENSOR_TYPE_OTHER_FRU:
196 return ("Other Fru");
197 case IPMI_MONITORING_SENSOR_TYPE_CABLE_INTERCONNECT:
198 return ("Cable/Interconnect");
199 case IPMI_MONITORING_SENSOR_TYPE_TERMINATOR:
200 return ("Terminator");
201 case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_BOOT_INITIATED:
202 return ("System Boot Initiated");
203 case IPMI_MONITORING_SENSOR_TYPE_BOOT_ERROR:
204 return ("Boot Error");
205 case IPMI_MONITORING_SENSOR_TYPE_OS_BOOT:
207 case IPMI_MONITORING_SENSOR_TYPE_OS_CRITICAL_STOP:
208 return ("OS Critical Stop");
209 case IPMI_MONITORING_SENSOR_TYPE_SLOT_CONNECTOR:
210 return ("Slot/Connector");
211 case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE:
212 return ("System ACPI Power State");
213 case IPMI_MONITORING_SENSOR_TYPE_WATCHDOG2:
214 return ("Watchdog 2");
215 case IPMI_MONITORING_SENSOR_TYPE_PLATFORM_ALERT:
216 return ("Platform Alert");
217 case IPMI_MONITORING_SENSOR_TYPE_ENTITY_PRESENCE:
218 return ("Entity Presence");
219 case IPMI_MONITORING_SENSOR_TYPE_MONITOR_ASIC_IC:
220 return ("Monitor ASIC/IC");
221 case IPMI_MONITORING_SENSOR_TYPE_LAN:
223 case IPMI_MONITORING_SENSOR_TYPE_MANAGEMENT_SUBSYSTEM_HEALTH:
224 return ("Management Subsystem Health");
225 case IPMI_MONITORING_SENSOR_TYPE_BATTERY:
227 case IPMI_MONITORING_SENSOR_TYPE_SESSION_AUDIT:
228 return ("Session Audit");
229 case IPMI_MONITORING_SENSOR_TYPE_VERSION_CHANGE:
230 return ("Version Change");
231 case IPMI_MONITORING_SENSOR_TYPE_FRU_STATE:
232 return ("FRU State");
235 return ("Unrecognized");
237 #endif // NETDATA_COMMENTED
240 // ----------------------------------------------------------------------------
241 // BEGIN NETDATA CODE
243 static int debug = 0;
245 static int netdata_update_every = 5;
246 static int netdata_priority = 90000;
247 static int netdata_do_sel = 1;
249 static size_t netdata_sensors_updated = 0;
250 static size_t netdata_sensors_collected = 0;
251 static size_t netdata_sel_events = 0;
252 static size_t netdata_sensors_states_nominal = 0;
253 static size_t netdata_sensors_states_warning = 0;
254 static size_t netdata_sensors_states_critical = 0;
264 int sensor_reading_type;
267 uint32_t uint32_value;
276 } *sensors_root = NULL;
278 static void netdata_mark_as_not_updated() {
280 for(sn = sensors_root; sn ;sn = sn->next)
281 sn->updated = sn->sent = 0;
283 netdata_sensors_updated = 0;
284 netdata_sensors_collected = 0;
285 netdata_sel_events = 0;
287 netdata_sensors_states_nominal = 0;
288 netdata_sensors_states_warning = 0;
289 netdata_sensors_states_critical = 0;
292 static void send_chart_to_netdata_for_units(int units) {
296 case IPMI_MONITORING_SENSOR_UNITS_CELSIUS:
297 printf("CHART ipmi.temperatures_c '' 'System Celcius Temperatures read by IPMI' 'Celcius' 'temperatures' 'ipmi.temperatures_c' 'line' %d %d\n"
298 , netdata_priority + 10
299 , netdata_update_every
303 case IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT:
304 printf("CHART ipmi.temperatures_f '' 'System Fahrenheit Temperatures read by IPMI' 'Fahrenheit' 'temperatures' 'ipmi.temperatures_f' 'line' %d %d\n"
305 , netdata_priority + 11
306 , netdata_update_every
310 case IPMI_MONITORING_SENSOR_UNITS_VOLTS:
311 printf("CHART ipmi.volts '' 'System Voltages read by IPMI' 'Volts' 'voltages' 'ipmi.voltages' 'line' %d %d\n"
312 , netdata_priority + 12
313 , netdata_update_every
317 case IPMI_MONITORING_SENSOR_UNITS_AMPS:
318 printf("CHART ipmi.amps '' 'System Current read by IPMI' 'Amps' 'current' 'ipmi.amps' 'line' %d %d\n"
319 , netdata_priority + 13
320 , netdata_update_every
324 case IPMI_MONITORING_SENSOR_UNITS_RPM:
325 printf("CHART ipmi.rpm '' 'System Fans read by IPMI' 'RPM' 'fans' 'ipmi.rpm' 'line' %d %d\n"
326 , netdata_priority + 14
327 , netdata_update_every
331 case IPMI_MONITORING_SENSOR_UNITS_WATTS:
332 printf("CHART ipmi.watts '' 'System Power read by IPMI' 'Watts' 'power' 'ipmi.watts' 'line' %d %d\n"
333 , netdata_priority + 5
334 , netdata_update_every
338 case IPMI_MONITORING_SENSOR_UNITS_PERCENT:
339 printf("CHART ipmi.percent '' 'System Metrics read by IPMI' '%%' 'other' 'ipmi.percent' 'line' %d %d\n"
340 , netdata_priority + 15
341 , netdata_update_every
346 for(sn = sensors_root; sn; sn = sn->next)
347 if(sn->sensor_units == units)
352 for(sn = sensors_root; sn; sn = sn->next) {
353 if(sn->sensor_units == units && sn->updated && !sn->ignore) {
356 switch(sn->sensor_reading_type) {
357 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL:
358 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32:
359 printf("DIMENSION i%d_n%d_r%d '%s i%d' absolute 1 1\n"
362 , sn->sensor_reading_type
368 case IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE:
369 printf("DIMENSION i%d_n%d_r%d '%s i%d' absolute 1 1000\n"
372 , sn->sensor_reading_type
386 static void send_metrics_to_netdata_for_units(int units) {
390 case IPMI_MONITORING_SENSOR_UNITS_CELSIUS:
391 printf("BEGIN ipmi.temperatures_c\n");
394 case IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT:
395 printf("BEGIN ipmi.temperatures_f\n");
398 case IPMI_MONITORING_SENSOR_UNITS_VOLTS:
399 printf("BEGIN ipmi.volts\n");
402 case IPMI_MONITORING_SENSOR_UNITS_AMPS:
403 printf("BEGIN ipmi.amps\n");
406 case IPMI_MONITORING_SENSOR_UNITS_RPM:
407 printf("BEGIN ipmi.rpm\n");
410 case IPMI_MONITORING_SENSOR_UNITS_WATTS:
411 printf("BEGIN ipmi.watts\n");
414 case IPMI_MONITORING_SENSOR_UNITS_PERCENT:
415 printf("BEGIN ipmi.percent\n");
419 for(sn = sensors_root; sn; sn = sn->next)
420 if(sn->sensor_units == units)
425 for(sn = sensors_root; sn; sn = sn->next) {
426 if(sn->sensor_units == units && sn->updated && !sn->sent && !sn->ignore) {
427 netdata_sensors_updated++;
431 switch(sn->sensor_reading_type) {
432 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL:
433 printf("SET i%d_n%d_r%d = %u\n"
436 , sn->sensor_reading_type
437 , sn->sensor_reading.bool_value
441 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32:
442 printf("SET i%d_n%d_r%d = %u\n"
445 , sn->sensor_reading_type
446 , sn->sensor_reading.uint32_value
450 case IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE:
451 printf("SET i%d_n%d_r%d = %lld\n"
454 , sn->sensor_reading_type
455 , (long long int)(sn->sensor_reading.double_value * 1000)
469 static void send_metrics_to_netdata() {
470 static int sel_chart_generated = 0, sensors_states_chart_generated = 0;
473 if(netdata_do_sel && !sel_chart_generated) {
474 sel_chart_generated = 1;
475 printf("CHART ipmi.events '' 'IPMI Events' 'events' 'events' ipmi.sel area %d %d\n"
476 , netdata_priority + 2
477 , netdata_update_every
479 printf("DIMENSION events '' absolute 1 1\n");
482 if(!sensors_states_chart_generated) {
483 sensors_states_chart_generated = 1;
484 printf("CHART ipmi.sensors_states '' 'IPMI Sensors State' 'sensors' 'states' ipmi.sensors_states line %d %d\n"
485 , netdata_priority + 1
486 , netdata_update_every
488 printf("DIMENSION nominal '' absolute 1 1\n");
489 printf("DIMENSION critical '' absolute 1 1\n");
490 printf("DIMENSION warning '' absolute 1 1\n");
493 // generate the CHART/DIMENSION lines, if we have to
494 for(sn = sensors_root; sn; sn = sn->next)
495 if(sn->updated && !sn->exposed && !sn->ignore)
496 send_chart_to_netdata_for_units(sn->sensor_units);
500 "BEGIN ipmi.events\n"
508 "BEGIN ipmi.sensors_states\n"
509 "SET nominal = %zu\n"
510 "SET warning = %zu\n"
511 "SET critical = %zu\n"
513 , netdata_sensors_states_nominal
514 , netdata_sensors_states_warning
515 , netdata_sensors_states_critical
518 // send metrics to netdata
519 for(sn = sensors_root; sn; sn = sn->next)
520 if(sn->updated && sn->exposed && !sn->sent && !sn->ignore)
521 send_metrics_to_netdata_for_units(sn->sensor_units);
525 static void netdata_get_sensor(
531 , int sensor_reading_type
533 , void *sensor_reading
535 // find the sensor record
537 for(sn = sensors_root; sn ;sn = sn->next)
538 if( sn->record_id == record_id &&
539 sn->sensor_number == sensor_number &&
540 sn->sensor_reading_type == sensor_reading_type &&
541 sn->sensor_units == sensor_units &&
542 !strcmp(sn->sensor_name, sensor_name)
547 // not found, create it
549 sn = calloc(1, sizeof(struct sensor));
551 fatal("cannot allocate %zu bytes of memory.", sizeof(struct sensor));
554 sn->record_id = record_id;
555 sn->sensor_number = sensor_number;
556 sn->sensor_type = sensor_type;
557 sn->sensor_state = sensor_state;
558 sn->sensor_units = sensor_units;
559 sn->sensor_reading_type = sensor_reading_type;
560 sn->sensor_name = strdup(sensor_name);
561 if(!sn->sensor_name) {
562 fatal("cannot allocate %zu bytes of memory.", strlen(sensor_name));
565 sn->next = sensors_root;
569 switch(sensor_reading_type) {
570 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL:
571 sn->sensor_reading.bool_value = *((uint8_t *)sensor_reading);
573 netdata_sensors_collected++;
576 case IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32:
577 sn->sensor_reading.uint32_value = *((uint32_t *)sensor_reading);
579 netdata_sensors_collected++;
582 case IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE:
583 sn->sensor_reading.double_value = *((double *)sensor_reading);
585 netdata_sensors_collected++;
593 switch(sensor_state) {
594 case IPMI_MONITORING_STATE_NOMINAL:
595 netdata_sensors_states_nominal++;
598 case IPMI_MONITORING_STATE_WARNING:
599 netdata_sensors_states_warning++;
602 case IPMI_MONITORING_STATE_CRITICAL:
603 netdata_sensors_states_critical++;
611 static void netdata_get_sel(
613 , int record_type_class
617 (void)record_type_class;
620 netdata_sel_events++;
624 void netdata_cleanup_and_exit(int ret) {
629 // ----------------------------------------------------------------------------
633 _ipmimonitoring_sensors (struct ipmi_monitoring_ipmi_config *ipmi_config)
635 ipmi_monitoring_ctx_t ctx = NULL;
636 unsigned int sensor_reading_flags = 0;
641 if (!(ctx = ipmi_monitoring_ctx_create ())) {
642 error("ipmi_monitoring_ctx_create()");
646 if (sdr_cache_directory)
648 if (ipmi_monitoring_ctx_sdr_cache_directory (ctx,
649 sdr_cache_directory) < 0)
651 error("ipmi_monitoring_ctx_sdr_cache_directory(): %s\n",
652 ipmi_monitoring_ctx_errormsg (ctx));
657 /* Must call otherwise only default interpretations ever used */
658 if (sensor_config_file)
660 if (ipmi_monitoring_ctx_sensor_config_file (ctx,
661 sensor_config_file) < 0)
663 error( "ipmi_monitoring_ctx_sensor_config_file(): %s\n",
664 ipmi_monitoring_ctx_errormsg (ctx));
670 if (ipmi_monitoring_ctx_sensor_config_file (ctx, NULL) < 0)
672 error( "ipmi_monitoring_ctx_sensor_config_file(): %s\n",
673 ipmi_monitoring_ctx_errormsg (ctx));
678 if (reread_sdr_cache)
679 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_REREAD_SDR_CACHE;
681 if (ignore_non_interpretable_sensors)
682 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_IGNORE_NON_INTERPRETABLE_SENSORS;
685 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_BRIDGE_SENSORS;
687 if (interpret_oem_data)
688 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_INTERPRET_OEM_DATA;
691 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_SHARED_SENSORS;
693 if (discrete_reading)
694 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_DISCRETE_READING;
696 if (ignore_scanning_disabled)
697 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_IGNORE_SCANNING_DISABLED;
699 if (assume_bmc_owner)
700 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_ASSUME_BMC_OWNER;
702 #ifdef IPMI_MONITORING_SENSOR_READING_FLAGS_ENTITY_SENSOR_NAMES
703 if (entity_sensor_names)
704 sensor_reading_flags |= IPMI_MONITORING_SENSOR_READING_FLAGS_ENTITY_SENSOR_NAMES;
705 #endif // IPMI_MONITORING_SENSOR_READING_FLAGS_ENTITY_SENSOR_NAMES
707 if (!record_ids_length && !sensor_types_length)
709 if ((sensor_count = ipmi_monitoring_sensor_readings_by_record_id (ctx,
712 sensor_reading_flags,
718 error( "ipmi_monitoring_sensor_readings_by_record_id(): %s",
719 ipmi_monitoring_ctx_errormsg (ctx));
723 else if (record_ids_length)
725 if ((sensor_count = ipmi_monitoring_sensor_readings_by_record_id (ctx,
728 sensor_reading_flags,
734 error( "ipmi_monitoring_sensor_readings_by_record_id(): %s",
735 ipmi_monitoring_ctx_errormsg (ctx));
741 if ((sensor_count = ipmi_monitoring_sensor_readings_by_sensor_type (ctx,
744 sensor_reading_flags,
750 error( "ipmi_monitoring_sensor_readings_by_sensor_type(): %s",
751 ipmi_monitoring_ctx_errormsg (ctx));
756 #ifdef NETDATA_COMMENTED
757 printf ("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
765 "Sensor Event/Reading Type Code",
766 "Sensor Event Bitmask",
767 "Sensor Event String");
768 #endif // NETDATA_COMMENTED
770 for (i = 0; i < sensor_count; i++, ipmi_monitoring_sensor_iterator_next (ctx))
772 int record_id, sensor_number, sensor_type, sensor_state, sensor_units,
775 #ifdef NETDATA_COMMENTED
776 int sensor_bitmask_type, sensor_bitmask, event_reading_type_code;
777 char **sensor_bitmask_strings = NULL;
778 const char *sensor_type_str;
779 const char *sensor_state_str;
780 #endif // NETDATA_COMMENTED
782 char *sensor_name = NULL;
783 void *sensor_reading;
785 if ((record_id = ipmi_monitoring_sensor_read_record_id (ctx)) < 0)
787 error( "ipmi_monitoring_sensor_read_record_id(): %s",
788 ipmi_monitoring_ctx_errormsg (ctx));
792 if ((sensor_number = ipmi_monitoring_sensor_read_sensor_number (ctx)) < 0)
794 error( "ipmi_monitoring_sensor_read_sensor_number(): %s",
795 ipmi_monitoring_ctx_errormsg (ctx));
799 if ((sensor_type = ipmi_monitoring_sensor_read_sensor_type (ctx)) < 0)
801 error( "ipmi_monitoring_sensor_read_sensor_type(): %s",
802 ipmi_monitoring_ctx_errormsg (ctx));
806 if (!(sensor_name = ipmi_monitoring_sensor_read_sensor_name (ctx)))
808 error( "ipmi_monitoring_sensor_read_sensor_name(): %s",
809 ipmi_monitoring_ctx_errormsg (ctx));
813 if ((sensor_state = ipmi_monitoring_sensor_read_sensor_state (ctx)) < 0)
815 error( "ipmi_monitoring_sensor_read_sensor_state(): %s",
816 ipmi_monitoring_ctx_errormsg (ctx));
820 if ((sensor_units = ipmi_monitoring_sensor_read_sensor_units (ctx)) < 0)
822 error( "ipmi_monitoring_sensor_read_sensor_units(): %s",
823 ipmi_monitoring_ctx_errormsg (ctx));
827 #ifdef NETDATA_COMMENTED
828 if ((sensor_bitmask_type = ipmi_monitoring_sensor_read_sensor_bitmask_type (ctx)) < 0)
830 error( "ipmi_monitoring_sensor_read_sensor_bitmask_type(): %s",
831 ipmi_monitoring_ctx_errormsg (ctx));
834 if ((sensor_bitmask = ipmi_monitoring_sensor_read_sensor_bitmask (ctx)) < 0)
837 "ipmi_monitoring_sensor_read_sensor_bitmask(): %s",
838 ipmi_monitoring_ctx_errormsg (ctx));
842 if (!(sensor_bitmask_strings = ipmi_monitoring_sensor_read_sensor_bitmask_strings (ctx)))
844 error( "ipmi_monitoring_sensor_read_sensor_bitmask_strings(): %s",
845 ipmi_monitoring_ctx_errormsg (ctx));
848 #endif // NETDATA_COMMENTED
850 if ((sensor_reading_type = ipmi_monitoring_sensor_read_sensor_reading_type (ctx)) < 0)
852 error( "ipmi_monitoring_sensor_read_sensor_reading_type(): %s",
853 ipmi_monitoring_ctx_errormsg (ctx));
857 sensor_reading = ipmi_monitoring_sensor_read_sensor_reading (ctx);
859 #ifdef NETDATA_COMMENTED
860 if ((event_reading_type_code = ipmi_monitoring_sensor_read_event_reading_type_code (ctx)) < 0)
862 error( "ipmi_monitoring_sensor_read_event_reading_type_code(): %s",
863 ipmi_monitoring_ctx_errormsg (ctx));
866 #endif // NETDATA_COMMENTED
874 , sensor_reading_type
879 #ifdef NETDATA_COMMENTED
880 if (!strlen (sensor_name))
883 sensor_type_str = _get_sensor_type_string (sensor_type);
885 printf ("%d, %s, %d, %s",
891 if (sensor_state == IPMI_MONITORING_STATE_NOMINAL)
892 sensor_state_str = "Nominal";
893 else if (sensor_state == IPMI_MONITORING_STATE_WARNING)
894 sensor_state_str = "Warning";
895 else if (sensor_state == IPMI_MONITORING_STATE_CRITICAL)
896 sensor_state_str = "Critical";
898 sensor_state_str = "N/A";
900 printf (", %s", sensor_state_str);
904 const char *sensor_units_str;
906 if (sensor_reading_type == IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER8_BOOL)
908 (*((uint8_t *)sensor_reading) ? "true" : "false"));
909 else if (sensor_reading_type == IPMI_MONITORING_SENSOR_READING_TYPE_UNSIGNED_INTEGER32)
911 *((uint32_t *)sensor_reading));
912 else if (sensor_reading_type == IPMI_MONITORING_SENSOR_READING_TYPE_DOUBLE)
914 *((double *)sensor_reading));
918 if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_CELSIUS)
919 sensor_units_str = "C";
920 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_FAHRENHEIT)
921 sensor_units_str = "F";
922 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_VOLTS)
923 sensor_units_str = "V";
924 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_AMPS)
925 sensor_units_str = "A";
926 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_RPM)
927 sensor_units_str = "RPM";
928 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_WATTS)
929 sensor_units_str = "W";
930 else if (sensor_units == IPMI_MONITORING_SENSOR_UNITS_PERCENT)
931 sensor_units_str = "%";
933 sensor_units_str = "N/A";
935 printf (", %s", sensor_units_str);
938 printf (", N/A, N/A");
940 printf (", %Xh", event_reading_type_code);
942 /* It is possible you may want to monitor specific event
943 * conditions that may occur. If that is the case, you may want
944 * to check out what specific bitmask type and bitmask events
945 * occurred. See ipmi_monitoring_bitmasks.h for a list of
946 * bitmasks and types.
949 if (sensor_bitmask_type != IPMI_MONITORING_SENSOR_BITMASK_TYPE_UNKNOWN)
950 printf (", %Xh", sensor_bitmask);
954 if (sensor_bitmask_type != IPMI_MONITORING_SENSOR_BITMASK_TYPE_UNKNOWN)
960 while (sensor_bitmask_strings[i])
965 sensor_bitmask_strings[i]);
974 #endif // NETDATA_COMMENTED
980 ipmi_monitoring_ctx_destroy (ctx);
986 _ipmimonitoring_sel (struct ipmi_monitoring_ipmi_config *ipmi_config)
988 ipmi_monitoring_ctx_t ctx = NULL;
989 unsigned int sel_flags = 0;
994 if (!(ctx = ipmi_monitoring_ctx_create ()))
996 error("ipmi_monitoring_ctx_create()");
1000 if (sdr_cache_directory)
1002 if (ipmi_monitoring_ctx_sdr_cache_directory (ctx,
1003 sdr_cache_directory) < 0)
1005 error( "ipmi_monitoring_ctx_sdr_cache_directory(): %s",
1006 ipmi_monitoring_ctx_errormsg (ctx));
1011 /* Must call otherwise only default interpretations ever used */
1012 if (sel_config_file)
1014 if (ipmi_monitoring_ctx_sel_config_file (ctx,
1015 sel_config_file) < 0)
1017 error( "ipmi_monitoring_ctx_sel_config_file(): %s",
1018 ipmi_monitoring_ctx_errormsg (ctx));
1024 if (ipmi_monitoring_ctx_sel_config_file (ctx, NULL) < 0)
1026 error( "ipmi_monitoring_ctx_sel_config_file(): %s",
1027 ipmi_monitoring_ctx_errormsg (ctx));
1032 if (reread_sdr_cache)
1033 sel_flags |= IPMI_MONITORING_SEL_FLAGS_REREAD_SDR_CACHE;
1035 if (interpret_oem_data)
1036 sel_flags |= IPMI_MONITORING_SEL_FLAGS_INTERPRET_OEM_DATA;
1038 if (assume_system_event_record)
1039 sel_flags |= IPMI_MONITORING_SEL_FLAGS_ASSUME_SYSTEM_EVENT_RECORD;
1041 #ifdef IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES
1042 if (entity_sensor_names)
1043 sel_flags |= IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES;
1044 #endif // IPMI_MONITORING_SEL_FLAGS_ENTITY_SENSOR_NAMES
1046 if (record_ids_length)
1048 if ((sel_count = ipmi_monitoring_sel_by_record_id (ctx,
1057 error( "ipmi_monitoring_sel_by_record_id(): %s",
1058 ipmi_monitoring_ctx_errormsg (ctx));
1062 else if (sensor_types_length)
1064 if ((sel_count = ipmi_monitoring_sel_by_sensor_type (ctx,
1069 sensor_types_length,
1073 error( "ipmi_monitoring_sel_by_sensor_type(): %s",
1074 ipmi_monitoring_ctx_errormsg (ctx));
1081 if ((sel_count = ipmi_monitoring_sel_by_date_range (ctx,
1090 error( "ipmi_monitoring_sel_by_sensor_type(): %s",
1091 ipmi_monitoring_ctx_errormsg (ctx));
1097 if ((sel_count = ipmi_monitoring_sel_by_record_id (ctx,
1106 error( "ipmi_monitoring_sel_by_record_id(): %s",
1107 ipmi_monitoring_ctx_errormsg (ctx));
1112 #ifdef NETDATA_COMMENTED
1113 printf ("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
1124 "Event Offset String");
1125 #endif // NETDATA_COMMENTED
1127 for (i = 0; i < sel_count; i++, ipmi_monitoring_sel_iterator_next (ctx))
1129 int record_id, record_type, sel_state, record_type_class;
1130 #ifdef NETDATA_COMMENTED
1131 int sensor_type, sensor_number, event_direction,
1132 event_offset_type, event_offset, event_type_code, manufacturer_id;
1133 unsigned int timestamp, event_data1, event_data2, event_data3;
1134 char *event_offset_string = NULL;
1135 const char *sensor_type_str;
1136 const char *event_direction_str;
1137 const char *sel_state_str;
1138 char *sensor_name = NULL;
1139 unsigned char oem_data[64];
1142 #endif // NETDATA_COMMENTED
1144 if ((record_id = ipmi_monitoring_sel_read_record_id (ctx)) < 0)
1146 error( "ipmi_monitoring_sel_read_record_id(): %s",
1147 ipmi_monitoring_ctx_errormsg (ctx));
1151 if ((record_type = ipmi_monitoring_sel_read_record_type (ctx)) < 0)
1153 error( "ipmi_monitoring_sel_read_record_type(): %s",
1154 ipmi_monitoring_ctx_errormsg (ctx));
1158 if ((record_type_class = ipmi_monitoring_sel_read_record_type_class (ctx)) < 0)
1160 error( "ipmi_monitoring_sel_read_record_type_class(): %s",
1161 ipmi_monitoring_ctx_errormsg (ctx));
1165 if ((sel_state = ipmi_monitoring_sel_read_sel_state (ctx)) < 0)
1167 error( "ipmi_monitoring_sel_read_sel_state(): %s",
1168 ipmi_monitoring_ctx_errormsg (ctx));
1178 #ifdef NETDATA_COMMENTED
1179 if (sel_state == IPMI_MONITORING_STATE_NOMINAL)
1180 sel_state_str = "Nominal";
1181 else if (sel_state == IPMI_MONITORING_STATE_WARNING)
1182 sel_state_str = "Warning";
1183 else if (sel_state == IPMI_MONITORING_STATE_CRITICAL)
1184 sel_state_str = "Critical";
1186 sel_state_str = "N/A";
1188 printf ("%d, %d, %s",
1193 if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD
1194 || record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD)
1197 if (ipmi_monitoring_sel_read_timestamp (ctx, ×tamp) < 0)
1199 error( "ipmi_monitoring_sel_read_timestamp(): %s",
1200 ipmi_monitoring_ctx_errormsg (ctx));
1204 /* XXX: This should be converted to a nice date output using
1205 * your favorite timestamp -> string conversion functions.
1207 printf (", %u", timestamp);
1212 if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD)
1214 /* If you are integrating ipmimonitoring SEL into a monitoring application,
1215 * you may wish to count the number of times a specific error occurred
1216 * and report that to the monitoring application.
1218 * In this particular case, you'll probably want to check out
1219 * what sensor type each SEL event is reporting, the
1220 * event offset type, and the specific event offset that occurred.
1222 * See ipmi_monitoring_offsets.h for a list of event offsets
1226 if (!(sensor_name = ipmi_monitoring_sel_read_sensor_name (ctx)))
1228 error( "ipmi_monitoring_sel_read_sensor_name(): %s",
1229 ipmi_monitoring_ctx_errormsg (ctx));
1233 if ((sensor_type = ipmi_monitoring_sel_read_sensor_type (ctx)) < 0)
1235 error( "ipmi_monitoring_sel_read_sensor_type(): %s",
1236 ipmi_monitoring_ctx_errormsg (ctx));
1240 if ((sensor_number = ipmi_monitoring_sel_read_sensor_number (ctx)) < 0)
1242 error( "ipmi_monitoring_sel_read_sensor_number(): %s",
1243 ipmi_monitoring_ctx_errormsg (ctx));
1247 if ((event_direction = ipmi_monitoring_sel_read_event_direction (ctx)) < 0)
1249 error( "ipmi_monitoring_sel_read_event_direction(): %s",
1250 ipmi_monitoring_ctx_errormsg (ctx));
1254 if ((event_type_code = ipmi_monitoring_sel_read_event_type_code (ctx)) < 0)
1256 error( "ipmi_monitoring_sel_read_event_type_code(): %s",
1257 ipmi_monitoring_ctx_errormsg (ctx));
1261 if (ipmi_monitoring_sel_read_event_data (ctx,
1266 error( "ipmi_monitoring_sel_read_event_data(): %s",
1267 ipmi_monitoring_ctx_errormsg (ctx));
1271 if ((event_offset_type = ipmi_monitoring_sel_read_event_offset_type (ctx)) < 0)
1273 error( "ipmi_monitoring_sel_read_event_offset_type(): %s",
1274 ipmi_monitoring_ctx_errormsg (ctx));
1278 if ((event_offset = ipmi_monitoring_sel_read_event_offset (ctx)) < 0)
1280 error( "ipmi_monitoring_sel_read_event_offset(): %s",
1281 ipmi_monitoring_ctx_errormsg (ctx));
1285 if (!(event_offset_string = ipmi_monitoring_sel_read_event_offset_string (ctx)))
1287 error( "ipmi_monitoring_sel_read_event_offset_string(): %s",
1288 ipmi_monitoring_ctx_errormsg (ctx));
1292 if (!strlen (sensor_name))
1293 sensor_name = "N/A";
1295 sensor_type_str = _get_sensor_type_string (sensor_type);
1297 if (event_direction == IPMI_MONITORING_SEL_EVENT_DIRECTION_ASSERTION)
1298 event_direction_str = "Assertion";
1300 event_direction_str = "Deassertion";
1302 printf (", %s, %s, %d, %s, %Xh, %Xh-%Xh-%Xh",
1306 event_direction_str,
1312 if (event_offset_type != IPMI_MONITORING_EVENT_OFFSET_TYPE_UNKNOWN)
1313 printf (", %Xh", event_offset);
1317 if (event_offset_type != IPMI_MONITORING_EVENT_OFFSET_TYPE_UNKNOWN)
1318 printf (", %s", event_offset_string);
1322 else if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD
1323 || record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_NON_TIMESTAMPED_OEM_RECORD)
1325 if (record_type_class == IPMI_MONITORING_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD)
1327 if ((manufacturer_id = ipmi_monitoring_sel_read_manufacturer_id (ctx)) < 0)
1329 error( "ipmi_monitoring_sel_read_manufacturer_id(): %s",
1330 ipmi_monitoring_ctx_errormsg (ctx));
1334 printf (", Manufacturer ID = %Xh", manufacturer_id);
1337 if ((oem_data_len = ipmi_monitoring_sel_read_oem_data (ctx, oem_data, 1024)) < 0)
1339 error( "ipmi_monitoring_sel_read_oem_data(): %s",
1340 ipmi_monitoring_ctx_errormsg (ctx));
1344 printf (", OEM Data = ");
1346 for (j = 0; j < oem_data_len; j++)
1347 printf ("%02Xh ", oem_data[j]);
1350 printf (", N/A, N/A, N/A, N/A, N/A, N/A, N/A");
1353 #endif // NETDATA_COMMENTED
1359 ipmi_monitoring_ctx_destroy (ctx);
1363 // ----------------------------------------------------------------------------
1364 // MAIN PROGRAM FOR NETDATA PLUGIN
1366 int ipmi_collect_data(struct ipmi_monitoring_ipmi_config *ipmi_config) {
1369 if (_ipmimonitoring_sensors(ipmi_config) < 0) return -1;
1371 if(netdata_do_sel) {
1372 if(_ipmimonitoring_sel(ipmi_config) < 0) return -2;
1378 int ipmi_detect_speed_secs(struct ipmi_monitoring_ipmi_config *ipmi_config) {
1380 unsigned long long total = 0;
1382 for(i = 0 ; i < checks ; i++) {
1383 if(debug) fprintf(stderr, "freeipmi.plugin: checking data collection speed iteration %d of %d\n", i+1, checks);
1385 // measure the time a data collection needs
1386 unsigned long long start = now_realtime_usec();
1387 if(ipmi_collect_data(ipmi_config) < 0)
1388 fatal("freeipmi.plugin: data collection failed.");
1390 unsigned long long end = now_realtime_usec();
1392 if(debug) fprintf(stderr, "freeipmi.plugin: data collection speed was %llu usec\n", end - start);
1394 // add it to our total
1395 total += end - start;
1397 // wait the same time
1398 // to avoid flooding the IPMI processor with requests
1399 sleep_usec(end - start);
1402 // so, we assume it needed 2x the time
1403 // we find the average in microseconds
1404 // and we round-up to the closest second
1406 return (( total * 2 / checks / 1000000 ) + 1);
1409 int main (int argc, char **argv) {
1411 // ------------------------------------------------------------------------
1412 // initialization of netdata plugin
1414 program_name = "freeipmi.plugin";
1417 error_log_syslog = 0;
1419 // set errors flood protection to 100 logs per hour
1420 error_log_errors_per_period = 100;
1421 error_log_throttle_period = 3600;
1424 // ------------------------------------------------------------------------
1425 // parse command line parameters
1428 for(i = 1; i < argc ; i++) {
1430 int n = atoi(argv[i]);
1437 if(strcmp("version", argv[i]) == 0 || strcmp("-v", argv[i]) == 0 || strcmp("-V", argv[i]) == 0) {
1438 printf("freeipmi.plugin %s\n", VERSION);
1441 else if(strcmp("debug", argv[i]) == 0) {
1445 else if(strcmp("sel", argv[i]) == 0) {
1449 else if(strcmp("no-sel", argv[i]) == 0) {
1453 else if(strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
1456 " netdata freeipmi.plugin %s\n"
1457 " Copyright (C) 2016-2017 Costa Tsaousis <costa@tsaousis.gr>\n"
1458 " Released under GNU General Public License v3 or later.\n"
1459 " All rights reserved.\n"
1461 " This program is a data collector plugin for netdata.\n"
1463 " Available command line options:\n"
1465 " SECONDS data collection frequency\n"
1468 " debug enable verbose output\n"
1469 " default: disabled\n"
1472 " no-sel enable/disable SEL collection\n"
1477 " password PASS connect to remote IPMI host\n"
1478 " default: local IPMI processor\n"
1480 " sdr-cache-dir PATH directory for SDR cache files\n"
1483 " sensor-config-file FILE filename to read sensor configuration\n"
1488 " version print version and exit\n"
1490 " Linux kernel module for IPMI is CPU hungry.\n"
1491 " On Linux run this to lower kipmiN CPU utilization:\n"
1492 " # echo 10 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us\n"
1494 " or create: /etc/modprobe.d/ipmi.conf with these contents:\n"
1495 " options ipmi_si kipmid_max_busy_us=10\n"
1497 " For more information:\n"
1498 " https://github.com/firehol/netdata/wiki/monitoring-IPMI\n"
1501 , netdata_update_every
1502 , netdata_do_sel?"enabled":"disabled"
1503 , sdr_cache_directory?sdr_cache_directory:"system default"
1504 , sensor_config_file?sensor_config_file:"system default"
1508 else if(i < argc && strcmp("hostname", argv[i]) == 0) {
1509 hostname = strdupz(argv[++i]);
1511 // mask it be hidden from the process tree
1512 while(*s) *s++ = 'x';
1513 if(debug) fprintf(stderr, "freeipmi.plugin: hostname set to '%s'\n", hostname);
1516 else if(i < argc && strcmp("username", argv[i]) == 0) {
1517 username = strdupz(argv[++i]);
1519 // mask it be hidden from the process tree
1520 while(*s) *s++ = 'x';
1521 if(debug) fprintf(stderr, "freeipmi.plugin: username set to '%s'\n", username);
1524 else if(i < argc && strcmp("password", argv[i]) == 0) {
1525 password = strdupz(argv[++i]);
1527 // mask it be hidden from the process tree
1528 while(*s) *s++ = 'x';
1529 if(debug) fprintf(stderr, "freeipmi.plugin: password set to '%s'\n", password);
1532 else if(i < argc && strcmp("sdr-cache-dir", argv[i]) == 0) {
1533 sdr_cache_directory = argv[++i];
1534 if(debug) fprintf(stderr, "freeipmi.plugin: SDR cache directory set to '%s'\n", sdr_cache_directory);
1537 else if(i < argc && strcmp("sensor-config-file", argv[i]) == 0) {
1538 sensor_config_file = argv[++i];
1539 if(debug) fprintf(stderr, "freeipmi.plugin: sensor config file set to '%s'\n", sensor_config_file);
1543 error("freeipmi.plugin: ignoring parameter '%s'", argv[i]);
1546 if(freq > netdata_update_every)
1547 netdata_update_every = freq;
1550 error("update frequency %d seconds is too small for IPMI. Using %d.", freq, netdata_update_every);
1553 // ------------------------------------------------------------------------
1556 struct ipmi_monitoring_ipmi_config ipmi_config;
1558 if(debug) fprintf(stderr, "freeipmi.plugin: calling _init_ipmi_config()\n");
1560 _init_ipmi_config(&ipmi_config);
1562 if(debug) fprintf(stderr, "freeipmi.plugin: calling ipmi_monitoring_init()\n");
1564 if(ipmi_monitoring_init(ipmimonitoring_init_flags, &errnum) < 0)
1565 fatal("ipmi_monitoring_init: %s", ipmi_monitoring_ctx_strerror(errnum));
1567 if(debug) fprintf(stderr, "freeipmi.plugin: detecting IPMI minimum update frequency...\n");
1568 freq = ipmi_detect_speed_secs(&ipmi_config);
1569 if(debug) fprintf(stderr, "freeipmi.plugin: IPMI minimum update frequency was calculated to %d seconds.\n", freq);
1571 if(netdata_update_every < freq) {
1572 info("enforcing minimum data collection frequency, calculated to %d seconds.", freq);
1573 netdata_update_every = freq;
1577 // ------------------------------------------------------------------------
1580 if(debug) fprintf(stderr, "freeipmi.plugin: starting data collection\n");
1582 time_t started_t = now_monotonic_sec();
1584 size_t iteration = 0;
1585 usec_t step = netdata_update_every * USEC_PER_SEC;
1588 heartbeat_init(&hb);
1589 for(iteration = 0; 1 ; iteration++) {
1590 usec_t dt = heartbeat_next(&hb, step);
1592 if(debug && iteration)
1593 fprintf(stderr, "freeipmi.plugin: iteration %zu, dt %llu usec, sensors collected %zu, sensors sent to netdata %zu \n"
1596 , netdata_sensors_collected
1597 , netdata_sensors_updated
1600 netdata_mark_as_not_updated();
1602 if(debug) fprintf(stderr, "freeipmi.plugin: calling ipmi_collect_data()\n");
1603 if(ipmi_collect_data(&ipmi_config) < 0)
1604 fatal("data collection failed.");
1606 if(debug) fprintf(stderr, "freeipmi.plugin: calling send_metrics_to_netdata()\n");
1607 send_metrics_to_netdata();
1610 // restart check (14400 seconds)
1611 if(now_monotonic_sec() - started_t > 14400) exit(0);
1615 #else // !HAVE_FREEIPMI
1617 int main(int argc, char **argv) {
1618 fatal("freeipmi.plugin is not compiled.");
1621 #endif // !HAVE_FREEIPMI