From 1b8666d1d9d85cea14c030ef964527d249dd6c3f Mon Sep 17 00:00:00 2001 From: queyanwen Date: Wed, 25 Oct 2023 14:36:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=93=A6=E7=89=B9=E8=B0=83=E5=BA=A6=E5=92=8Csmart=5Fg?= =?UTF-8?q?rid=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/inc/pwrdata.h | 11 +- common/inc/pwrerr.h | 5 +- pwrapic/src/powerapi.c | 4 +- pwrapic/test/CMakeLists.txt | 2 +- pwrapic/test/demo_main.c | 3 + pwrapic/test/procapitest.c | 123 +++++++++++ pwrapic/test/procapitest.h | 19 ++ pwrapis/inc/common.h | 3 + pwrapis/inc/procservice.h | 30 +++ pwrapis/inc/sysservice.h | 1 - pwrapis/inc/utils.h | 1 + pwrapis/src/cpuservice.c | 5 +- pwrapis/src/procservice.c | 405 ++++++++++++++++++++++++++++++++++++ pwrapis/src/server.c | 14 +- pwrapis/src/sysservice.c | 4 +- pwrapis/src/utils.c | 14 +- 16 files changed, 626 insertions(+), 18 deletions(-) create mode 100644 pwrapic/test/procapitest.c create mode 100644 pwrapic/test/procapitest.h create mode 100644 pwrapis/inc/procservice.h create mode 100644 pwrapis/src/procservice.c diff --git a/common/inc/pwrdata.h b/common/inc/pwrdata.h index 67b40f2..14f466c 100644 --- a/common/inc/pwrdata.h +++ b/common/inc/pwrdata.h @@ -36,7 +36,7 @@ #define PWR_CONVERSION 1000 #define PWR_MAX_CPU_ID_WIDTH 5 #define PWR_MAX_INPUT_NUM 512 -#define MAX_GOV_ATTR_NUM 20 +#define PWR_MAX_GOV_ATTR_NUM 20 #define PWR_MAX_CPU_DMA_LATENCY 2000000000 #define PWR_MAX_DISK_LIST_LEN 128 @@ -44,6 +44,13 @@ #define PWR_ONE_HUNDRED 100 #define PWR_ONE_THOUSAND 1000 #define PWR_MAX_WATT_SCALE_INTERVAL 3600000 +#define PWR_MAX_PROC_NUM 5000 + +#define PWR_TRUE 1 +#define PWR_FALSE 0 +#define PWR_ENABLE 1 +#define PWR_DISABLE 0 +#define PWR_STATE_LEN 4 enum PWR_Arch { PWR_AARCH_64 = 0, @@ -193,7 +200,7 @@ typedef struct PWR_CPU_FreqGovAttr { typedef struct PWR_CPU_FreqGovAttrs { char gov[PWR_MAX_ELEMENT_NAME_LEN]; - PWR_COM_Attr attrs[MAX_GOV_ATTR_NUM]; + PWR_COM_Attr attrs[PWR_MAX_GOV_ATTR_NUM]; uint32_t attrNum; } PWR_CPU_FreqGovAttrs; diff --git a/common/inc/pwrerr.h b/common/inc/pwrerr.h index 7a04724..12ba40d 100644 --- a/common/inc/pwrerr.h +++ b/common/inc/pwrerr.h @@ -15,9 +15,6 @@ #ifndef POWERAPI_ERR_H__ #define POWERAPI_ERR_H__ -#define PWR_TRUE 1 -#define PWR_FALSE 0 - enum PWR_RtnCode { PWR_SUCCESS = 0, PWR_ERR_COMMON = 1, @@ -36,6 +33,8 @@ enum PWR_RtnCode { PWR_ERR_PATH_VERIFY, PWR_ERR_NOT_REGISTED = 100, PWR_ERR_NOT_AUTHED, + PWR_ERR_WATT_SCHED_NOT_ENABLE, + PWR_ERR_SMART_GRID_NOT_SURPPORTED, PWR_ERR_OVER_MAX_CONNECTION, PWR_ERR_DISCONNECTED = 300, PWR_ERR_WRONG_RESPONSE_FROM_SERVER, diff --git a/pwrapic/src/powerapi.c b/pwrapic/src/powerapi.c index 434fb92..d08e1fe 100644 --- a/pwrapic/src/powerapi.c +++ b/pwrapic/src/powerapi.c @@ -495,7 +495,7 @@ int PWR_PROC_GetWattState(int *state) int PWR_PROC_SetWattState(int state) { CHECK_STATUS(STATUS_AUTHED); - if (state != PWR_TRUE || state != PWR_FALSE) { + if (state != PWR_ENABLE || state != PWR_DISABLE) { return PWR_ERR_INVALIDE_PARAM; } return SetProcWattState(state); @@ -561,7 +561,7 @@ int PWR_PROC_GetSmartGridState(int *state) int PWR_PROC_SetSmartGridState(int state) { CHECK_STATUS(STATUS_AUTHED); - if (state != PWR_TRUE || state != PWR_FALSE) { + if (state != PWR_ENABLE || state != PWR_DISABLE) { return PWR_ERR_INVALIDE_PARAM; } return SetSmartGridState(state); diff --git a/pwrapic/test/CMakeLists.txt b/pwrapic/test/CMakeLists.txt index 122508e..a91ff54 100644 --- a/pwrapic/test/CMakeLists.txt +++ b/pwrapic/test/CMakeLists.txt @@ -11,7 +11,7 @@ link_directories( ${PROJECT_SOURCE_DIR}/../../build/pwrapic/src ) # Set compile policy set (PG_NAME ${PROJECT_NAME}) -add_executable (${PG_NAME} demo_main.c) +add_executable (${PG_NAME} procapitest.c demo_main.c) target_link_libraries(${PG_NAME} -lpwrapi -lpthread) set (CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/pwrapic/test/demo_main.c b/pwrapic/test/demo_main.c index 5f5ad54..d7c52a3 100644 --- a/pwrapic/test/demo_main.c +++ b/pwrapic/test/demo_main.c @@ -18,6 +18,7 @@ #include #include #include "powerapi.h" +#include "procapitest.h" #define MAIN_LOOP_INTERVAL 5 #define TEST_FREQ 2400 @@ -562,6 +563,8 @@ int main(int argc, const char *args[]) // TEST_PWR_DISK_GetList(); // TEST_PWR_COM_DcTaskMgr(); + /************ PROC ***********/ + TEST_PROC_AllFunc(); // todo: 其他接口测试 while (g_run) { sleep(MAIN_LOOP_INTERVAL); diff --git a/pwrapic/test/procapitest.c b/pwrapic/test/procapitest.c new file mode 100644 index 0000000..9f91104 --- /dev/null +++ b/pwrapic/test/procapitest.c @@ -0,0 +1,123 @@ +/* ***************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023 All rights reserved. + * PowerAPI licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Author: queyanwen + * Create: 2023-10-25 + * Description: The testing of PowerAPI of PROC module. + * **************************************************************************** */ +#include +#include +#include +#include "powerapi.h" + +#define INVALIDE_STATE (-1) +static void TEST_PWR_PROC_SetAndGetWattState(void) +{ + int state = INVALIDE_STATE; + int ret = PWR_SUCCESS; + ret = PWR_PROC_GetWattState(&state); + printf("PWR_PROC_GetWattState. ret: %d state:%d\n", ret, state); + ret = PWR_PROC_SetWattState(PWR_ENABLE); + printf("PWR_PROC_SetWattState. ret: %d state:%d\n", ret, state); +} + +#define TEST_WATT_TH 60 +#define TEST_WATT_IT 3000 +#define TEST_WATT_DM 11 + +static void TEST_PWR_PROC_SetAndGetWattAttrs(void) +{ + int ret = PWR_SUCCESS; + PWR_PROC_WattAttrs was = {0}; + ret = PWR_PROC_GetWattAttrs(&was); + printf("PWR_PROC_GetWattAttrs: ret:%d th:%d, interval:%d dmask:%d\n", ret, + was.scaleThreshold, was.scaleInterval, was.domainMask); + was.scaleThreshold = TEST_WATT_TH; + was.scaleInterval = TEST_WATT_IT; + was.domainMask = TEST_WATT_DM; + ret = PWR_PROC_SetWattAttrs(&was); + if (ret != PWR_SUCCESS) { + printf("PWR_PROC_SetWattAttrs: failed, ret: %d\n", ret); + return; + } + bzero(&was, sizeof(was)); + (void)PWR_PROC_GetWattAttrs(&was); + printf("PWR_PROC_SetWattAttrs: SUCCESS\n"); +} + +#define TEST_PID_NUM 2 +#define TEST_PID_1 1 +#define TEST_PID_2 2 +static void TEST_PWR_PROC_AddAndDelWattProcs(void) +{ + // 1: pid 1 + // 2: pid 2 + pid_t procs[TEST_PID_NUM] = {TEST_PID_1, TEST_PID_2}; + int num = TEST_PID_NUM; + int ret = PWR_PROC_AddWattProcs(procs, num); + printf("PWR_PROC_AddWattProcs: ret:%d\n", ret); + + bzero(procs, sizeof(procs)); + ret = PWR_PROC_GetWattProcs(procs, &num); + printf("PWR_PROC_GetWattProcs: ret:%d num:%d\n", ret, num); + for (int i = 0; i < TEST_PID_NUM; i++) { + printf("\tPWR_PROC_GetWattProcs. procs%d: %d.\n", i, procs[i]); + } + + ret = PWR_PROC_DelWattProcs(procs, num - 1); + printf("PWR_PROC_DelWattProcs: ret:%d\n", ret); + bzero(procs, sizeof(procs)); + (void)PWR_PROC_GetWattProcs(procs, &num); + for (int i = 0; i < num; i++) { + printf("\tPWR_PROC_DelWattProcs. after del. procs%d: %d.\n", i, procs[i]); + } +} + +static void TEST_PWR_PROC_SetAndGetSmartGridState(void) +{ + int state = INVALIDE_STATE; + int ret = PWR_SUCCESS; + ret = PWR_PROC_GetSmartGridState(&state); + printf("PWR_PROC_GetSmartGridState. ret: %d state:%d\n", ret, state); + ret = PWR_PROC_SetSmartGridState(!state); + printf("PWR_PROC_SetSmartGridState. ret: %d state:%d\n", ret, state); +} + +static void TEST_PWR_PROC_SetAndGetSmartGridProcs(void) +{ + size_t size = sizeof(PWR_PROC_SmartGridProcs) + TEST_PID_NUM * sizeof(pid_t); + PWR_PROC_SmartGridProcs *sgp = (PWR_PROC_SmartGridProcs *)malloc(size); + if (!sgp) { + return; + } + sgp->level = PWR_PROC_SG_LEVEL_1; + sgp->procNum = TEST_PID_NUM; + sgp->procs[0] = TEST_PID_1; + sgp->procs[1] = TEST_PID_2; + int ret = PWR_PROC_SetSmartGridLevel(sgp); + printf("PWR_PROC_SetSmartGridLevel: ret:%d\n", ret); + bzero(sgp, size); + ret = PWR_PROC_GetSmartGridProcs(PWR_PROC_SG_LEVEL_1, sgp); + printf("PWR_PROC_GetSmartGridProcs: ret:%d num:%d\n", ret, sgp->procNum); + for (int i = 0; i < sgp->procNum; i++) { + printf("\tPWR_PROC_GetSmartGridProcs, procId%d:%d\n", i, sgp->procs[i]); + } + free(sgp); +} + +// public============================================================================== +void TEST_PROC_AllFunc(void) +{ + TEST_PWR_PROC_SetAndGetWattState(); + TEST_PWR_PROC_SetAndGetWattAttrs(); + TEST_PWR_PROC_AddAndDelWattProcs(); + TEST_PWR_PROC_SetAndGetSmartGridState(); + TEST_PWR_PROC_SetAndGetSmartGridProcs(); +} \ No newline at end of file diff --git a/pwrapic/test/procapitest.h b/pwrapic/test/procapitest.h new file mode 100644 index 0000000..150fda1 --- /dev/null +++ b/pwrapic/test/procapitest.h @@ -0,0 +1,19 @@ +/* ***************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023 All rights reserved. + * PowerAPI licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Author: queyanwen + * Create: 2023-10-25 + * Description: The testing of PowerAPI of PROC module. + * **************************************************************************** */ +#ifndef POWERAPI_TEST_PROC_H__ +#define POWERAPI_TEST_PROC_H__ + +void TEST_PROC_AllFunc(void); +#endif diff --git a/pwrapis/inc/common.h b/pwrapis/inc/common.h index 8115628..ff52f12 100644 --- a/pwrapis/inc/common.h +++ b/pwrapis/inc/common.h @@ -59,6 +59,7 @@ #define MD_NM_SVR_CPU "CPU_SERVICE" #define MD_NM_SVR_DISK "DISK_SERVICE" #define MD_NM_SVR_TASK "TASK_SERVICE" +#define MD_NM_SVR_PROC "PROC_SERVICE" #define MD_NM_CRED "CREDENTIALS" // Define configuration section name @@ -159,6 +160,7 @@ #define CURRENT_DIR "." #define PARENT_DIR ".." #define K_TO_M 1024 +#define LINE_SEP "\n" // Collected data name separator #define DATA_NM_SEP '.' #define DT_NM_SEP_STR "." @@ -250,6 +252,7 @@ enum STATUS { #define MAX_COLL_DURATION MAX_PERIOD #define STR_LEN_FOR_LONG 22 +#define STR_LEN_FOR_INT 12 #define WRONG_OBJ "coll_item_not_existed" enum ExistSt { diff --git a/pwrapis/inc/procservice.h b/pwrapis/inc/procservice.h new file mode 100644 index 0000000..d6fc181 --- /dev/null +++ b/pwrapis/inc/procservice.h @@ -0,0 +1,30 @@ +/* ***************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + * PowerAPI licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Author: queyanwen + * Create: 2023-10-19 + * Description: provide PROC service + * **************************************************************************** */ +#ifndef PAPIS_PROC_SERVICE_H__ +#define PAPIS_PROC_SERVICE_H__ +#include "pwrmsg.h" + +void ProcGetWattState(PwrMsg *req); +void ProcSetWattState(PwrMsg *req); +void procGetWattAttrs(PwrMsg *req); +void ProcSetWattAttrs(PwrMsg *req); +void ProcGetWattProcs(PwrMsg *req); +void ProcAddWattProcs(PwrMsg *req); +void ProcDelWattProcs(PwrMsg *req); +void ProcGetSmartGridState(PwrMsg *req); +void ProcSetSmartGridState(PwrMsg *req); +void ProcGetSmartGridProcs(PwrMsg *req); +void ProcSetSmartGridProcsLevel(PwrMsg *req); +#endif diff --git a/pwrapis/inc/sysservice.h b/pwrapis/inc/sysservice.h index aa88d8c..9ae8e4a 100644 --- a/pwrapis/inc/sysservice.h +++ b/pwrapis/inc/sysservice.h @@ -17,7 +17,6 @@ #include "pwrmsg.h" #include "pwrdata.h" -int PowerSet(char *state); void SetSysPowerState(PwrMsg *req); void GetSysRtPowerInfo(PwrMsg *req); #endif diff --git a/pwrapis/inc/utils.h b/pwrapis/inc/utils.h index b67714b..492c6c3 100644 --- a/pwrapis/inc/utils.h +++ b/pwrapis/inc/utils.h @@ -246,6 +246,7 @@ int InIntRange(int *range, int len, int a); int ReadFile(const char *strInfo, char *buf, int bufLen); int WriteFile(const char *strInfo, char *buf, int bufLen); int WriteFileAndCheck(const char *strInfo, char *buf, int bufLen); +int WriteIntToFile(const char *path, int content); int GetMd5(const char *filename, char *md5); int NormalizeAndVerifyFilepath(const char *filename, char *realpathRes); int GetSockoptFromOS(const pid_t pid, UnixCredOS *credOS); diff --git a/pwrapis/src/cpuservice.c b/pwrapis/src/cpuservice.c index b2ff411..f642fb5 100644 --- a/pwrapis/src/cpuservice.c +++ b/pwrapis/src/cpuservice.c @@ -715,9 +715,6 @@ static int GetGovAttrs(PWR_CPU_FreqGovAttrs *attrs) char attrPath[PWR_MAX_NAME_LEN] = {0}; StrCopy(attrPath, base, PWR_MAX_NAME_LEN - 1); strncat(attrPath, attrs->gov, strlen(attrs->gov)); - if (access(attrPath, F_OK) != 0) { - return PWR_ERR_FILE_ACCESS_FAILED; - } DIR *dir = opendir(attrPath); if (dir == NULL) { Logger(ERROR, MD_NM_SVR_CPU, "Unable to open direct: %s", attrPath); @@ -728,7 +725,7 @@ static int GetGovAttrs(PWR_CPU_FreqGovAttrs *attrs) pathEnd++; struct dirent *dt; int ret = PWR_SUCCESS; - while ((dt = readdir(dir)) != NULL && attrs->attrNum < MAX_GOV_ATTR_NUM) { + while ((dt = readdir(dir)) != NULL && attrs->attrNum < PWR_MAX_GOV_ATTR_NUM) { if (strcmp(dt->d_name, CURRENT_DIR) == 0 || strcmp(dt->d_name, PARENT_DIR) == 0) { continue; } diff --git a/pwrapis/src/procservice.c b/pwrapis/src/procservice.c new file mode 100644 index 0000000..d405c13 --- /dev/null +++ b/pwrapis/src/procservice.c @@ -0,0 +1,405 @@ +/* ***************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023 All rights reserved. + * PowerAPI licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Author: queyanwen + * Create: 2023-10-19 + * Description: provide cpu service + * **************************************************************************** */ + +#include "procservice.h" +#include +#include +#include "pwrerr.h" +#include "server.h" +#include "log.h" +#include "utils.h" + +#define WATT_CGROUP_PATH "/sys/fs/cgroup/cpu/watt_sched" +#define WATT_STATE_PATH "/sys/fs/cgroup/cpu/watt_sched/cpu.dynamic_affinity_mode" + +#define WATT_ATTR_SCALE_THRESHOLD_PATH "/proc/sys/kernel/sched_util_low_pct" +#define WATT_ATTR_DOMAIN_MASK_PATH "/sys/fs/cgroup/cpu/watt_sched/cpu.affinity_domain_mask" +#define WATT_ATTR_SCALE_INTERVAL_PATH "/sys/fs/cgroup/cpu/watt_sched/cpu.affinity_period_ms" +#define WATT_PROC_PATH "/sys/fs/cgroup/cpu/watt_sched/tasks" +#define ROOT_CGROUP_PROC_PATH "/sys/fs/cgroup/cpu/tasks" + +#define SMART_GRID_STATE_PATH "/proc/sys/kernel/smart_grid_strategy_ctl" +#define SMART_GRID_LEVEL_PATH_D "/proc/%d/smart_grid_level" +#define SMART_GRID_LEVEL_PATH_S "/proc/%s/smart_grid_level" +#define PROC_PATH "/proc" + +static int ReadWattAttrs(PWR_PROC_WattAttrs *wattAttrs) +{ + char buff[STR_LEN_FOR_INT] = {0}; + int ret = ReadFile(WATT_ATTR_SCALE_THRESHOLD_PATH, buff, STR_LEN_FOR_INT); + if (ret != PWR_SUCCESS) { + return ret; + } + wattAttrs->scaleThreshold = atoi(buff); + ret = ReadFile(WATT_ATTR_DOMAIN_MASK_PATH, buff, STR_LEN_FOR_INT); + if (ret != PWR_SUCCESS) { + return ret; + } + wattAttrs->domainMask = atoi(buff); + ret = ReadFile(WATT_ATTR_SCALE_INTERVAL_PATH, buff, STR_LEN_FOR_INT); + if (ret != PWR_SUCCESS) { + return ret; + } + wattAttrs->scaleInterval = atoi(buff); + return PWR_SUCCESS; +} + +static int WriteWattAttrs(const PWR_PROC_WattAttrs *wattAttrs) +{ + int ret = PWR_SUCCESS; + if (wattAttrs->scaleThreshold != 0) { + ret = WriteIntToFile(WATT_ATTR_SCALE_THRESHOLD_PATH, wattAttrs->scaleThreshold); + if (ret != PWR_SUCCESS) { + return ret; + } + } + if (wattAttrs->domainMask != 0) { + ret = WriteIntToFile(WATT_ATTR_DOMAIN_MASK_PATH, wattAttrs->domainMask); + if (ret != PWR_SUCCESS) { + return ret; + } + } + if (wattAttrs->scaleInterval != 0) { + ret = WriteIntToFile(WATT_ATTR_SCALE_INTERVAL_PATH, wattAttrs->scaleInterval); + if (ret != PWR_SUCCESS) { + return ret; + } + } + return PWR_SUCCESS; +} + +static int ReadWattProcs(pid_t *wattProcs, size_t size, int *procNum) +{ + char *content = (char *)malloc(size); + if (!content) { + return PWR_ERR_SYS_EXCEPTION; + } + + int ret = ReadFile(WATT_PROC_PATH, content, size); + if (ret != PWR_SUCCESS) { + free(content); + return ret; + } + + char **strProcs = calloc(PWR_MAX_PROC_NUM, sizeof(char *)); + if (!strProcs) { + free(content); + return PWR_ERR_SYS_EXCEPTION; + } + int num = PWR_MAX_PROC_NUM; + char *splitBuff = StrSplit(content, LINE_SEP, strProcs, &num); + if (!splitBuff) { + free(strProcs); + free(content); + return PWR_ERR_SYS_EXCEPTION; + } + + for (int i = 0; i < num; i++) { + wattProcs[i] = (pid_t)atoi(strProcs[i]); + } + *procNum = num; + free(splitBuff); + free(strProcs); + free(content); + return PWR_SUCCESS; +} + +static inline int SupportSmartGrid() +{ + if (access(SMART_GRID_STATE_PATH, F_OK) != 0) { + return PWR_FALSE; + } + return PWR_TRUE; +} + +static int ReadSmartGridProcsByLevel(PWR_PROC_SMART_GRID_LEVEL level, + PWR_PROC_SmartGridProcs *sgProcs, int maxNum) +{ + DIR *dir = opendir(PROC_PATH); + if (!dir) { + Logger(ERROR, MD_NM_SVR_PROC, "Unable to open direct: %s", PROC_PATH); + return PWR_ERR_FILE_OPEN_FAILED; + } + struct dirent *dt; + char procLevelPath[MAX_FULL_NAME] = {0}; + char strLevel[STR_LEN_FOR_INT] = {0}; + StrCopy(procLevelPath, PROC_PATH, MAX_FULL_NAME); + while ((dt = readdir(dir)) != NULL && sgProcs->procNum < maxNum) { + if (!IsNumStr(dt->d_name)) { + continue; + } + if (sprintf(procLevelPath, SMART_GRID_LEVEL_PATH_S, dt->d_name) < 0) { + return PWR_ERR_FILE_SPRINTF_FIILED; + } + if (ReadFile(procLevelPath, strLevel, STR_LEN_FOR_INT) != PWR_SUCCESS) { + continue; + } + if (atoi(strLevel) == level) { + sgProcs->procs[sgProcs->procNum] = (pid_t)atoi(dt->d_name); + sgProcs->procNum++; + } + } + return PWR_SUCCESS; +} + +static int WriteSmartGridProcsLevel(const PWR_PROC_SmartGridProcs *sgProcs) +{ + char strLevel[STR_LEN_FOR_INT] = {0}; + if (sprintf(strLevel, "%d", sgProcs->level) < 0) { + return PWR_ERR_FILE_SPRINTF_FIILED; + } + char procLevelPath[MAX_FULL_NAME] = {0}; + for (int i = 0; i < sgProcs->procNum; i++) { + if (sprintf(procLevelPath, SMART_GRID_LEVEL_PATH_D, sgProcs->procs[i]) < 0) { + return PWR_ERR_FILE_SPRINTF_FIILED; + } + (void)WriteFile(procLevelPath, strLevel, STR_LEN_FOR_INT); + } + return PWR_SUCCESS; +} + +// public=========================================================================================== +void ProcGetWattState(PwrMsg *req) +{ + int *state = (int *)malloc(sizeof(int)); + if (!state) { + return; + } + *state = PWR_DISABLE; + char buff[PWR_STATE_LEN] = {0}; + int ret = ReadFile(WATT_STATE_PATH, buff, PWR_STATE_LEN); + if (ret == PWR_SUCCESS) { + *state = atoi(buff); + } + SendRspToClient(req, 0, (char *)state, sizeof(int)); +} + +void ProcSetWattState(PwrMsg *req) +{ + if (req->head.dataLen != sizeof(int) || !req->data) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + int *state = (int *)req->data; + if (*state != PWR_ENABLE || *state != PWR_DISABLE) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + if (access(WATT_CGROUP_PATH, F_OK) != 0 && MkDirs(WATT_CGROUP_PATH) != PWR_SUCCESS) { + SendRspToClient(req, PWR_ERR_SYS_EXCEPTION, NULL, 0); + return; + } + int rspCode = WriteIntToFile(WATT_STATE_PATH, *state); + SendRspToClient(req, rspCode, NULL, 0); +} + +void procGetWattAttrs(PwrMsg *req) +{ + size_t size = sizeof(PWR_PROC_WattAttrs); + PWR_PROC_WattAttrs *wattAttrs = (PWR_PROC_WattAttrs *)malloc(size); + if (!wattAttrs) { + SendRspToClient(req, PWR_ERR_SYS_EXCEPTION, NULL, 0); + return; + } + bzero(wattAttrs, size); + int rspCode = ReadWattAttrs(wattAttrs); + if (rspCode != PWR_SUCCESS) { + free(wattAttrs); + SendRspToClient(req, rspCode, NULL, 0); + } else { + SendRspToClient(req, rspCode, (char *)wattAttrs, size); + } +} + +void ProcSetWattAttrs(PwrMsg *req) +{ + if (req->head.dataLen != sizeof(PWR_PROC_WattAttrs) || !req->data) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + PWR_PROC_WattAttrs *wattAttrs = (PWR_PROC_WattAttrs *)req->data; + if (wattAttrs->scaleThreshold < 0 || wattAttrs->scaleThreshold > PWR_ONE_HUNDRED + || wattAttrs->scaleInterval <0 || wattAttrs->scaleInterval > PWR_MAX_WATT_SCALE_INTERVAL + || wattAttrs->domainMask < 0) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + // Record the original data so that it can be restored to the + // previous value if some settings fails. + PWR_PROC_WattAttrs orgAttrs = {0}; + if (ReadWattAttrs(&orgAttrs) != PWR_SUCCESS) { + SendRspToClient(req, PWR_ERR_WATT_SCHED_NOT_ENABLE, NULL, 0); + return; + } + int rspCode = WriteWattAttrs(wattAttrs); + if (rspCode != PWR_SUCCESS) { + WriteWattAttrs(&orgAttrs); + } + SendRspToClient(req, rspCode, NULL, 0); +} + +void ProcGetWattProcs(PwrMsg *req) +{ + if (access(WATT_PROC_PATH, F_OK) != 0) { + SendRspToClient(req, PWR_ERR_WATT_SCHED_NOT_ENABLE, NULL, 0); + return; + } + size_t size = sizeof(pid_t) * PWR_MAX_PROC_NUM; + pid_t *wattProcs = (pid_t *)malloc(size); + if (!wattProcs) { + SendRspToClient(req, PWR_ERR_SYS_EXCEPTION, NULL, 0); + return; + } + bzero(wattProcs, size); + int procNum = 0; + int rspCode = ReadWattProcs(wattProcs, size, &procNum); + if (rspCode != PWR_SUCCESS) { + free(wattProcs); + SendRspToClient(req, rspCode, NULL, 0); + } else { + SendRspToClient(req, rspCode, (char *)wattProcs, procNum * sizeof(pid_t)); + } +} + +void ProcAddWattProcs(PwrMsg *req) +{ + if (access(WATT_PROC_PATH, F_OK) != 0) { + SendRspToClient(req, PWR_ERR_WATT_SCHED_NOT_ENABLE, NULL, 0); + return; + } + if (req->head.dataLen < sizeof(pid_t) || !req->data) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + int procNum = req->head.dataLen / sizeof(pid_t); + pid_t *procs = (pid_t *)req->data; + for (int i = 0; i < procNum; i++) { + (void)WriteIntToFile(WATT_PROC_PATH, *procs); + procs++; + } + SendRspToClient(req, PWR_SUCCESS, NULL, 0); +} + +void ProcDelWattProcs(PwrMsg *req) +{ + if (access(WATT_PROC_PATH, F_OK) != 0) { + SendRspToClient(req, PWR_ERR_WATT_SCHED_NOT_ENABLE, NULL, 0); + return; + } + if (req->head.dataLen < sizeof(pid_t) || !req->data) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + int procNum = req->head.dataLen / sizeof(pid_t); + pid_t *procs = (pid_t *)req->data; + for (int i = 0; i < procNum; i++) { + // Move the task back to the root cgroup to delete the task from the watt cgroup. + (void)WriteIntToFile(ROOT_CGROUP_PROC_PATH, *procs); + procs++; + } + SendRspToClient(req, PWR_SUCCESS, NULL, 0); +} + +void ProcGetSmartGridState(PwrMsg *req) +{ + if (!SupportSmartGrid()) { + SendRspToClient(req, PWR_ERR_SMART_GRID_NOT_SURPPORTED, NULL, 0); + return; + } + int *state = (int *)malloc(sizeof(int)); + if (!state) { + return; + } + *state = PWR_DISABLE; + char buff[PWR_STATE_LEN] = {0}; + int ret = ReadFile(SMART_GRID_STATE_PATH, buff, PWR_STATE_LEN); + if (ret != PWR_SUCCESS) { + free(state); + SendRspToClient(req, ret, NULL, 0); + } else { + *state = atoi(buff); + SendRspToClient(req, ret, (char *)state, sizeof(int)); + } +} + +void ProcSetSmartGridState(PwrMsg *req) +{ + if (!SupportSmartGrid()) { + SendRspToClient(req, PWR_ERR_SMART_GRID_NOT_SURPPORTED, NULL, 0); + return; + } + int ret = PWR_SUCCESS; + do { + if (req->head.dataLen != sizeof(int) || !req->data) { + ret = PWR_ERR_INVALIDE_PARAM; + break; + } + int *state = (int *)req->data; + if (*state != PWR_ENABLE || *state != PWR_DISABLE) { + ret = PWR_ERR_INVALIDE_PARAM; + break; + } + char buff[PWR_STATE_LEN] = {0}; + if (sprintf(buff, "%d", *state) < 0) { + ret = PWR_ERR_SYS_EXCEPTION; + break; + } + ret = WriteFile(SMART_GRID_STATE_PATH, buff, PWR_STATE_LEN); + } while (PWR_FALSE); + + SendRspToClient(req, ret, NULL, 0); +} + +void ProcGetSmartGridProcs(PwrMsg *req) +{ + if (!SupportSmartGrid()) { + SendRspToClient(req, PWR_ERR_SMART_GRID_NOT_SURPPORTED, NULL, 0); + return; + } + if (req->head.dataLen < sizeof(PWR_PROC_SMART_GRID_LEVEL) || !req->data) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + + PWR_PROC_SMART_GRID_LEVEL level = (PWR_PROC_SMART_GRID_LEVEL)req->data; + size_t size = sizeof(PWR_PROC_SmartGridProcs) + PWR_MAX_PROC_NUM * sizeof(pid_t); + PWR_PROC_SmartGridProcs *sgProcs = (PWR_PROC_SmartGridProcs *)malloc(size); + if (!sgProcs) { + SendRspToClient(req, PWR_ERR_SYS_EXCEPTION, NULL, 0); + return; + } + int ret = ReadSmartGridProcsByLevel(level, sgProcs, PWR_MAX_PROC_NUM); + if (ret != PWR_SUCCESS) { + free(sgProcs); + SendRspToClient(req, ret, NULL, 0); + } else { + SendRspToClient(req, ret, (char *)sgProcs, + sizeof(PWR_PROC_SmartGridProcs) + sgProcs->procNum * sizeof(pid_t)); + } +} + +void ProcSetSmartGridProcsLevel(PwrMsg *req) +{ + if (!SupportSmartGrid()) { + SendRspToClient(req, PWR_ERR_SMART_GRID_NOT_SURPPORTED, NULL, 0); + return; + } + if (req->head.dataLen < sizeof(PWR_PROC_SmartGridProcs) || !req->data) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + PWR_PROC_SmartGridProcs *sgProcs = (PWR_PROC_SmartGridProcs *)req->data; + SendRspToClient(req, WriteSmartGridProcsLevel(sgProcs), NULL, 0); +} diff --git a/pwrapis/src/server.c b/pwrapis/src/server.c index 9c2a6f3..7cbf4bd 100644 --- a/pwrapis/src/server.c +++ b/pwrapis/src/server.c @@ -33,6 +33,7 @@ #include "taskservice.h" #include "comservice.h" #include "diskservice.h" +#include "procservice.h" #include "pwrerr.h" #include "utils.h" #define COUNT_MAX 5 @@ -473,7 +474,18 @@ static OptToFunct g_optToFunct[] = { {CPU_SET_CUR_FREQ, SetCpuFreq}, {CPU_GET_FREQ_ABILITY, GetCpuFreqAbility}, {CPU_GET_FREQ_RANGE, GetCpuFreqRange}, - {CPU_SET_FREQ_RANGE, SetCpuFreqRange} + {CPU_SET_FREQ_RANGE, SetCpuFreqRange}, + {PROC_GET_WATT_STATE, ProcGetWattState}, + {PROC_SET_WATT_STATE, ProcSetWattState}, + {PROC_GET_WATT_ARRTS, procGetWattAttrs}, + {PROC_SET_WATT_ARRTS, ProcSetWattAttrs}, + {PROC_GET_WATT_PROCS, ProcGetWattProcs}, + {PROC_ADD_WATT_PROCS, ProcAddWattProcs}, + {PROC_DEL_WATT_PROCS, ProcDelWattProcs}, + {PROC_GET_SMART_GRID_STATE, ProcGetSmartGridState}, + {PROC_SET_SMART_GRID_STATE, ProcSetSmartGridState}, + {PROC_GET_SMART_GRID_PROCS, ProcGetSmartGridProcs}, + {PROC_SET_SMART_GRID_PROCS_LEVEL, ProcSetSmartGridProcsLevel} }; static void ProcessReqMsg(PwrMsg *req) diff --git a/pwrapis/src/sysservice.c b/pwrapis/src/sysservice.c index afb1755..6bb703a 100644 --- a/pwrapis/src/sysservice.c +++ b/pwrapis/src/sysservice.c @@ -10,10 +10,10 @@ * See the Mulan PSL v2 for more details. * Author: wuhaotian * Create: 2022-11-10 - * Description: provide cpu service + * Description: provide sys service * **************************************************************************** */ -#include "cpuservice.h" +#include "sysservice.h" #include "string.h" #include "pwrerr.h" #include "server.h" diff --git a/pwrapis/src/utils.c b/pwrapis/src/utils.c index 070101b..5e40a49 100644 --- a/pwrapis/src/utils.c +++ b/pwrapis/src/utils.c @@ -999,6 +999,15 @@ int WriteFileAndCheck(const char *strInfo, char *buf, int bufLen) return 0; } +int WriteIntToFile(const char *path, int content) +{ + char buff[STR_LEN_FOR_INT] = {0}; + if (sprintf(buff, "%d", content) < 0) { + return PWR_ERR_FILE_SPRINTF_FIILED; + } + return WriteFile(path, buff, strlen(buff)); +} + int GetMd5(const char *filename, char *md5) { char md5Cmd[PWR_MAX_NAME_LEN]; @@ -1064,8 +1073,8 @@ int GetSockoptFromOS(const pid_t pid, UnixCredOS *credOS) if (res == NULL) { return PWR_ERR_NULL_POINTER; } - - if (StrSplit(buf, " ", res, &maxNum) == NULL) { + char *p = StrSplit(buf, " ", res, &maxNum); + if (!p) { free(res); return PWR_ERR_COMMON; } @@ -1086,5 +1095,6 @@ int GetSockoptFromOS(const pid_t pid, UnixCredOS *credOS) credOS->gid = atoi(res[2]); free(res); + free(p); return PWR_SUCCESS; } \ No newline at end of file -- Gitee