diff options
author | Yong Li <yong.b.li@linux.intel.com> | 2018-04-12 16:52:35 +0300 |
---|---|---|
committer | Yong Li <yong.b.li@linux.intel.com> | 2018-04-16 12:05:22 +0300 |
commit | 7b96082fa3b11f5f79889e4ac5e734da3afddda6 (patch) | |
tree | 384a0c8e7f16bbd4b629bc95f68f54e765728bb0 /services | |
parent | 49ac43d9cae497fa0755af42bfb33952acbdf445 (diff) | |
download | provingground-7b96082fa3b11f5f79889e4ac5e734da3afddda6.tar.xz |
Implement the chassis power control service using sdbusplus
Implement the below service using sdbusplus, as a replacement:
https://github.com/openbmc/skeleton/blob/master/op-pwrctl/power_control_obj.c
Change-Id: I055b6a3f2a739de0029c068fb66d4236bf77337e
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Diffstat (limited to 'services')
13 files changed, 231 insertions, 291 deletions
diff --git a/services/chassisctl/.clang-format b/services/chassis/PowerControl/.clang-format index 92dc471..92dc471 100644 --- a/services/chassisctl/.clang-format +++ b/services/chassis/PowerControl/.clang-format diff --git a/services/chassis/PowerControl/CMakeLists.txt b/services/chassis/PowerControl/CMakeLists.txt new file mode 100644 index 0000000..cc029ba --- /dev/null +++ b/services/chassis/PowerControl/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR) +project(PowerControl CXX) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH} ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +include(GNUInstallDirs) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc) + +set(DBUS_OBJECT_NAME "xyz/openbmc_project/Chassis/Control/Power") +set(DBUS_INTF_NAME "xyz.openbmc_project.Chassis.Control.Power") + +add_definitions(-DDBUS_OBJECT_NAME="/${DBUS_OBJECT_NAME}") +add_definitions(-DDBUS_INTF_NAME="${DBUS_INTF_NAME}") +set(SRC_FILES + src/PowerControl.cpp + src/timer.cpp + src/main.cpp +) + +# import libsystemd +find_package(PkgConfig REQUIRED) +pkg_check_modules(SYSTEMD libsystemd REQUIRED) +include_directories(${SYSTEMD_INCLUDE_DIRS}) +link_directories(${SYSTEMD_LIBRARY_DIRS}) + +# import sdbusplus +find_package(PkgConfig REQUIRED) +pkg_check_modules(SDBUSPLUSPLUS sdbusplus REQUIRED) +include_directories(${SDBUSPLUSPLUS_INCLUDE_DIRS}) +link_directories(${SDBUSPLUSPLUS_LIBRARY_DIRS}) +find_program(SDBUSPLUSPLUS sdbus++) + +# import phosphor-logging +find_package(PkgConfig REQUIRED) +pkg_check_modules(LOGGING phosphor-logging REQUIRED) +include_directories(${LOGGING_INCLUDE_DIRS}) +link_directories(${LOGGING_LIBRARY_DIRS}) + +# phosphor-dbus-interfaces +find_package(PkgConfig REQUIRED) +pkg_check_modules(DBUSINTERFACE phosphor-dbus-interfaces REQUIRED) +include_directories(${DBUSINTERFACE_INCLUDE_DIRS}) +link_directories(${DBUSINTERFACE_LIBRARY_DIRS}) + +option(ENABLE_GTEST "Enable Google Test" OFF) +if(ENABLE_GTEST) + enable_testing() + find_package(Threads REQUIRED) + find_package(GTest REQUIRED) + include_directories(${GTEST_INCLUDE_DIRS}) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/tests/inc) + add_executable(timertest tests/src/timer_test.cpp src/timer.cpp) + target_link_libraries(timertest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${SDBUSPLUSPLUS_LIBRARIES} ${DBUSINTERFACE_LIBRARIES}) + add_test(NAME timertest COMMAND timertest) +endif() + +add_executable(${PROJECT_NAME} ${SRC_FILES}) +target_link_libraries(${PROJECT_NAME} ${SYSTEMD_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} ${SDBUSPLUSPLUS_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} ${DBUSINTERFACE_LIBRARIES}) + +install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/services/chassis/PowerControl/inc/PowerControl.hpp b/services/chassis/PowerControl/inc/PowerControl.hpp new file mode 100644 index 0000000..c7ccfb9 --- /dev/null +++ b/services/chassis/PowerControl/inc/PowerControl.hpp @@ -0,0 +1,45 @@ +#pragma once +#include <phosphor-logging/elog-errors.hpp> +#include <phosphor-logging/elog.hpp> +#include <phosphor-logging/log.hpp> +#include <xyz/openbmc_project/Chassis/Control/Power/error.hpp> +#include <xyz/openbmc_project/Chassis/Control/Power/server.hpp> +#include <xyz/openbmc_project/Common/error.hpp> +#include <iostream> +#include "timer.hpp" + +static constexpr size_t POLLING_INTERVAL_MS = 500; +using pwr_control = + sdbusplus::xyz::openbmc_project::Chassis::Control::server::Power; + +struct PowerControl : sdbusplus::server::object_t<pwr_control> { + PowerControl(sdbusplus::bus::bus& bus, const char* path, + phosphor::watchdog::EventPtr event) + : sdbusplus::server::object_t<pwr_control>(bus, path), + bus(bus), + timer(event, std::bind(&PowerControl::timeOutHandler, this)) { + timer.start(std::chrono::duration_cast<std::chrono::microseconds>( + std::chrono::milliseconds(POLLING_INTERVAL_MS))); + timer.setEnabled<std::true_type>(); + phosphor::logging::log<phosphor::logging::level::DEBUG>("Enable timer"); + } + + void timeOutHandler() { + phosphor::logging::log<phosphor::logging::level::DEBUG>( + "timeOutHandler..."); + + // TODO polling acpi status + + this->timer.start(std::chrono::duration_cast<std::chrono::microseconds>( + std::chrono::milliseconds(POLLING_INTERVAL_MS))); + this->timer.setEnabled<std::true_type>(); + } + + int32_t forcePowerOff() override; + int32_t setPowerState(int32_t newState) override; + int32_t getPowerState() override; + + private: + phosphor::watchdog::Timer timer; + sdbusplus::bus::bus& bus; +}; diff --git a/services/chassisctl/include/timer.hpp b/services/chassis/PowerControl/inc/timer.hpp index a6a6108..3aa0f87 100644 --- a/services/chassisctl/include/timer.hpp +++ b/services/chassis/PowerControl/inc/timer.hpp @@ -1,5 +1,6 @@ #pragma once +#include <functional> #include <memory> #include <chrono> #include <systemd/sd-event.h> diff --git a/services/chassis/PowerControl/src/PowerControl.cpp b/services/chassis/PowerControl/src/PowerControl.cpp new file mode 100644 index 0000000..b6bf5e1 --- /dev/null +++ b/services/chassis/PowerControl/src/PowerControl.cpp @@ -0,0 +1,31 @@ +/* +// Copyright (c) 2018 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ +#include "PowerControl.hpp" + +int32_t PowerControl::forcePowerOff() { + // TODO + throw sdbusplus::xyz::openbmc_project::Chassis::Control::Power::Error:: + UnsupportedCommand(); + return 0; +} + +int32_t PowerControl::setPowerState(int32_t newState) { + // TODO + state(newState); + return 0; +} + +int32_t PowerControl::getPowerState() { return state(); } diff --git a/services/chassis/PowerControl/src/main.cpp b/services/chassis/PowerControl/src/main.cpp new file mode 100644 index 0000000..f9216d8 --- /dev/null +++ b/services/chassis/PowerControl/src/main.cpp @@ -0,0 +1,74 @@ +/* +// Copyright (c) 2018 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <systemd/sd-event.h> +#include <unistd.h> +#include <phosphor-logging/elog-errors.hpp> +#include <phosphor-logging/elog.hpp> +#include <phosphor-logging/log.hpp> +#include <xyz/openbmc_project/Common/error.hpp> +#include <chrono> +#include <experimental/filesystem> +#include <fstream> +#include <iostream> +#include "PowerControl.hpp" + +int main(int argc, char* argv[]) { + int ret = 0; + + phosphor::logging::log<phosphor::logging::level::INFO>( + "Start Chassis power control service..."); + + sd_event* event = nullptr; + ret = sd_event_default(&event); + if (ret < 0) { + phosphor::logging::log<phosphor::logging::level::ERR>( + "Error creating a default sd_event handler"); + return ret; + } + phosphor::watchdog::EventPtr eventP{event, + phosphor::watchdog::EventDeleter()}; + event = nullptr; + + auto bus = sdbusplus::bus::new_default(); + sdbusplus::server::manager_t m{bus, DBUS_OBJECT_NAME}; + + bus.request_name(DBUS_INTF_NAME); + + PowerControl powerControl{bus, DBUS_OBJECT_NAME, eventP}; + + auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>( + std::chrono::system_clock::now()); + + try { + bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL); + while (true) { + ret = sd_event_run(eventP.get(), (uint64_t)-1); + if (ret < 0) { + phosphor::logging::log<phosphor::logging::level::ERR>( + "Error waiting for events"); + } + } + } + + catch (std::exception& e) { + phosphor::logging::log<phosphor::logging::level::ERR>(e.what()); + return -1; + } + return 0; +} diff --git a/services/chassisctl/src/timer.cpp b/services/chassis/PowerControl/src/timer.cpp index 2825855..f562f92 100644 --- a/services/chassisctl/src/timer.cpp +++ b/services/chassis/PowerControl/src/timer.cpp @@ -1,3 +1,18 @@ +/** + * Copyright © 2017 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include <chrono> #include <systemd/sd-event.h> #include <phosphor-logging/log.hpp> diff --git a/services/chassisctl/tests/include/timer_test.hpp b/services/chassis/PowerControl/tests/inc/timer_test.hpp index 85c443f..85c443f 100644 --- a/services/chassisctl/tests/include/timer_test.hpp +++ b/services/chassis/PowerControl/tests/inc/timer_test.hpp diff --git a/services/chassisctl/tests/src/timer_test.cpp b/services/chassis/PowerControl/tests/src/timer_test.cpp index e9f323b..e9f323b 100644 --- a/services/chassisctl/tests/src/timer_test.cpp +++ b/services/chassis/PowerControl/tests/src/timer_test.cpp diff --git a/services/chassisctl/CMakeLists.txt b/services/chassisctl/CMakeLists.txt deleted file mode 100644 index fdd65c2..0000000 --- a/services/chassisctl/CMakeLists.txt +++ /dev/null @@ -1,93 +0,0 @@ -cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR) -project(chassisctld CXX) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -include(GNUInstallDirs) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -set(DBUS_OBJECT_NAME "org/openbmc/control/Power") -set(DBUS_INTF_NAME "org.openbmc.control.Power") - -set(SRC_FILES - src/chassisctld.cpp - src/timer.cpp -) -set(GENERATED_SRC_FILES - ${DBUS_OBJECT_NAME}/error.cpp - ${DBUS_OBJECT_NAME}/server.cpp -) - -# import libsystemd -find_package(PkgConfig REQUIRED) -pkg_check_modules(SYSTEMD libsystemd REQUIRED) -include_directories(${SYSTEMD_INCLUDE_DIRS}) -link_directories(${SYSTEMD_LIBRARY_DIRS}) - -# import sdbusplus -find_package(PkgConfig REQUIRED) -pkg_check_modules(SDBUSPLUSPLUS sdbusplus REQUIRED) -include_directories(${SDBUSPLUSPLUS_INCLUDE_DIRS}) -link_directories(${SDBUSPLUSPLUS_LIBRARY_DIRS}) -find_program(SDBUSPLUSPLUS sdbus++) - -# import phosphor-logging -find_package(PkgConfig REQUIRED) -pkg_check_modules(LOGGING phosphor-logging REQUIRED) -include_directories(${LOGGING_INCLUDE_DIRS}) -link_directories(${LOGGING_LIBRARY_DIRS}) - -# phosphor-dbus-interfaces -find_package(PkgConfig REQUIRED) -pkg_check_modules(DBUSINTERFACE phosphor-dbus-interfaces REQUIRED) -include_directories(${DBUSINTERFACE_INCLUDE_DIRS}) -link_directories(${DBUSINTERFACE_LIBRARY_DIRS}) - -include_directories(${CMAKE_CURRENT_BINARY_DIR}/${DBUS_OBJECT_NAME}) - -option(ENABLE_GTEST "Enable Google Test" ON) -if(ENABLE_GTEST) - enable_testing() - find_package(Threads REQUIRED) - find_package(GTest REQUIRED) - include_directories(${GTEST_INCLUDE_DIRS}) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/tests/include) - add_executable(timertest tests/src/timer_test.cpp src/timer.cpp) - target_link_libraries(timertest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${SDBUSPLUSPLUS_LIBRARIES} ${DBUSINTERFACE_LIBRARIES}) - add_test(NAME timertest COMMAND timertest) -endif() - -add_custom_command( - OUTPUT ${DBUS_OBJECT_NAME}/error.hpp - OUTPUT ${DBUS_OBJECT_NAME}/error.cpp - COMMAND mkdir -p ${DBUS_OBJECT_NAME} - COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} error exception-header ${DBUS_INTF_NAME} > ${DBUS_OBJECT_NAME}/error.hpp - COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} error exception-cpp ${DBUS_INTF_NAME} > ${DBUS_OBJECT_NAME}/error.cpp - DEPENDS ${DBUS_OBJECT_NAME}.errors.yaml -) -set_source_files_properties( - ${DBUS_OBJECT_NAME}/error.hpp - ${DBUS_OBJECT_NAME}/error.cpp - PROPERTIES GENERATED TRUE) - -add_custom_command( - OUTPUT ${DBUS_OBJECT_NAME}/server.hpp - OUTPUT ${DBUS_OBJECT_NAME}/server.cpp - COMMAND mkdir -p ${DBUS_OBJECT_NAME} - COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} interface server-header ${DBUS_INTF_NAME} > ${DBUS_OBJECT_NAME}/server.hpp - COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} interface server-cpp ${DBUS_INTF_NAME} > ${DBUS_OBJECT_NAME}/server.cpp - DEPENDS ${DBUS_OBJECT_NAME}.interface.yaml -) -set_source_files_properties( - ${DBUS_OBJECT_NAME}/server.hpp - ${DBUS_OBJECT_NAME}/server.cpp - PROPERTIES GENERATED TRUE) - -add_executable(${PROJECT_NAME} ${SRC_FILES} ${GENERATED_SRC_FILES}) -target_link_libraries(${PROJECT_NAME} ${SYSTEMD_LIBRARIES}) -target_link_libraries(${PROJECT_NAME} ${SDBUSPLUSPLUS_LIBRARIES}) -target_link_libraries(${PROJECT_NAME} ${DBUSINTERFACE_LIBRARIES}) - -install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/services/chassisctl/org/openbmc/control/Power.errors.yaml b/services/chassisctl/org/openbmc/control/Power.errors.yaml deleted file mode 100644 index 9de4b9d..0000000 --- a/services/chassisctl/org/openbmc/control/Power.errors.yaml +++ /dev/null @@ -1,9 +0,0 @@ -- name: UnsupportedCommand - description: > - An unsupported command was attempted. -- name: InvalidParameter - description: > - An invalid parameter was attempted. -- name: IOError - description: > - An IO error occurred. diff --git a/services/chassisctl/org/openbmc/control/Power.interface.yaml b/services/chassisctl/org/openbmc/control/Power.interface.yaml deleted file mode 100644 index 3334fd6..0000000 --- a/services/chassisctl/org/openbmc/control/Power.interface.yaml +++ /dev/null @@ -1,75 +0,0 @@ -description: > - Chassis control service -methods: - - name: SetPowerState - description: > - set host power state. - parameters: - - name: state - type: uint32 - description: > - host state - returns: - - name: status - type: uint32 - description: > - The result of command. - errors: - - self.Error.UnsupportedCommand - - self.Error.InvalidParameter - - self.Error.IOError - - - name: GetPowerState - description: > - Power off the host. - returns: - - name: status - type: uint32 - description: > - The result of power off command. - errors: - - self.Error.UnsupportedCommand - - self.Error.InvalidParameter - - self.Error.IOError - - - name: ForcePowerOff - description: > - Power off the host. - returns: - - name: status - type: uint32 - description: > - The result of power off command. - errors: - - self.Error.UnsupportedCommand - - self.Error.InvalidParameter - - self.Error.IOError - -properties: - - name: pgood - type: uint32 - default: 0 - description: > - pgood property - - name: state - type: uint32 - default: 0 - description: > - state property - - name: pgood_timeout - type: uint32 - default: 0 - description: > - pgoodtimeout property -signals: - - name: PowerGood - description: > - Signal for powergood - - name: PowerLost - description: > - Signal for powerlost - - name: GotoSystemState - description: > - Signal for GotoSystemState - properties: - - type: string
\ No newline at end of file diff --git a/services/chassisctl/src/chassisctld.cpp b/services/chassisctl/src/chassisctld.cpp deleted file mode 100644 index 28a65cd..0000000 --- a/services/chassisctl/src/chassisctld.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* -// Copyright (c) 2017 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -*/ -#include <phosphor-logging/elog-errors.hpp> -#include <phosphor-logging/elog.hpp> -#include <phosphor-logging/log.hpp> -#include <xyz/openbmc_project/Common/error.hpp> - -#include <error.hpp> -#include <server.hpp> -#include <chrono> - -#include "timer.hpp" - -namespace Log = phosphor::logging; -namespace Watchdog = phosphor::watchdog; - -using Chassisctl_inherit = sdbusplus::server::object_t< - sdbusplus::org::openbmc::control::server::Power>; - -struct Chassisctl : Chassisctl_inherit { - Chassisctl(sdbusplus::bus::bus& bus, const char* path, - Watchdog::EventPtr event) - : Chassisctl_inherit(bus, path), - bus(bus), - timer(event, std::bind(&Chassisctl::timeOutHandler, this)) { - timer.start(std::chrono::duration_cast<std::chrono::microseconds>( - std::chrono::milliseconds(500))); - timer.setEnabled<std::true_type>(); - Log::log<Log::level::DEBUG>("Enable timer"); - } - - uint32_t forcePowerOff() override { - // TODO - throw sdbusplus::org::openbmc::control::Power::Error::UnsupportedCommand(); - return 0; - } - - uint32_t setPowerState(uint32_t newState) override { - state(newState); - return 0; - } - - uint32_t getPowerState() override { return state(); } - - void timeOutHandler() { - Log::log<Log::level::DEBUG>("timeOutHandler..."); - // TODO check acpi status - } - - Watchdog::Timer timer; - - private: - sdbusplus::bus::bus& bus; -}; - -int main(int argc, char* argv[]) { - int ret = 0; - - Log::log<Log::level::INFO>("Start Chassis service..."); - - constexpr const char* path = "/org/openbmc/control/power0"; - - sd_event* event = nullptr; - ret = sd_event_default(&event); - if (ret < 0) { - Log::log<Log::level::ERR>("Error creating a default sd_event handler"); - return ret; - } - Watchdog::EventPtr eventP{event, Watchdog::EventDeleter()}; - event = nullptr; - - auto bus = sdbusplus::bus::new_default(); - sdbusplus::server::manager_t m{bus, path}; - - bus.request_name("org.openbmc.control.Power"); - - Chassisctl c1{bus, path, eventP}; - - try { - bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL); - - while (true) { - ret = sd_event_run(eventP.get(), (uint64_t)-1); - if (ret < 0) { - Log::log<Log::level::ERR>("Error waiting for events"); - } - if (c1.timer.expired()) { - Log::log<Log::level::DEBUG>("timer expired restart..."); - c1.timer.start(std::chrono::duration_cast<std::chrono::microseconds>( - std::chrono::milliseconds(1000 * 1))); - c1.timer.setEnabled<std::true_type>(); - } - } - } - - catch (std::exception& e) { - Log::log<Log::level::ERR>(e.what()); - return -1; - } - return 0; -} |