diff options
author | James Feist <james.feist@linux.intel.com> | 2019-02-06 23:38:50 +0300 |
---|---|---|
committer | Feist, James <james.feist@intel.com> | 2019-02-12 20:06:35 +0300 |
commit | 41f20f7d2f46a8e0ea785292b06ba399ada31255 (patch) | |
tree | 5a500e721865b8afa45538f3b624eab7785a36cc /callback-manager | |
parent | 267b0e891f98e055c6c59c8d903cee73131cb9c9 (diff) | |
download | provingground-41f20f7d2f46a8e0ea785292b06ba399ada31255.tar.xz |
Add callback manager
Callback manager setups matches and sets properties on
dbus.
Tested-by: used sensor override to make sensors assert
critical and warning interfaces and saw led change. also
caught a few buggy threshold settings using led.
Change-Id: I06c164b749febbc3e81cb3db5f7a0a2b72b3678f
Signed-off-by: James Feist <james.feist@linux.intel.com>
Diffstat (limited to 'callback-manager')
-rw-r--r-- | callback-manager/.clang-format | 99 | ||||
-rw-r--r-- | callback-manager/.gitignore | 3 | ||||
-rw-r--r-- | callback-manager/CMakeLists.txt | 74 | ||||
-rw-r--r-- | callback-manager/LICENCE | 13 | ||||
-rw-r--r-- | callback-manager/cmake-format.json | 13 | ||||
-rw-r--r-- | callback-manager/service_files/callback-manager.service | 13 | ||||
-rw-r--r-- | callback-manager/src/.clang-format | 99 | ||||
-rw-r--r-- | callback-manager/src/callback_manager.cpp | 202 |
8 files changed, 516 insertions, 0 deletions
diff --git a/callback-manager/.clang-format b/callback-manager/.clang-format new file mode 100644 index 0000000..ea71ad6 --- /dev/null +++ b/callback-manager/.clang-format @@ -0,0 +1,99 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +PointerAlignment: Left +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^[<"](gtest|gmock)' + Priority: 5 + - Regex: '^"config.h"' + Priority: -1 + - Regex: '^".*\.hpp"' + Priority: 1 + - Regex: '^<.*\.h>' + Priority: 2 + - Regex: '^<.*' + Priority: 3 + - Regex: '.*' + Priority: 4 +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... + diff --git a/callback-manager/.gitignore b/callback-manager/.gitignore new file mode 100644 index 0000000..0cb1d79 --- /dev/null +++ b/callback-manager/.gitignore @@ -0,0 +1,3 @@ +build/* +oe-logs +oe-workdir diff --git a/callback-manager/CMakeLists.txt b/callback-manager/CMakeLists.txt new file mode 100644 index 0000000..80a3dcc --- /dev/null +++ b/callback-manager/CMakeLists.txt @@ -0,0 +1,74 @@ +cmake_minimum_required (VERSION 3.1 FATAL_ERROR) +set (BUILD_SHARED_LIBRARIES OFF) +include (ExternalProject) +set (CMAKE_CXX_STANDARD 17) +set (CMAKE_CXX_STANDARD_REQUIRED ON) +set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti") + +option (YOCTO "Enable Building in Yocto" OFF) + +if (NOT YOCTO) + externalproject_add ( + Boost URL + https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz + URL_MD5 d275cd85b00022313c171f602db59fc5 SOURCE_DIR + "${CMAKE_BINARY_DIR}/boost-src" BINARY_DIR + "${CMAKE_BINARY_DIR}/boost-build" CONFIGURE_COMMAND "" BUILD_COMMAND "" + INSTALL_COMMAND mkdir -p "${CMAKE_BINARY_DIR}/prefix/include/" && cp -R + ${CMAKE_BINARY_DIR}/boost-src/boost ${CMAKE_BINARY_DIR}/prefix/include + ) # requires apt install autoconf-archive and autoconf + externalproject_add (sdbusplus-project PREFIX + ${CMAKE_BINARY_DIR}/sdbusplus-project GIT_REPOSITORY + https://github.com/openbmc/sdbusplus.git GIT_TAG + bed15f0cee4784acdf151cca14efdfb98cb9d397 SOURCE_DIR + ${CMAKE_BINARY_DIR}/sdbusplus-src BINARY_DIR + ${CMAKE_BINARY_DIR}/sdbusplus-build CONFIGURE_COMMAND + "" BUILD_COMMAND cd ${CMAKE_BINARY_DIR}/sdbusplus-src + && ./bootstrap.sh && ./configure --enable-transaction + && make -j libsdbusplus.la INSTALL_COMMAND "" + LOG_DOWNLOAD ON) + + include_directories (${CMAKE_BINARY_DIR}/sdbusplus-src) + include_directories (${CMAKE_BINARY_DIR}/nlohmann/include) + include_directories (${CMAKE_BINARY_DIR}/nlohmann/include/nlohmann) + include_directories (${CMAKE_BINARY_DIR}/phosphor-dbus-interfaces/include) + link_directories (${CMAKE_BINARY_DIR}/sdbusplus-src/.libs) + + include_directories (${CMAKE_BINARY_DIR}/boost-src) + set (CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/boost-src ${CMAKE_PREFIX_PATH}) + option (ENABLE_TEST "Enable Google Test" OFF) + if (ENABLE_TEST) + hunter_add_package (GTest) + find_package (GTest CONFIG REQUIRED) + enable_testing () + endif () +endif () + +add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY) +add_definitions (-DBOOST_SYSTEM_NO_DEPRECATED) +add_definitions (-DBOOST_ALL_NO_LIB) +add_definitions (-DBOOST_NO_RTTI) +add_definitions (-DBOOST_NO_TYPEID) +add_definitions (-DBOOST_ASIO_DISABLE_THREADS) + +include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include) +include_directories (${Boost_INCLUDE_DIRS}) +include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include) + +add_executable (callback-manager src/callback_manager.cpp) + +target_link_libraries (callback-manager -lsystemd) +target_link_libraries (callback-manager stdc++fs) +target_link_libraries (callback-manager ${Boost_LIBRARIES}) +target_link_libraries (callback-manager sdbusplus) + +if (NOT YOCTO) + add_dependencies (callback-manager sdbusplus-project) +endif () + +set (SERVICE_FILES ${PROJECT_SOURCE_DIR}/service_files/callback-manager.service) + +install (TARGETS callback-manager DESTINATION sbin) +install (FILES ${SERVICE_FILES} DESTINATION /lib/systemd/system/) diff --git a/callback-manager/LICENCE b/callback-manager/LICENCE new file mode 100644 index 0000000..729f4d4 --- /dev/null +++ b/callback-manager/LICENCE @@ -0,0 +1,13 @@ +Copyright 2019 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. diff --git a/callback-manager/cmake-format.json b/callback-manager/cmake-format.json new file mode 100644 index 0000000..4a68fb7 --- /dev/null +++ b/callback-manager/cmake-format.json @@ -0,0 +1,13 @@ +{ + "enum_char": ".", + "line_ending": "unix", + "bullet_char": "*", + "max_subargs_per_line": 99, + "command_case": "lower", + "tab_size": 4, + "line_width": 80, + "separate_fn_name_with_space": true, + "dangle_parens": true, + "separate_ctrl_name_with_space": true +} + diff --git a/callback-manager/service_files/callback-manager.service b/callback-manager/service_files/callback-manager.service new file mode 100644 index 0000000..b6abae3 --- /dev/null +++ b/callback-manager/service_files/callback-manager.service @@ -0,0 +1,13 @@ +[Unit] +Description=Callback Manager +StopWhenUnneeded=false + +[Service] +Type=dbus +BusName=xyz.openbmc_project.CallbackManager +Restart=always +RestartSec=5 +ExecStart=/usr/sbin/callback-manager + +[Install] +WantedBy=multi-user.target diff --git a/callback-manager/src/.clang-format b/callback-manager/src/.clang-format new file mode 100644 index 0000000..ea71ad6 --- /dev/null +++ b/callback-manager/src/.clang-format @@ -0,0 +1,99 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +PointerAlignment: Left +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^[<"](gtest|gmock)' + Priority: 5 + - Regex: '^"config.h"' + Priority: -1 + - Regex: '^".*\.hpp"' + Priority: 1 + - Regex: '^<.*\.h>' + Priority: 2 + - Regex: '^<.*' + Priority: 3 + - Regex: '.*' + Priority: 4 +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... + diff --git a/callback-manager/src/callback_manager.cpp b/callback-manager/src/callback_manager.cpp new file mode 100644 index 0000000..706c607 --- /dev/null +++ b/callback-manager/src/callback_manager.cpp @@ -0,0 +1,202 @@ +/* +// Copyright (c) 2019 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 <boost/container/flat_map.hpp> +#include <iostream> +#include <sdbusplus/asio/connection.hpp> +#include <sdbusplus/asio/object_server.hpp> +#include <variant> + +constexpr const char* fatalLedPath = + "/xyz/openbmc_project/led/groups/status_critical"; +constexpr const char* criticalLedPath = + "/xyz/openbmc_project/led/groups/status_non_critical"; +constexpr const char* warningLedPath = + "/xyz/openbmc_project/led/groups/status_degraded"; + +constexpr const char* ledIface = "xyz.openbmc_project.Led.Group"; +constexpr const char* ledAssertProp = "Asserted"; +constexpr const char* ledManagerBusname = + "xyz.openbmc_project.LED.GroupManager"; + +std::shared_ptr<sdbusplus::asio::dbus_interface> assertedIface = nullptr; + +constexpr const bool debug = false; + +// final led state tracking +bool fatalState = false; +bool criticalState = false; +bool warnState = false; + +// maps of <object-path, <property, asserted>> +boost::container::flat_map<std::string, + boost::container::flat_map<std::string, bool>> + fatalAssertMap; +boost::container::flat_map<std::string, + boost::container::flat_map<std::string, bool>> + criticalAssertMap; +boost::container::flat_map<std::string, + boost::container::flat_map<std::string, bool>> + warningAssertMap; + +std::vector<std::string> assertedInMap( + const boost::container::flat_map< + std::string, boost::container::flat_map<std::string, bool>>& map) +{ + std::vector<std::string> ret; + // if any of the properties are true, return true + for (const auto& pair : map) + { + for (const auto& item : pair.second) + { + if (item.second) + { + ret.push_back(pair.first); + } + } + } + return ret; +} + +void updateLedStatus(std::shared_ptr<sdbusplus::asio::connection>& conn) +{ + std::vector<std::pair<std::string, std::variant<bool>>> ledsToSet; + + std::vector<std::string> assertedVector = assertedInMap(fatalAssertMap); + assertedIface->set_property("Fatal", assertedVector); + + bool fatal = assertedVector.size(); + if (fatal != fatalState) + { + fatalState = fatal; + ledsToSet.push_back(std::make_pair(fatalLedPath, fatalState)); + } + + assertedVector = assertedInMap(criticalAssertMap); + assertedIface->set_property("Critical", assertedVector); + + bool critical = assertedVector.size(); + if (critical != criticalState) + { + criticalState = critical; + ledsToSet.push_back(std::make_pair(criticalLedPath, criticalState)); + } + + assertedVector = assertedInMap(warningAssertMap); + assertedIface->set_property("Warning", assertedVector); + + bool warn = assertedVector.size(); + if (warn != warnState) + { + warnState = warn; + ledsToSet.push_back(std::make_pair(warningLedPath, warnState)); + } + + for (const auto& ledPair : ledsToSet) + { + conn->async_method_call( + [ledPair](const boost::system::error_code ec) { + if (ec) + { + std::cerr << "Cannot set " << ledPair.first << " to " + << std::boolalpha + << std::get<bool>(ledPair.second) << "\n"; + } + if constexpr (debug) + { + std::cerr << "Set " << ledPair.first << " to " + << std::boolalpha + << std::get<bool>(ledPair.second) << "\n"; + } + }, + ledManagerBusname, ledPair.first, "org.freedesktop.DBus.Properties", + "Set", ledIface, ledAssertProp, ledPair.second); + } +} + +void createThresholdMatch(std::shared_ptr<sdbusplus::asio::connection>& conn) +{ + static std::unique_ptr<sdbusplus::bus::match::match> match = nullptr; + + std::function<void(sdbusplus::message::message&)> thresholdCallback = + [&conn](sdbusplus::message::message& message) { + std::string objectName; + boost::container::flat_map<std::string, std::variant<bool>> values; + message.read(objectName, values); + + if constexpr (debug) + { + std::cerr << "Threshold callback " << message.get_path() + << "\n"; + } + + auto findCriticalLow = values.find("CriticalAlarmLow"); + auto findCriticalHigh = values.find("CriticalAlarmHigh"); + + auto findWarnLow = values.find("WarningAlarmLow"); + auto findWarnHigh = values.find("WarningAlarmHigh"); + + if (findCriticalLow != values.end()) + { + criticalAssertMap[message.get_path()]["Low"] = + std::get<bool>(findCriticalLow->second); + } + if (findCriticalHigh != values.end()) + { + criticalAssertMap[message.get_path()]["High"] = + std::get<bool>(findCriticalHigh->second); + } + if (findWarnLow != values.end()) + { + warningAssertMap[message.get_path()]["Low"] = + std::get<bool>(findWarnLow->second); + } + if (findWarnHigh != values.end()) + { + warningAssertMap[message.get_path()]["High"] = + std::get<bool>(findWarnHigh->second); + } + updateLedStatus(conn); + }; + + match = std::make_unique<sdbusplus::bus::match::match>( + static_cast<sdbusplus::bus::bus&>(*conn), + "type='signal',interface='org.freedesktop.DBus.Properties',path_" + "namespace='/xyz/openbmc_project/" + "sensors',arg0namespace='xyz.openbmc_project.Sensor.Threshold'", + thresholdCallback); +} + +int main(int argc, char** argv) +{ + boost::asio::io_service io; + auto conn = std::make_shared<sdbusplus::asio::connection>(io); + conn->request_name("xyz.openbmc_project.CallbackManager"); + sdbusplus::asio::object_server objServer(conn); + assertedIface = + objServer.add_interface("/xyz/openbmc_project/CallbackManager", + "xyz.openbmc_project.CallbackManager"); + assertedIface->register_property("Warning", std::vector<std::string>()); + assertedIface->register_property("Critical", std::vector<std::string>()); + assertedIface->register_property("Fatal", std::vector<std::string>()); + assertedIface->initialize(); + + createThresholdMatch(conn); + + io.run(); + + return 0; +} |