From 9c17bfe0bfc0bb55507ec2a6d30e703f685de8f4 Mon Sep 17 00:00:00 2001 From: Carl Philipp Klemm Date: Tue, 2 May 2023 10:52:56 +0200 Subject: [PATCH] sensor monitoring compleat, starting on fan control --- CMakeLists.txt | 2 +- ipmi.cpp | 1 + lm.cpp | 63 ++++++++++++++++++++++++++ lm.h | 12 +++++ main.cpp | 118 +++++++++++++++++++++---------------------------- sensor.h | 4 +- 6 files changed, 130 insertions(+), 70 deletions(-) create mode 100644 lm.cpp create mode 100644 lm.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ac7d40a..4eb83d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ find_package(Doxygen) find_package(PkgConfig REQUIRED) pkg_search_module(IPMI REQUIRED libipmimonitoring) -add_executable(${PROJECT_NAME} main.cpp ipmi.cpp) +add_executable(${PROJECT_NAME} main.cpp ipmi.cpp lm.cpp) target_link_libraries(${PROJECT_NAME} ${IPMI_LINK_LIBRARIES} ${IPMIPOSIX_LINK_LIBRARIES} sensors) target_include_directories(${PROJECT_NAME} PRIVATE ${IPMI_INCLUDE_DIRS} ${IPMIPOSIX_INCLUDE_DIRS}) target_compile_options(${PROJECT_NAME} PRIVATE "-Wall" "-O2" "-g" "-fno-strict-aliasing" "-Wfatal-errors" "-Wno-reorder") diff --git a/ipmi.cpp b/ipmi.cpp index 8fd1e9c..ed4a024 100644 --- a/ipmi.cpp +++ b/ipmi.cpp @@ -16,6 +16,7 @@ static double ipmi_convert_sensor_reading(void *sensor_reading, int sensor_readi Sensor ipmi_read_sensor_from_ctx(ipmi_monitoring_ctx_t ctx) { Sensor sensor; + sensor.chip = "IPMI"; int record_id = ipmi_monitoring_sensor_read_record_id(ctx); int reading_type = ipmi_monitoring_sensor_read_sensor_reading_type(ctx); char *name = ipmi_monitoring_sensor_read_sensor_name(ctx); diff --git a/lm.cpp b/lm.cpp new file mode 100644 index 0000000..b474ac3 --- /dev/null +++ b/lm.cpp @@ -0,0 +1,63 @@ +#include "lm.h" + +std::vector lm_get_chips(const std::string& match) +{ + std::vector out; + + sensors_chip_name name_glob; + int ret = sensors_parse_chip_name(match.c_str(), &name_glob); + if(ret < 0) + { + std::cerr<<"could not parse chip name\n"; + return out; + } + + const sensors_chip_name* s_name; + int nr = 0; + do + { + s_name = sensors_get_detected_chips(&name_glob, &nr); + if(s_name) + out.push_back(s_name); + } while(s_name); + sensors_free_chip_name(&name_glob); + + return out; +} + +std::vector lm_get_temperatures(std::vector& chips) +{ + std::vector out; + + for(const sensors_chip_name* chip : chips) + { + int nr = 0; + const sensors_feature* feature; + while((feature = sensors_get_features(chip, &nr))) + { + if(feature->type != SENSORS_FEATURE_TEMP) + continue; + const sensors_subfeature* subfeature = sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_INPUT); + if(!subfeature) + { + std::cerr<<"could not read subfeature\n"; + continue; + } + + double val = 0; + int ret = sensors_get_value(chip, subfeature->number, &val); + if(ret < 0) + { + std::cerr<<"unable to read temperature for subfeature " + <number<<' '<name<<": "<number; + sensor.reading = val; + out.push_back(sensor); + } + } + return out; +} diff --git a/lm.h b/lm.h new file mode 100644 index 0000000..faec7c3 --- /dev/null +++ b/lm.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "sensor.h" + +std::vector lm_get_chips(const std::string& match); +std::vector lm_get_temperatures(std::vector& chips); diff --git a/main.cpp b/main.cpp index c631445..0c59648 100644 --- a/main.cpp +++ b/main.cpp @@ -5,73 +5,71 @@ #include #include #include +#include #include "ipmi.h" +#include "lm.h" -std::vector lm_get_chips(const std::string& match) +sig_atomic_t running = true; + +void sig_handler(int sig) { - std::vector out; + (void)sig; + running = false; +} - sensors_chip_name name_glob; - int ret = sensors_parse_chip_name(match.c_str(), &name_glob); - if(ret < 0) +std::vector gather_sensors(std::vector& ipmi_sensors, ipmi_monitoring_ctx_t ctx, std::vector& lm_chips) +{ + std::vector out; + struct ipmi_monitoring_ipmi_config ipmi_config = {}; + ipmi_config.driver_type = IPMI_MONITORING_DRIVER_TYPE_OPENIPMI; + + bool grabids = false; + for(Sensor& sensor : ipmi_sensors) { - std::cerr<<"could not parse chip name\n"; - return out; + if(sensor.id <= 0) + { + grabids = true; + break; + } } - const sensors_chip_name* s_name; - int nr = 0; - do + if(grabids) { - s_name = sensors_get_detected_chips(&name_glob, &nr); - if(s_name) - out.push_back(s_name); - } while(s_name); - sensors_free_chip_name(&name_glob); + if(!ipmi_fill_sensor_ids(ipmi_sensors, ctx, &ipmi_config)) + { + std::cout<<"could not get ids for all the required sensors\n"; + return out; + } + } + else + { + ipmi_update_sensors(ipmi_sensors, ctx, &ipmi_config); + } + + out.insert(out.end(), ipmi_sensors.begin(), ipmi_sensors.end()); + std::vector lm_sensors = lm_get_temperatures(lm_chips); + out.insert(out.end(), lm_sensors.begin(), lm_sensors.end()); return out; } -std::vector lm_get_sensors(std::vector& chips) +std::vector get_fan_zones(const std::vector& sensors) { - std::vector out; + std::vector out; - for(const sensors_chip_name* chip : chips) - { - int nr = 0; - const sensors_feature* feature; - while((feature = sensors_get_features(chip, &nr))) - { - if(feature->type != SENSORS_FEATURE_TEMP) - continue; - const sensors_subfeature* subfeature = sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_INPUT); - if(!subfeature) - { - std::cerr<<"could not read subfeature\n"; - continue; - } + for(const Sensor& sensor : sensors) + std::cout<number, &val); - if(ret < 0) - { - std::cerr<<"unable to read temperature for subfeature " - <number<<' '<name<<": "<number; - sensor.reading = val; - out.push_back(sensor); - } - } return out; } int main (int argc, char **argv) { + signal(SIGABRT, sig_handler); + signal(SIGTERM, sig_handler); + signal(SIGHUP, sig_handler); + signal(SIGINT, sig_handler); int ret = sensors_init(nullptr); if(ret < 0) @@ -80,34 +78,18 @@ int main (int argc, char **argv) } std::vector lm_chips = lm_get_chips("amdgpu-*"); - std::vector lmsensors = lm_get_sensors(lm_chips); - - for(const Sensor& sensor : lmsensors) - { - std::cout< sensors; - sensors.push_back(Sensor("CPU Temp")); - sensors.push_back(Sensor("System Temp")); + std::vector ipmi_sensors; + ipmi_sensors.push_back(Sensor("IPMI", "CPU Temp")); + ipmi_sensors.push_back(Sensor("IPMI", "System Temp")); ipmi_monitoring_ctx_t ctx = init_ipmi_monitoring(); if(!ctx) return 1; - if(!ipmi_fill_sensor_ids(sensors, ctx, &ipmi_config)) + while(running) { - std::cout<<"could not get ids for all the required sensors\n"; - return 1; - } - - while(true) - { - ipmi_update_sensors(sensors, ctx, &ipmi_config); - std::cout< sensors = gather_sensors(ipmi_sensors, ctx, lm_chips); + get_fan_zones(sensors); sleep(1); } diff --git a/sensor.h b/sensor.h index 59a4b04..4884c97 100644 --- a/sensor.h +++ b/sensor.h @@ -1,3 +1,5 @@ +#pragma once + #include class Sensor @@ -10,6 +12,6 @@ public: public: Sensor() = default; - Sensor(std::string chipI, std::string nameI, int idI = 0): name(nameI), chip(chipI), name(nameI), id(idI) {} + Sensor(std::string chipI, std::string nameI, int idI = 0): name(nameI), chip(chipI), id(idI) {} bool operator==(const Sensor& other) {return other.name == name && other.chip == chip;} };