diff --git a/contextual-classifier/CMakeLists.txt b/contextual-classifier/CMakeLists.txt index 3b2ff9364..ed806c464 100644 --- a/contextual-classifier/CMakeLists.txt +++ b/contextual-classifier/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories(${CMAKE_SOURCE_DIR}/modula/CoreModules/Include) include_directories(${CMAKE_SOURCE_DIR}/extensions/Include) include_directories(${CMAKE_SOURCE_DIR}/resource-tuner/core/Include) include_directories(${CMAKE_SOURCE_DIR}/resource-tuner/signals/Include/) +include_directories(${CMAKE_SOURCE_DIR}/resource-tuner/dbus-modules/Include/) # Single shared library that contains parser + classifier + netlink glue add_library(ContextualClassifier SHARED diff --git a/modula/Common/Include/ErrCodes.h b/modula/Common/Include/ErrCodes.h index c90d54611..ad16bce67 100644 --- a/modula/Common/Include/ErrCodes.h +++ b/modula/Common/Include/ErrCodes.h @@ -45,6 +45,7 @@ enum ErrCode { RC_WORKER_THREAD_ASSIGNMENT_FAILURE, RC_LOGICAL_TO_PHYSICAL_GEN_FAILED, RC_CGROUP_CREATION_FAILURE, + RC_DBUS_COMM_FAIL, }; #define RC_IS_OK(rc) ({ \ diff --git a/modula/Components/Include/Logger.h b/modula/Components/Include/Logger.h index ab656633c..40624d004 100644 --- a/modula/Components/Include/Logger.h +++ b/modula/Components/Include/Logger.h @@ -113,6 +113,7 @@ enum CommonMessageTypes { NOTIFY_CLASSIFIER_PROC_EVENT, NOTIFY_CLASSIFIER_PROC_IGNORE, NOTIFY_MODEL_PREDICTION, + SYSTEM_BUS_CONN_FAILED, }; /** diff --git a/modula/Components/Logger.cpp b/modula/Components/Logger.cpp index 53c3e6509..6f56b412f 100644 --- a/modula/Components/Logger.cpp +++ b/modula/Components/Logger.cpp @@ -746,6 +746,13 @@ void Logger::typeLog(CommonMessageTypes type, const std::string& funcName, ...) Logger::log(LOG_INFO, "CONTEXTUAL_CLASSIFIER", funcName, buffer); break; + case CommonMessageTypes::SYSTEM_BUS_CONN_FAILED: + vsnprintf(buffer, sizeof(buffer), + "Failed to establish connection with system bus, Error: %s", args); + + Logger::log(LOG_ERR, "RESTUNE_COCO_TABLE", funcName, std::string(buffer)); + break; + default: break; } diff --git a/resource-tuner/CMakeLists.txt b/resource-tuner/CMakeLists.txt index 45a419c09..35b573175 100644 --- a/resource-tuner/CMakeLists.txt +++ b/resource-tuner/CMakeLists.txt @@ -1,6 +1,16 @@ # Mandatory Dependencies pkg_check_modules(LIBYAML REQUIRED yaml-0.1) +# Optional Dependency: libsystemd +set(LIB_SYSTEMD_DEP_FOUND FALSE) +pkg_check_modules(PC_SYSTEMD QUIET systemd) +if(PC_SYSTEMD_FOUND) + pkg_check_modules(SYSTEMD QUIET libsystemd) + if(SYSTEMD_FOUND) + set(LIB_SYSTEMD_DEP_FOUND TRUE) + endif() +endif() + # Optional Modules option(BUILD_TESTS "Testing" OFF) option(BUILD_STATE_DETECTOR "Display Detector" OFF) @@ -18,19 +28,33 @@ list(APPEND LINK_LIBS ${LIBYAML_LIBRARIES} ) -if(BUILD_STATE_DETECTOR) - pkg_check_modules(SYSTEMD REQUIRED libsystemd) - list(APPEND SOURCES extensions/StateDetector.cpp) +if(LIB_SYSTEMD_DEP_FOUND) list(APPEND LINK_LIBS ${SYSTEMD_LIBRARIES}) + list(APPEND SOURCES dbus-modules/RestuneDBusInternal.cpp) + if(BUILD_STATE_DETECTOR) + list(APPEND SOURCES dbus-modules/StateDetector.cpp) + endif() +else() + list(APPEND SOURCES dbus-modules/RestuneDBusStubs.cpp) endif() add_library(RestuneCore ${SOURCES}) set_target_properties(RestuneCore PROPERTIES VERSION 1.0.0 SOVERSION 1) -target_include_directories(RestuneCore PRIVATE ${LIBYAML_INCLUDE_DIRS}) target_link_libraries(RestuneCore PUBLIC ${LINK_LIBS}) target_include_directories(RestuneCore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/core/Include) target_include_directories(RestuneCore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/core/Server/Include) target_include_directories(RestuneCore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/signals/Include) target_include_directories(RestuneCore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/init/Include) +target_include_directories(RestuneCore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/dbus-modules/Include) + +# libyaml headers +target_include_directories(RestuneCore PRIVATE ${LIBYAML_INCLUDE_DIRS}) + +# libsystemd headers +if(LIB_SYSTEMD_DEP_FOUND) + target_include_directories(RestuneCore PRIVATE ${SYSTEMD_INCLUDE_DIRS}) +endif() + +# Install RestuneCore install(TARGETS RestuneCore LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/resource-tuner/core/CocoTable.cpp b/resource-tuner/core/CocoTable.cpp index 5f5b1547e..5dddcebc6 100644 --- a/resource-tuner/core/CocoTable.cpp +++ b/resource-tuner/core/CocoTable.cpp @@ -47,7 +47,7 @@ static int8_t comparLBetter(DLRootNode* newNode, DLRootNode* targetNode) { return newValue < targetValue; } -int8_t CocoTable::needAllocation(Resource* res) { +int8_t CocoTable::needsAllocation(Resource* res) { ResConfInfo* rConf = this->mResourceRegistry->getResConf(res->getResCode()); return (rConf->mPolicy != Policy::PASS_THROUGH); } diff --git a/resource-tuner/core/Include/CocoTable.h b/resource-tuner/core/Include/CocoTable.h index 13eb6a64b..b9a01f86d 100644 --- a/resource-tuner/core/Include/CocoTable.h +++ b/resource-tuner/core/Include/CocoTable.h @@ -126,7 +126,7 @@ class CocoTable { void fastPathApply(Resource* resource); void fastPathReset(Resource* resource); - int8_t needAllocation(Resource* res); + int8_t needsAllocation(Resource* res); public: ~CocoTable(); diff --git a/resource-tuner/core/Include/TargetRegistry.h b/resource-tuner/core/Include/TargetRegistry.h index cea5ff02a..3cac58a7a 100644 --- a/resource-tuner/core/Include/TargetRegistry.h +++ b/resource-tuner/core/Include/TargetRegistry.h @@ -21,10 +21,11 @@ #include #include +#include "Logger.h" +#include "ErrCodes.h" #include "UrmSettings.h" #include "AuxRoutines.h" -#include "ErrCodes.h" -#include "Logger.h" +#include "RestuneDBus.h" #define POLICY_DIR_PATH "/sys/devices/system/cpu/cpufreq/" #define ONLINE_CPU_FILE_PATH "/sys/devices/system/cpu/online" @@ -166,6 +167,7 @@ class TargetRegistry { ErrCode addIrqAffine(std::vector& values, int8_t areClusterValues = false); + ErrCode addLogLimit(std::vector& values); static std::shared_ptr getInstance() { if(targetRegistryInstance == nullptr) { diff --git a/resource-tuner/core/TargetRegistry.cpp b/resource-tuner/core/TargetRegistry.cpp index 2fb299c4c..67d9f6fb8 100644 --- a/resource-tuner/core/TargetRegistry.cpp +++ b/resource-tuner/core/TargetRegistry.cpp @@ -162,6 +162,12 @@ void TargetRegistry::generatePolicyBasedMapping(std::vector& policy } } +static std::string trimStr(const std::string &s) { + size_t start = s.find_first_not_of(" \t"); + size_t end = s.find_last_not_of(" \t\r"); + return (start == std::string::npos) ? "" : s.substr(start, end - start + 1); +} + void TargetRegistry::getClusterIdBasedMapping() { const std::string cpuDir = "/sys/devices/system/cpu"; const std::regex cpuRegex("^cpu([0-9]+)$"); @@ -551,6 +557,95 @@ ErrCode TargetRegistry::addIrqAffine(std::vector& values, return RC_SUCCESS; } +ErrCode TargetRegistry::addLogLimit(std::vector& values) { + if(values.size() < 1) { + return RC_INVALID_VALUE; + } + + std::string logLevel = values[0]; + if(logLevel != "minimal") { + return RC_SUCCESS; + } + + const std::string journaldConfFile = "/etc/systemd/journald.conf"; + const std::unordered_map configOptions = { + {"RuntimeMaxUse", "20M"}, + {"RuntimeMaxFileSize", "128K"}, + {"MaxLevelStore", "notice"}, + {"MaxLevelSyslog", "notice"}, + {"MaxLevelKMsg", "notice"}, + {"MaxLevelConsole", "notice"}, + {"ForwardToSyslog", "no"} + }; + + std::ifstream confInStream(journaldConfFile); + if(!confInStream) { + return RC_SUCCESS; + } + + std::ostringstream oldContent; + std::ostringstream newContent; + std::string line; + int8_t journalSectionFound = false; + + std::unordered_map keyUpdated; + for(auto &entry : configOptions) { + keyUpdated[entry.first] = false; + } + + while(std::getline(confInStream, line)) { + std::string trimmedLine = trimStr(line); + int8_t replaced = false; + + if(trimmedLine == "[Journal]") { + journalSectionFound = true; + } + + for(auto &entry : configOptions) { + if(trimmedLine.find(entry.first + "=") == 0 || + trimmedLine.find("#" + entry.first + "=") == 0) { + newContent << entry.first << "=" << entry.second << "\n"; + keyUpdated[entry.first] = true; + replaced = true; + break; + } + } + if(!replaced) { + newContent << line << "\n"; + } + oldContent << line << "\n"; + } + confInStream.close(); + + if(!journalSectionFound) { + newContent << "\n[Journal]\n"; + } + + for(auto &entry : configOptions) { + if(!keyUpdated[entry.first]) { + newContent << entry.first << "=" << entry.second << "\n"; + } + } + + std::ofstream confOutStream(journaldConfFile); + confOutStream << newContent.str(); + confOutStream.close(); + + // Set printk kernel logging to minimal + const std::string printkPath = "/proc/sys/kernel/printk"; + const std::string newLevels = "3 4 1 3"; + + std::ofstream printkFile(printkPath); + if(printkFile.is_open()) { + printkFile << newLevels; + printkFile.close(); + } + + // Restart journald + RestuneSDBus::getInstance()->restartService("systemd-journald.service"); + return RC_SUCCESS; +} + // Methods for Building CGroup Config from InitConfigs.yaml CGroupConfigInfoBuilder::CGroupConfigInfoBuilder() { this->mCGroupConfigInfo = new(std::nothrow) CGroupConfigInfo; diff --git a/resource-tuner/dbus-modules/Include/RestuneDBus.h b/resource-tuner/dbus-modules/Include/RestuneDBus.h new file mode 100644 index 000000000..115d9b0d5 --- /dev/null +++ b/resource-tuner/dbus-modules/Include/RestuneDBus.h @@ -0,0 +1,38 @@ +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// SPDX-License-Identifier: BSD-3-Clause-Clear + +#ifndef RESTUNE_DBUS_INTERNAL_H +#define RESTUNE_DBUS_INTERNAL_H + +#include + +#include "Logger.h" +#include "ErrCodes.h" + +class RestuneSDBus { +private: + static std::shared_ptr restuneSDBusInstance; + void* mBus; + + RestuneSDBus(); + +public: + ~RestuneSDBus(); + + ErrCode stopService(const std::string& unitName); + ErrCode startService(const std::string& unitName); + ErrCode restartService(const std::string& unitName); + + // For custom use-cases, like StateDetector while still keeping + // a single open connection to system-bus. + void* getBus(); + + static std::shared_ptr getInstance() { + if(restuneSDBusInstance == nullptr) { + restuneSDBusInstance = std::shared_ptr(new RestuneSDBus()); + } + return restuneSDBusInstance; + } +}; + +#endif diff --git a/resource-tuner/dbus-modules/RestuneDBusInternal.cpp b/resource-tuner/dbus-modules/RestuneDBusInternal.cpp new file mode 100644 index 000000000..4aba868ef --- /dev/null +++ b/resource-tuner/dbus-modules/RestuneDBusInternal.cpp @@ -0,0 +1,123 @@ +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// SPDX-License-Identifier: BSD-3-Clause-Clear + +#include +#include + +#include "RestuneDBus.h" + +#define SYSTEMD_DBUS_NAME "org.freedesktop.systemd1" +#define SYSTEMD_DBUS_PATH "/org/freedesktop/systemd1" +#define SYSTEMD_DBUS_IF "org.freedesktop.systemd1.Manager" + +std::shared_ptr RestuneSDBus::restuneSDBusInstance = nullptr; + +RestuneSDBus::RestuneSDBus() { + this->mBus = nullptr; + + // Connect to the system bus + int32_t rc; + if((rc = sd_bus_default_system((sd_bus**)&this->mBus)) < 0) { + TYPELOGV(SYSTEM_BUS_CONN_FAILED, strerror(-rc)); + } +} + +ErrCode RestuneSDBus::startService(const std::string& unitName) { + if(this->mBus == nullptr) return RC_MODULE_INIT_FAILURE; + + sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus_message *reply = NULL; + + int32_t rc = sd_bus_call_method( + static_cast(this->mBus), + SYSTEMD_DBUS_NAME, + SYSTEMD_DBUS_PATH, + SYSTEMD_DBUS_IF, + "StartUnit", + &error, + &reply, + "ss", + unitName.c_str(), + "replace" + ); + + if(rc < 0) { + LOGE("RESTUNE_COCO_TABLE", "Failed to start irqbalanced: " + std::string(error.message)); + return RC_DBUS_COMM_FAIL; + } + + sd_bus_message_unref(reply); + sd_bus_error_free(&error); + + return RC_SUCCESS; +} + +ErrCode RestuneSDBus::stopService(const std::string& unitName) { + if(this->mBus == nullptr) return RC_DBUS_COMM_FAIL; + + sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus_message *reply = NULL; + + int32_t rc = sd_bus_call_method( + static_cast(this->mBus), + SYSTEMD_DBUS_NAME, + SYSTEMD_DBUS_PATH, + SYSTEMD_DBUS_IF, + "StopUnit", + &error, + &reply, + "ss", + unitName.c_str(), + "replace" + ); + + if(rc < 0) { + LOGE("RESTUNE_COCO_TABLE", "Failed to stop irqbalanced: " + std::string(error.message)); + return RC_DBUS_COMM_FAIL; + } + + sd_bus_message_unref(reply); + sd_bus_error_free(&error); + + return RC_SUCCESS; +} + +ErrCode RestuneSDBus::restartService(const std::string& unitName) { + if(this->mBus == nullptr) return RC_DBUS_COMM_FAIL; + + sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus_message *reply = NULL; + + int32_t rc = sd_bus_call_method( + static_cast(this->mBus), + SYSTEMD_DBUS_NAME, + SYSTEMD_DBUS_PATH, + SYSTEMD_DBUS_IF, + "RestartUnit", + &error, + &reply, + "ss", + unitName.c_str(), + "replace" + ); + + if(rc < 0) { + LOGE("RESTUNE_COCO_TABLE", "Failed to start irqbalanced: " + std::string(error.message)); + } + + sd_bus_message_unref(reply); + sd_bus_error_free(&error); + + return RC_SUCCESS; +} + +void* RestuneSDBus::getBus() { + return this->mBus; +} + +RestuneSDBus::~RestuneSDBus() { + if(this->mBus != nullptr) { + sd_bus_unref((sd_bus*)this->mBus); + this->mBus = nullptr; + } +} diff --git a/resource-tuner/dbus-modules/RestuneDBusStubs.cpp b/resource-tuner/dbus-modules/RestuneDBusStubs.cpp new file mode 100644 index 000000000..6446c123e --- /dev/null +++ b/resource-tuner/dbus-modules/RestuneDBusStubs.cpp @@ -0,0 +1,32 @@ +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// SPDX-License-Identifier: BSD-3-Clause-Clear + +#include "RestuneDBus.h" + +std::shared_ptr RestuneSDBus::restuneSDBusInstance = nullptr; + +RestuneSDBus::RestuneSDBus() {} + +ErrCode RestuneSDBus::startService(const std::string& unitName) { + (void)unitName; + LOGE("URM_DBUS_DEP_MODULES", "dBus support not found, skipping."); + return RC_SUCCESS; +} + +ErrCode RestuneSDBus::stopService(const std::string& unitName) { + (void)unitName; + LOGE("URM_DBUS_DEP_MODULES", "dBus support not found, skipping."); + return RC_SUCCESS; +} + +ErrCode RestuneSDBus::restartService(const std::string& unitName) { + (void)unitName; + LOGE("URM_DBUS_DEP_MODULES", "dBus support not found, skipping."); + return RC_SUCCESS; +} + +void* RestuneSDBus::getBus() { + return nullptr; +} + +RestuneSDBus::~RestuneSDBus() {} diff --git a/resource-tuner/extensions/StateDetector.cpp b/resource-tuner/dbus-modules/StateDetector.cpp similarity index 99% rename from resource-tuner/extensions/StateDetector.cpp rename to resource-tuner/dbus-modules/StateDetector.cpp index e1da3da20..f5a2ebf4d 100644 --- a/resource-tuner/extensions/StateDetector.cpp +++ b/resource-tuner/dbus-modules/StateDetector.cpp @@ -89,8 +89,8 @@ static int32_t onSdBusMessageReceived(sd_bus_message* message, static int32_t eventLoopTerminator(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { - (void)s;; - (void)si;; + (void)s; + (void)si; (void)userdata; sd_event_exit(event, 0); return 0; diff --git a/resource-tuner/init/Include/RestuneParser.h b/resource-tuner/init/Include/RestuneParser.h index 68e461ed9..41a90b268 100644 --- a/resource-tuner/init/Include/RestuneParser.h +++ b/resource-tuner/init/Include/RestuneParser.h @@ -80,6 +80,9 @@ #define INIT_CONFIG_IRQ_AFFINE_ONE "AffineIRQ" #define INIT_CONFIG_IRQ_AFFINE_TO_CLUSTER "AffineIRQToCluster" +// Journal Configs +#define INIT_CONFIG_LOGGING_CONF "LogLevel" + // Properties #define PROPERTY_CONFIGS_ROOT "PropertyConfigs" #define PROPERTY_CONFIGS_ELEM_NAME "Name" diff --git a/resource-tuner/init/RestuneParser.cpp b/resource-tuner/init/RestuneParser.cpp index 80bfc54d7..631762e12 100644 --- a/resource-tuner/init/RestuneParser.cpp +++ b/resource-tuner/init/RestuneParser.cpp @@ -107,6 +107,7 @@ static int8_t isKey(const std::string& keyName) { INIT_CONFIGS_IRQ_CONFIGS_LIST, INIT_CONFIG_IRQ_AFFINE_TO_CLUSTER, INIT_CONFIG_IRQ_AFFINE_ONE, + INIT_CONFIG_LOGGING_CONF, SIGNAL_CONFIGS_ROOT, SIGNAL_CONFIGS_ELEM_SIGID, SIGNAL_CONFIGS_ELEM_CATEGORY, @@ -154,6 +155,8 @@ static int8_t isKeyTypeList(const std::string& keyName) { if(keyName == INIT_CONFIG_IRQ_AFFINE_TO_CLUSTER) return true; if(keyName == INIT_CONFIG_IRQ_AFFINE_ONE) return true; + if(keyName == INIT_CONFIG_LOGGING_CONF) return true; + if(keyName == RESOURCE_CONFIGS_ELEM_MODES) return true; if(keyName == RESOURCE_CONFIGS_ELEM_TARGETS_ENABLED) return true; if(keyName == RESOURCE_CONFIGS_ELEM_TARGETS_DISABLED) return true; @@ -465,6 +468,7 @@ ErrCode RestuneParser::parseInitConfigYamlNode(const std::string& filePath) { int8_t docMarker = false; int8_t inAffineClusterList = false; int8_t inAffineOneList = false; + int8_t inLoggingConfList = false; std::string value; std::string topKey; @@ -496,6 +500,8 @@ ErrCode RestuneParser::parseInitConfigYamlNode(const std::string& filePath) { inAffineClusterList = true; } else if(topKey == INIT_CONFIG_IRQ_AFFINE_ONE) { inAffineOneList = true; + } else if(topKey == INIT_CONFIG_LOGGING_CONF) { + inLoggingConfList = true; } break; @@ -524,6 +530,15 @@ ErrCode RestuneParser::parseInitConfigYamlNode(const std::string& filePath) { } itemArray.clear(); inAffineOneList = !inAffineOneList; + + } else if(inLoggingConfList) { + if(RC_IS_OK(rc)) { + rc = TargetRegistry::getInstance()->addLogLimit(itemArray); + if(RC_IS_NOTOK(rc)) { + return RC_YAML_INVALID_SYNTAX; + } + } + inLoggingConfList = !inLoggingConfList; } keyTracker.pop(); @@ -635,7 +650,9 @@ ErrCode RestuneParser::parseInitConfigYamlNode(const std::string& filePath) { ADD_TO_CACHE_INFO_BUILDER(INIT_CONFIGS_ELEM_CACHE_INFO_BLK_CNT, setNumBlocks); ADD_TO_CACHE_INFO_BUILDER(INIT_CONFIGS_ELEM_CACHE_INFO_PRIO_AWARE, setPriorityAware); - if(topKey == INIT_CONFIG_IRQ_AFFINE_TO_CLUSTER || topKey == INIT_CONFIG_IRQ_AFFINE_ONE) { + if(topKey == INIT_CONFIG_IRQ_AFFINE_TO_CLUSTER || + topKey == INIT_CONFIG_IRQ_AFFINE_ONE || + topKey == INIT_CONFIG_LOGGING_CONF) { itemArray.push_back(value); }