diff --git a/TODO.txt b/TODO.txt index c15a21cf9..09fca5bbd 100644 --- a/TODO.txt +++ b/TODO.txt @@ -2,7 +2,6 @@ - SeLinux Rules enablement - Enable Classifier on meta-qcom builds - Analyze CodeQL reported issues - - Documentation Reordering 2. Process tasks (GitHub actions and repo workflow) - Enable Axiom CI tests @@ -11,9 +10,8 @@ - Integrate and Enable ARMOR 3. Implementation specific - - Adding irq resources - - Client API requests encoding / decoding support + - Client API requests encoding / decoding support (Making Buffers smaller for efficiency) - Client CLI improvements, to support all types of requests - Focused cgroup creation - Memory Leaks analysis and reduction. Major issues are resolved, still observing some lost blocks. - - Coordination Table changes (will add details here). + - Tests Cleanup diff --git a/configs/PropertiesConfig.yaml b/configs/PropertiesConfig.yaml index f35f24ce5..d1e446fb0 100644 --- a/configs/PropertiesConfig.yaml +++ b/configs/PropertiesConfig.yaml @@ -37,3 +37,6 @@ PropertyConfigs: - Name: urm.logging.redirect_to # Possible values: FILE, SYSLOG, FTRACE, LOGCAT. Value: "SYSLOG" + + - Name: urm.extensions_lib.count + Value: "3" diff --git a/modula/Common/Include/Utils.h b/modula/Common/Include/Utils.h index bc717b9b8..c61372d0f 100644 --- a/modula/Common/Include/Utils.h +++ b/modula/Common/Include/Utils.h @@ -133,6 +133,7 @@ typedef void (*MessageReceivedCallback)(int32_t, MsgForwardInfo*); #define LOGGER_LOGGING_LEVEL "urm.logging.level" #define LOGGER_LOGGING_LEVEL_TYPE "urm.logging.level.exact" #define LOGGER_LOGGING_OUTPUT_REDIRECT "urm.logging.redirect_to" +#define URM_MAX_PLUGIN_COUNT "urm.extensions_lib.count" #define COMM(pid) ("/proc/" + std::to_string(pid) + "/comm") #define COMM_S(pidstr) ("/proc/" + pidstr + "/comm") diff --git a/modula/Components/Logger.cpp b/modula/Components/Logger.cpp index 1010eb719..b91f79512 100644 --- a/modula/Components/Logger.cpp +++ b/modula/Components/Logger.cpp @@ -311,14 +311,14 @@ void Logger::typeLog(CommonMessageTypes type, const std::string& funcName, ...) case CommonMessageTypes::NOTIFY_EXTENSIONS_LOAD_FAILED: vsnprintf(buffer, sizeof(buffer), - "Error loading extension lib, Error: %s", args); + "Error loading extension lib: [%s], Error: [%s]", args); Logger::log(LOG_ERR, "RESTUNE_SERVER_INIT", funcName, buffer); break; case CommonMessageTypes::NOTIFY_EXTENSIONS_LIB_LOADED_SUCCESS: Logger::log(LOG_INFO, "RESTUNE_SERVER_INIT", funcName, - "Extension library present and successfully loaded"); + "Successfully Loaded: [%d] extension plugins"); break; case CommonMessageTypes::NOTIFY_COCO_TABLE_INSERT_START: diff --git a/modula/CoreModules/Include/UrmSettings.h b/modula/CoreModules/Include/UrmSettings.h index c0eef566b..fb0542ac9 100644 --- a/modula/CoreModules/Include/UrmSettings.h +++ b/modula/CoreModules/Include/UrmSettings.h @@ -25,6 +25,7 @@ typedef struct { uint32_t mCleanupBatchSize; double mPenaltyFactor; double mRewardFactor; + uint32_t mPluginCount; } MetaConfigs; typedef struct { @@ -42,8 +43,8 @@ class UrmSettings { static int32_t serverOnlineStatus; public: - static const int32_t desiredThreadCount = 15; - static const int32_t maxScalingCapacity = 30; + static const int32_t desiredThreadCount = 5; + static const int32_t maxScalingCapacity = 10; // Support both versions: Common and Custom static const std::string mCommonResourceFilePath; @@ -64,7 +65,7 @@ class UrmSettings { static const std::string mDeviceNamePath; static const std::string mBaseCGroupPath; static const std::string mPersistenceFile; - static const std::string mExtensionsPluginLibPath; + static const std::string mExtensionPluginsLibPath; // Target Information Stores static MetaConfigs metaConfigs; diff --git a/modula/CoreModules/UrmSettings.cpp b/modula/CoreModules/UrmSettings.cpp index 28e27924f..2c93e1cad 100644 --- a/modula/CoreModules/UrmSettings.cpp +++ b/modula/CoreModules/UrmSettings.cpp @@ -36,8 +36,8 @@ const std::string UrmSettings::mCustomExtFeaturesFilePath = const std::string UrmSettings::mCustomAppConfigFilePath = "/etc/urm/custom/PerApp.yaml"; -const std::string UrmSettings::mExtensionsPluginLibPath = - "libRestunePlugin.so"; +const std::string UrmSettings::mExtensionPluginsLibPath = + "/etc/urm/extensions"; const std::string UrmSettings::mDeviceNamePath = "/sys/devices/soc0/machine"; diff --git a/resource-tuner/init/RestuneInit.cpp b/resource-tuner/init/RestuneInit.cpp index 04a80ba3e..775103602 100644 --- a/resource-tuner/init/RestuneInit.cpp +++ b/resource-tuner/init/RestuneInit.cpp @@ -21,7 +21,10 @@ #include "SignalRegistry.h" #include "RestuneParser.h" -static void* extensionsLibHandle = nullptr; +#define MAX_EXTENSION_LIB_HANDLES 3 +static void** extensionLibHandles = nullptr; + +// Request Listener and Handler Threads static std::thread restuneHandlerThread; static std::thread resourceTunerListener; @@ -37,16 +40,40 @@ static void restoreToSafeState() { // Load the Extensions Plugin lib if it is available // If the lib is not present, we simply return Success. Since this lib is optional static ErrCode loadExtensionsLib() { - std::string libPath = UrmSettings::mExtensionsPluginLibPath; + if(extensionLibHandles == nullptr) { + extensionLibHandles = (void**) calloc(MAX_EXTENSION_LIB_HANDLES, sizeof(void*)); + if(extensionLibHandles == nullptr) { + return RC_MODULE_INIT_FAILURE; + } + } + std::string libDirPath = UrmSettings::mExtensionPluginsLibPath; + + DIR* dir = opendir(libDirPath.c_str()); + if(dir == nullptr) { + return RC_SUCCESS; // Return success regardless, since this is an extension. + } + + uint32_t extLibHandleIndex = 0; + int32_t libsLoaded = 0; + struct dirent* entry; + while(((entry = readdir(dir)) != nullptr) && + (extLibHandleIndex < UrmSettings::metaConfigs.mPluginCount)) { + std::string libPath = libDirPath + "/" + entry->d_name; - // Check if the library file exists - extensionsLibHandle = dlopen(libPath.c_str(), RTLD_NOW); - if(extensionsLibHandle == nullptr) { - TYPELOGV(NOTIFY_EXTENSIONS_LOAD_FAILED, dlerror()); - return RC_SUCCESS; // Return success regardless, since this is an extension. + // Check if the library file exists + extensionLibHandles[extLibHandleIndex] = dlopen(libPath.c_str(), RTLD_NOW); + if(extensionLibHandles[extLibHandleIndex] != nullptr) { + libsLoaded++; + } else { + TYPELOGV(NOTIFY_EXTENSIONS_LOAD_FAILED, libPath.c_str(), dlerror()); + } + extLibHandleIndex++; } + closedir(dir); - TYPELOGD(NOTIFY_EXTENSIONS_LIB_LOADED_SUCCESS); + if(libsLoaded > 0) { + TYPELOGV(NOTIFY_EXTENSIONS_LIB_LOADED_SUCCESS, libsLoaded); + } return RC_SUCCESS; } @@ -136,7 +163,8 @@ static ErrCode fetchMetaConfigs() { submitPropGetRequest(RATE_LIMITER_REWARD_FACTOR, resultBuffer, "0.4"); UrmSettings::metaConfigs.mRewardFactor = std::stod(resultBuffer); - initLogger(); + submitPropGetRequest(URM_MAX_PLUGIN_COUNT, resultBuffer, "3"); + UrmSettings::metaConfigs.mPluginCount = (uint32_t)std::stol(resultBuffer); } catch(const std::invalid_argument& e) { TYPELOGV(META_CONFIG_PARSE_FAILURE, e.what()); @@ -171,18 +199,22 @@ static ErrCode parseUtil(const std::string& filePath, return opStatus; } -static ErrCode fetchProperties() { +static ErrCode fetchCommonProperties() { ErrCode opStatus = RC_SUCCESS; // Parse Common Properties Configs std::string filePath = UrmSettings::mCommonPropertiesFilePath; opStatus = parseUtil(filePath, COMMON_PROPERTIES, ConfigType::PROPERTIES_CONFIG); - if(RC_IS_NOTOK(opStatus)) { - // Common Properties Parsing Failed - return opStatus; + if(RC_IS_OK(opStatus)) { + return fetchMetaConfigs(); } + return opStatus; +} - filePath = Extensions::getPropertiesConfigFilePath(); +static ErrCode fetchCustomProperties() { + ErrCode opStatus = RC_SUCCESS; + + std::string filePath = Extensions::getPropertiesConfigFilePath(); // Parse Custom Properties Configs provided via Extension Interface (if any) if(filePath.length() > 0) { TYPELOGV(NOTIFY_CUSTOM_CONFIG_FILE, "Property", filePath.c_str()); @@ -429,12 +461,27 @@ static ErrCode init(void* arg) { // Mandatory Configs include: Properties Configs, Resource Configs and Signal Configs (if Signal // module is plugged in) + // Fetch common properties + if(RC_IS_NOTOK(fetchCommonProperties())) { + TYPELOGD(PROPERTY_RETRIEVAL_FAILED); + return RC_MODULE_INIT_FAILURE; + } + + uint32_t pluginCount = UrmSettings::metaConfigs.mPluginCount; + if(pluginCount > MAX_EXTENSION_LIB_HANDLES) { + extensionLibHandles = (void**) realloc(extensionLibHandles, pluginCount * sizeof(void*)); + if(extensionLibHandles == nullptr) { + return RC_MODULE_INIT_FAILURE; + } + } + // Check if Extensions Plugin lib is available if(RC_IS_NOTOK(loadExtensionsLib())) { return RC_MODULE_INIT_FAILURE; } - if(RC_IS_NOTOK(fetchProperties())) { + // Fetch custom Properties + if(RC_IS_NOTOK(fetchCustomProperties())) { TYPELOGD(PROPERTY_RETRIEVAL_FAILED); return RC_MODULE_INIT_FAILURE; } @@ -442,24 +489,30 @@ static ErrCode init(void* arg) { // Pre-Allocate Memory for Commonly used Types via Memory Pool preAllocateMemory(); + // Setup the logger, according to configuration urm can log to either: + // syslog, ftrace or regular text file. + initLogger(); + + // Pre Allocate some Worker Threads in the Thread Pool for handling requests if(RC_IS_NOTOK(preAllocateWorkers())) { return RC_MODULE_INIT_FAILURE; } - // Target Configs + // Fetch and Parse: Custom Target Configs if(RC_IS_NOTOK(fetchTargetInfo())) { return RC_MODULE_INIT_FAILURE; } - TargetRegistry::getInstance()->displayTargetInfo(); - // Fetch and Parse: - // - Init Configs + // Fetch and Parse: Init Configs + // Init Configs which will be considered: + // - Common Init Configs + // - Custom Init Configs (if present) if(RC_IS_NOTOK(fetchInitInfo())) { return RC_MODULE_INIT_FAILURE; } // Fetch and Parse Resource Configs - // Resource Parsing which will be considered: + // Resource Configs which will be considered: // - Common Resource Configs // - Custom Resource Configs (if present) // Note by this point, we will know the Target Info, i.e. number of Core, Clusters etc. @@ -475,10 +528,12 @@ static ErrCode init(void* arg) { return RC_MODULE_INIT_FAILURE; } + // Fetch and Parse: Custom Per-App Configs if(RC_IS_NOTOK(fetchPerAppConfigs())) { return RC_MODULE_INIT_FAILURE; } + // Fetch and Parse: Custom ExtFeature Configs if(RC_IS_NOTOK(fetchExtFeatureConfigs())) { return RC_MODULE_INIT_FAILURE; } @@ -564,8 +619,15 @@ static ErrCode tear(void* arg) { // Delete the Sysfs Persistent File AuxRoutines::deleteFile(UrmSettings::mPersistenceFile); - if(extensionsLibHandle != nullptr) { - dlclose(extensionsLibHandle); + if(extensionLibHandles != nullptr) { + for(uint32_t i = 0; i < UrmSettings::metaConfigs.mPluginCount; i++) { + if(extensionLibHandles[i] != nullptr) { + dlclose(extensionLibHandles[i]); + extensionLibHandles[i] = nullptr; + } + } + + free(extensionLibHandles); } return RC_SUCCESS;