From 020d944998aa2e55e6c8fcbac31dba0f91871d0a Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Thu, 30 Jul 2026 11:13:41 +0200 Subject: [PATCH] Automatic IOC systemd startup from Power_switch --- CMakeLists.txt | 1 + README.md | 4 ++ src/device/power_switch.cpp | 3 +- src/frontend/power_switch_scfe.cpp | 70 ++++++++++++++++++++++--- src/frontend/power_switch_scfe.h | 7 +++ src/frontend/power_switch_scfe_config.h | 9 ++++ 6 files changed, 86 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a2301f..1ea4d1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ set_property( target_link_libraries( power_switch PRIVATE + /usr/lib64/libsystemd.so midas::mfe m_epics_ca ${LIBS} diff --git a/README.md b/README.md index c51675e..58bf198 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,10 @@ Start it with specified frontend name and equipment name ```bash $ $PWD/build/ePowerSwitchFront ``` +Start it with also a systemd service +```bash +$ $PWD/build/ePowerSwitchFront +``` # Features diff --git a/src/device/power_switch.cpp b/src/device/power_switch.cpp index c9abe92..5dd05f5 100644 --- a/src/device/power_switch.cpp +++ b/src/device/power_switch.cpp @@ -2,9 +2,8 @@ #include "odbxx.h" #include "power_switch_config.h" #include "tmfe.h" -#include - #include +#include /** * @brief Insert a integer value between two string diff --git a/src/frontend/power_switch_scfe.cpp b/src/frontend/power_switch_scfe.cpp index a65d454..79fd1be 100644 --- a/src/frontend/power_switch_scfe.cpp +++ b/src/frontend/power_switch_scfe.cpp @@ -2,6 +2,7 @@ #include "../device/power_switch.h" #include "power_switch_scfe_config.h" #include "tmfe.h" +#include int main(int argc, char *argv[]) { @@ -13,8 +14,10 @@ int main(int argc, char *argv[]) { std::string frontendName; std::string equipmentName; + std::string serviceName; - if (argc == 1) { + switch (argc) { + case 1: frontendName = DEFAULT_FRONTEND_NAME; TMFE::Instance()->Msg(MINFO, __FUNCTION__, "No frontend name provided; %s will be used", @@ -23,22 +26,37 @@ int main(int argc, char *argv[]) { TMFE::Instance()->Msg(MINFO, __FUNCTION__, "No equipment name provided; %s will be used", DEFAULT_EQUIPMENT_NAME); - } - if (argc == 2) { + break; + case 2: frontendName = std::string(argv[1]); argv++; argc--; TMFE::Instance()->Msg(MINFO, __FUNCTION__, "No equipment name provided; %s will be use", DEFAULT_EQUIPMENT_NAME); - } else if (argc == 3) { + break; + case 3: frontendName = std::string(argv[1]); equipmentName = std::string(argv[2]); argv += 2; argc -= 2; + break; + + case 4: + frontendName = std::string(argv[1]); + equipmentName = std::string(argv[2]); + serviceName = std::string(argv[3]); + argv += 3; + argc -= 3; + default: + break; } - auto front = powerSwitchSCFE(frontendName, equipmentName); + auto front = + (serviceName.empty()) + ? powerSwitchSCFE(frontendName, equipmentName) + : powerSwitchSCFE(frontendName, equipmentName, serviceName); + front.FeMain(argc, argv); } @@ -46,4 +64,44 @@ powerSwitchSCFE::powerSwitchSCFE(std::string frontendName, std::string equipmentName) { FeSetName(frontendName.c_str()); FeAddEquipment(new powerSwitch(equipmentName.c_str(), __FILE__)); -} \ No newline at end of file +} + +powerSwitchSCFE::powerSwitchSCFE(std::string frontendName, + std::string equipmentName, + std::string serviceName) { + verifySystemdService(serviceName); + FeSetName(frontendName.c_str()); + FeAddEquipment(new powerSwitch(equipmentName.c_str(), __FILE__)); +} + +void powerSwitchSCFE::verifySystemdService(std::string serviceName) { + sd_bus *bus = nullptr; + sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus_message *reply = nullptr; + + int returnCode = sd_bus_open_system(&bus); + if (returnCode < 0) { + TMFE::Instance()->Msg( + MINFO, __FUNCTION__, + "Systemd d-bus cannot be opened, error code %d - Starting " + "without verifying service current status\n", + returnCode); + } + + returnCode = sd_bus_call_method( + bus, SystemdPathConfig::DBUS_SYSTEMD_DESTINATION.c_str(), + SystemdPathConfig::DBUS_SYSTEMD_PATH.c_str(), + SystemdPathConfig::DBUS_SYSTEMD_INTERFACE_MANAGER.c_str(), "StartUnit", + &error, &reply, "ss", serviceName.c_str(), "replace"); + if (returnCode < 0) { + TMFE::Instance()->Msg( + MERROR, __FUNCTION__, + "Couldn't start %s service, error code %d - Aborting\n", + serviceName.c_str(), returnCode); + exit(-1); + } + + sd_bus_error_free(&error); + sd_bus_message_unref(reply); + sd_bus_flush_close_unref(bus); +} diff --git a/src/frontend/power_switch_scfe.h b/src/frontend/power_switch_scfe.h index 61f1dd6..7ffa5fd 100644 --- a/src/frontend/power_switch_scfe.h +++ b/src/frontend/power_switch_scfe.h @@ -12,6 +12,13 @@ class powerSwitchSCFE : public TMFrontend { * @param equipmentName name shown on Midas for the equipment */ powerSwitchSCFE(std::string frontendName, std::string equipmentName); + powerSwitchSCFE(std::string frontendName, std::string equipmentName, + std::string serviceName); + + private: + /* + */ + void verifySystemdService(std::string serviceName); }; #endif \ No newline at end of file diff --git a/src/frontend/power_switch_scfe_config.h b/src/frontend/power_switch_scfe_config.h index 8569583..9187f15 100644 --- a/src/frontend/power_switch_scfe_config.h +++ b/src/frontend/power_switch_scfe_config.h @@ -3,5 +3,14 @@ #define DEFAULT_FRONTEND_NAME "powerSwitch" #define DEFAULT_EQUIPMENT_NAME "powerSwitch" +#include + +namespace SystemdPathConfig { + +const std::string DBUS_SYSTEMD_DESTINATION = "org.freedesktop.systemd1"; +const std::string DBUS_SYSTEMD_PATH = "/org/freedesktop/systemd1"; +const std::string DBUS_SYSTEMD_INTERFACE_MANAGER = + "org.freedesktop.systemd1.Manager"; +}; // namespace SystemdPathConfig #endif \ No newline at end of file