add ipmi fan controll support

This commit is contained in:
Carl Philipp Klemm 2023-05-02 18:58:52 +02:00
parent f213a52570
commit 913cea1603
2 changed files with 51 additions and 7 deletions

View File

@ -7,11 +7,12 @@ set(CMAKE_CXX_STANDARD 20)
find_package(Doxygen) find_package(Doxygen)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_search_module(IPMI REQUIRED libipmimonitoring) pkg_search_module(IPMI_MONITORING REQUIRED libipmimonitoring)
pkg_search_module(IPMI REQUIRED libfreeipmi)
add_executable(${PROJECT_NAME} main.cpp ipmi.cpp lm.cpp) add_executable(${PROJECT_NAME} main.cpp ipmi.cpp lm.cpp)
target_link_libraries(${PROJECT_NAME} ${IPMI_LINK_LIBRARIES} ${IPMIPOSIX_LINK_LIBRARIES} sensors) target_link_libraries(${PROJECT_NAME} ${IPMI_LINK_LIBRARIES} ${IPMI_MONITORING_LINK_LIBRARIES} sensors)
target_include_directories(${PROJECT_NAME} PRIVATE ${IPMI_INCLUDE_DIRS} ${IPMIPOSIX_INCLUDE_DIRS}) target_include_directories(${PROJECT_NAME} PRIVATE ${IPMI_INCLUDE_DIRS} ${IPMI_MONITORING_INCLUDE_DIRS})
target_compile_options(${PROJECT_NAME} PRIVATE "-Wall" "-O2" "-g" "-fno-strict-aliasing" "-Wfatal-errors" "-Wno-reorder") target_compile_options(${PROJECT_NAME} PRIVATE "-Wall" "-O2" "-g" "-fno-strict-aliasing" "-Wfatal-errors" "-Wno-reorder")
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)

View File

@ -1,3 +1,6 @@
#include <cstddef>
#include <cstdint>
#include <freeipmi/api/ipmi-api.h>
#include <vector> #include <vector>
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -7,10 +10,13 @@
#include <sensors/error.h> #include <sensors/error.h>
#include <signal.h> #include <signal.h>
#include <limits> #include <limits>
#include <freeipmi/freeipmi.h>
#include "ipmi.h" #include "ipmi.h"
#include "lm.h" #include "lm.h"
static constexpr size_t IPMI_RAW_MAX_ARGS = 65536*2;
sig_atomic_t running = true; sig_atomic_t running = true;
void sig_handler(int sig) void sig_handler(int sig)
@ -108,6 +114,35 @@ std::vector<double> get_fan_zones(const std::vector<Sensor>& sensors)
return out; return out;
} }
ipmi_ctx_t ipmi_open()
{
ipmi_ctx_t ctx = nullptr;
ipmi_driver_type_t driver = IPMI_DEVICE_OPENIPMI;
int ret = ipmi_ctx_find_inband(ctx, &driver, false, 0, 0, nullptr, 0, 0);
if(ret < 0)
{
std::cerr<<"Could not create raw context "<<ipmi_ctx_errormsg(ctx)<<'\n';
return nullptr;
}
return ctx;
}
bool ipmi_set_fan_group(ipmi_ctx_t raw_ctx, uint8_t group, double speed)
{
char converted_speed = std::min(std::max(static_cast<char>(64), static_cast<char>(speed*64)), static_cast<char>(0));
char command[] = {0x70, 0x66, 0x01, static_cast<char>(group), converted_speed};
char bytesrx[IPMI_RAW_MAX_ARGS] = {0};
int rxlen = ipmi_cmd_raw(raw_ctx, 0, 0x30, command, sizeof(command), bytesrx, IPMI_RAW_MAX_ARGS);
if(rxlen < 0)
{
std::cerr<<"Raw write to ipmi failed with: "<<ipmi_ctx_errormsg(raw_ctx);
return false;
}
return true;
}
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
signal(SIGABRT, sig_handler); signal(SIGABRT, sig_handler);
@ -126,20 +161,28 @@ int main (int argc, char **argv)
ipmi_sensors.push_back(Sensor("IPMI", "CPU Temp")); ipmi_sensors.push_back(Sensor("IPMI", "CPU Temp"));
ipmi_sensors.push_back(Sensor("IPMI", "System Temp")); ipmi_sensors.push_back(Sensor("IPMI", "System Temp"));
ipmi_monitoring_ctx_t ctx = init_ipmi_monitoring(); ipmi_monitoring_ctx_t monitoring_ctx = init_ipmi_monitoring();
if(!ctx) if(!monitoring_ctx)
return 1; return 1;
ipmi_ctx_t raw_ctx = ipmi_open();
if(!raw_ctx)
return 1;
while(running) while(running)
{ {
std::vector<Sensor> sensors = gather_sensors(ipmi_sensors, ctx, lm_chips); std::vector<Sensor> sensors = gather_sensors(ipmi_sensors, monitoring_ctx, lm_chips);
std::vector<double> fanzones = get_fan_zones(sensors); std::vector<double> fanzones = get_fan_zones(sensors);
for(const double fanzone : fanzones) for(const double fanzone : fanzones)
std::cout<<fanzone<<'\n'; std::cout<<fanzone<<'\n';
sleep(1); sleep(1);
} }
ipmi_monitoring_ctx_destroy(ctx); ipmi_ctx_close(raw_ctx);
ipmi_ctx_destroy(raw_ctx);
ipmi_monitoring_ctx_destroy(monitoring_ctx);
sensors_cleanup(); sensors_cleanup();
return 0; return 0;
} }