From c0f042800dd622a3dbc3ab11683cc960471dd89f Mon Sep 17 00:00:00 2001 From: wuhaotian315 <694496640@qq.com> Date: Wed, 15 May 2024 23:13:50 +0800 Subject: [PATCH] add get service state and set service state interfaces --- common/inc/pwrdata.h | 28 ++++++++ common/inc/pwrerr.h | 2 + common/inc/pwrmsg.h | 2 + pwrapic/inc/powerapi.h | 2 + pwrapic/inc/pwrproc.h | 2 + pwrapic/src/powerapi.c | 17 +++++ pwrapic/src/pwrproc.c | 42 +++++++++++ pwrapic/test/procapitest.c | 35 ++++++++- pwrapis/inc/procservice.h | 8 +++ pwrapis/src/procservice.c | 141 +++++++++++++++++++++++++++++++++++++ pwrapis/src/server.c | 2 + 11 files changed, 280 insertions(+), 1 deletion(-) diff --git a/common/inc/pwrdata.h b/common/inc/pwrdata.h index 9f95c30..68b1a37 100644 --- a/common/inc/pwrdata.h +++ b/common/inc/pwrdata.h @@ -54,6 +54,8 @@ #define PWR_ENABLE 1 #define PWR_DISABLE 0 #define PWR_STATE_LEN 4 +#define PWR_SERVICE_START 1 +#define PWR_SERVICE_STOP 0 enum PWR_Arch { PWR_AARCH_64 = 0, @@ -83,6 +85,22 @@ typedef enum PWR_PROC_SMART_GRID_LEVEL { PWR_PROC_SG_LEVEL_1 = 1, } PWR_PROC_SMART_GRID_LEVEL; +typedef enum PWR_PROC_SERVICE_NAME { + PWR_PROC_SERVICE_INVALIDE = 0, + PWR_PROC_SERVICE_MPCTOOL, + PWR_PROC_SERVICE_EAGLE, +} PWR_PROC_SERVICE_NAME; + +typedef enum PWR_PROC_SERVICE_STATUS { + PWR_PROC_SRV_ST_INACTIVE = 0, + PWR_PROC_SRV_ST_ACTIVATING, + PWR_PROC_SRV_ST_RUNNING, + PWR_PROC_SRV_ST_EXITED, + PWR_PROC_SRV_ST_WAITING, + PWR_PROC_SRV_ST_FAILED = 5, + PWR_PROC_SRV_ST_UNKNOWN = 99, +} PWR_PROC_SERVICE_STATUS; + typedef enum PWR_COM_COL_DATATYPE { PWR_COM_DATATYPE_CPU_PERF = 1, PWR_COM_DATATYPE_CPU_USAGE, @@ -298,6 +316,16 @@ typedef struct PWR_PROC_SmartGridGov { char sgLevel1Gov[PWR_MAX_ELEMENT_NAME_LEN]; } PWR_PROC_SmartGridGov; +typedef struct PWR_PROC_ServiceStatus { + PWR_PROC_SERVICE_NAME name; + PWR_PROC_SERVICE_STATUS status; +} PWR_PROC_ServiceStatus; + +typedef struct PWR_PROC_ServiceState { + PWR_PROC_SERVICE_NAME name; + int state; +} PWR_PROC_ServiceState; + // HBM typedef enum PWR_HBM_SysState { PWR_HBM_NOT_SUPPORT = 0, diff --git a/common/inc/pwrerr.h b/common/inc/pwrerr.h index 4de333e..4df6b7c 100644 --- a/common/inc/pwrerr.h +++ b/common/inc/pwrerr.h @@ -41,6 +41,8 @@ enum PWR_RtnCode { PWR_ERR_WATT_SCHED_NEVER_ENABLED, PWR_ERR_SMART_GRID_NOT_SURPPORTED, PWR_ERR_SMART_GRID_GOV_DISABLED, + PWR_ERR_SERVICE_UNABLE, + PWR_ERR_SERVICE_NOT_EXIST, PWR_ERR_DISCONNECTED = 300, PWR_ERR_WRONG_RESPONSE_FROM_SERVER, PWR_ERR_ANSWER_LONGER_THAN_SIZE, diff --git a/common/inc/pwrmsg.h b/common/inc/pwrmsg.h index 19a2e37..bcf4583 100644 --- a/common/inc/pwrmsg.h +++ b/common/inc/pwrmsg.h @@ -103,6 +103,8 @@ enum OperationType { PROC_SET_SMART_GRID_PROCS_LEVEL, PROC_GET_SMART_GRID_GOV, PROC_SET_SMART_GRID_GOV, + PROC_GET_SERVICE_STATE, + PROC_SET_SERVICE_STATE, HBM_GET_SYS_STATE = 700, HBM_SET_ALL_POWER_STATE, }; diff --git a/pwrapic/inc/powerapi.h b/pwrapic/inc/powerapi.h index 3c4c08e..245079d 100644 --- a/pwrapic/inc/powerapi.h +++ b/pwrapic/inc/powerapi.h @@ -103,6 +103,8 @@ PWR_API int PWR_PROC_GetSmartGridProcs(PWR_PROC_SMART_GRID_LEVEL level, PWR_PROC PWR_API int PWR_PROC_SetSmartGridLevel(const PWR_PROC_SmartGridProcs *sgProcs); PWR_API int PWR_PROC_GetSmartGridGov(PWR_PROC_SmartGridGov *sgGov); PWR_API int PWR_PROC_SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov); +PWR_API int PWR_PROC_GetServiceState(PWR_PROC_ServiceStatus *sStatus); +PWR_API int PWR_PROC_SetServiceState(PWR_PROC_ServiceState *sState); // HBM PWR_API int PWR_HBM_GetSysState(PWR_HBM_SysState *hbmState); diff --git a/pwrapic/inc/pwrproc.h b/pwrapic/inc/pwrproc.h index 996824c..6b160d1 100644 --- a/pwrapic/inc/pwrproc.h +++ b/pwrapic/inc/pwrproc.h @@ -31,4 +31,6 @@ int GetSmartGridProcs(PWR_PROC_SMART_GRID_LEVEL level, PWR_PROC_SmartGridProcs * int SetSmartGridLevel(const PWR_PROC_SmartGridProcs *sgProcs); int GetSmartGridGov(PWR_PROC_SmartGridGov *sgGov); int SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov); +int GetServiceState(PWR_PROC_ServiceStatus *sStatus); +int SetServiceState(const PWR_PROC_ServiceState *sState); #endif diff --git a/pwrapic/src/powerapi.c b/pwrapic/src/powerapi.c index a202570..14874e4 100644 --- a/pwrapic/src/powerapi.c +++ b/pwrapic/src/powerapi.c @@ -700,4 +700,21 @@ int PWR_PROC_SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov) return SetSmartGridGov(sgGov); } +int PWR_PROC_GetServiceState(PWR_PROC_ServiceStatus *sStatus) +{ + CHECK_STATUS(STATUS_REGISTERTED); + CHECK_NULL_POINTER(sStatus); + return GetServiceState(sStatus); +} + +int PWR_PROC_SetServiceState(PWR_PROC_ServiceState *sState) +{ + CHECK_STATUS(STATUS_REGISTERTED); + CHECK_NULL_POINTER(sState); + if (sState->state != PWR_SERVICE_START && sState->state != PWR_SERVICE_STOP) { + return PWR_ERR_INVALIDE_PARAM; + } + return SetServiceState(sState); +} + #endif // #ifndef RELEASE_MODE \ No newline at end of file diff --git a/pwrapic/src/pwrproc.c b/pwrapic/src/pwrproc.c index d14c24d..469a1c5 100644 --- a/pwrapic/src/pwrproc.c +++ b/pwrapic/src/pwrproc.c @@ -311,3 +311,45 @@ int SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov) } return ret; } + +int GetServiceState(PWR_PROC_ServiceStatus *sStatus) +{ + uint32_t size = (uint32_t)sizeof(PWR_PROC_ServiceStatus); + ReqInputParam input; + input.optType = PROC_GET_SERVICE_STATE; + input.dataLen = size; + input.data = (char *)sStatus; + + RspOutputParam output; + output.rspBuffSize = &size; + output.rspData = (char *)sStatus; + + int ret = SendReqAndWaitForRsp(input, output); + if (ret != PWR_SUCCESS) { + PwrLog(ERROR, "GetServiceState failed. ret:%d", ret); + } else { + PwrLog(DEBUG, "GetServiceState succeed."); + } + return ret; +} + +int SetServiceState(const PWR_PROC_ServiceState *sState) +{ + ReqInputParam input; + input.optType = PROC_SET_SERVICE_STATE; + uint32_t size = (uint32_t)sizeof(PWR_PROC_ServiceState); + input.dataLen = size; + input.data = (char *)sState; + + RspOutputParam output; + output.rspBuffSize = NULL; + output.rspData = NULL; + + int ret = SendReqAndWaitForRsp(input, output); + if (ret != PWR_SUCCESS) { + PwrLog(ERROR, "SetServiceState failed. ret:%d", ret); + } else { + PwrLog(DEBUG, "SetServiceState succeed."); + } + return ret; +} diff --git a/pwrapic/test/procapitest.c b/pwrapic/test/procapitest.c index 5c6e51b..955a4b5 100644 --- a/pwrapic/test/procapitest.c +++ b/pwrapic/test/procapitest.c @@ -143,6 +143,36 @@ static void TEST_PWR_PROC_SetAndGetSmartGridGov(void) ret, sgGov.sgAgentState, sgGov.sgLevel0Gov, sgGov.sgLevel1Gov); } +static void TEST_PWR_PROC_GetServiceState(void) +{ + size_t size = sizeof(PWR_PROC_ServiceStatus); + PWR_PROC_ServiceStatus *sStatus = (PWR_PROC_ServiceStatus *)malloc(size); + if (!sStatus) { + return; + } + bzero(sStatus, size); + sStatus->name = PWR_PROC_SERVICE_EAGLE; + int ret = PWR_PROC_GetServiceState(sStatus); + printf("PWR_PROC_GetServiceState ret:%d status:%d\n", ret, sStatus->status); + bzero(sStatus, size); + free(sStatus); +} + +static void TEST_PWR_PROC_SetServiceState(void) +{ + size_t size = sizeof(PWR_PROC_ServiceState); + PWR_PROC_ServiceState *sState = (PWR_PROC_ServiceState *)malloc(size); + if (!sState) { + return; + } + bzero(sState, size); + sState->name = PWR_PROC_SERVICE_EAGLE; + sState->state = PWR_SERVICE_START; + int ret = PWR_PROC_SetServiceState(sState); + printf("PWR_PROC_SetServiceState ret:%d\n", ret); + bzero(sState, size); + free(sState); +} // public============================================================================== void TEST_PROC_AllFunc(void) { @@ -153,4 +183,7 @@ void TEST_PROC_AllFunc(void) TEST_PWR_PROC_SetAndGetSmartGridState(); TEST_PWR_PROC_SetAndGetSmartGridProcs(); TEST_PWR_PROC_SetAndGetSmartGridGov(); -} \ No newline at end of file + TEST_PWR_PROC_GetServiceState(); + TEST_PWR_PROC_SetServiceState(); + TEST_PWR_PROC_GetServiceState(); +} diff --git a/pwrapis/inc/procservice.h b/pwrapis/inc/procservice.h index bb8ea3c..684210c 100644 --- a/pwrapis/inc/procservice.h +++ b/pwrapis/inc/procservice.h @@ -15,6 +15,12 @@ #ifndef PAPIS_PROC_SERVICE_H__ #define PAPIS_PROC_SERVICE_H__ #include "pwrmsg.h" +#define MAX_SERVICE_LEN 100 + +typedef struct ServiceToString { + PWR_PROC_SERVICE_NAME name; + char nameString[MAX_SERVICE_LEN]; +} ServiceToString; void ProcQueryProcs(PwrMsg *req); void ProcGetWattState(PwrMsg *req); @@ -30,4 +36,6 @@ void ProcGetSmartGridProcs(PwrMsg *req); void ProcSetSmartGridProcsLevel(PwrMsg *req); void ProcGetSmartGridGov(PwrMsg *req); void ProcSetSmartGridGov(PwrMsg *req); +void ProcGetServiceState(PwrMsg *req); +void ProcSetServiceState(PwrMsg *req); #endif diff --git a/pwrapis/src/procservice.c b/pwrapis/src/procservice.c index a231f04..54552b0 100644 --- a/pwrapis/src/procservice.c +++ b/pwrapis/src/procservice.c @@ -40,6 +40,9 @@ #define PROC_PATH "/proc" #define SMART_GRID_GOV_ENABL_PATH "/sys/devices/system/cpu/cpufreq/smart_grid_governor_enable" #define SMART_GRID_GOV_PATH "/sys/devices/system/cpu/cpufreq/smart_grid_governor" +#define SERVICE_PATH "/usr/lib/systemd/system/%s.service" +#define QUERY_SERVICE_STATE_CMD "systemctl status %s | grep -o 'Active:.*' | awk '{print $2, $3}'" +#define MODIFY_SERVICE_STATE_CMD "systemctl %s %s" #define CHECK_SUPPORT_WATT_SCHED() \ { \ @@ -65,6 +68,34 @@ } \ } +static ServiceToString g_serToString[] = { + {PWR_PROC_SERVICE_EAGLE, "eagle"}, + {PWR_PROC_SERVICE_MPCTOOL, "mpctool"}, +}; + +static int Check_Service_Exist(PWR_PROC_SERVICE_NAME name, char *serviceName) +{ + int i; + int count = sizeof(g_serToString) / sizeof(g_serToString[0]); + char servicePath[MAX_PATH_NAME] = {0}; + for (i = 0; i < count; i++) { + if (name == g_serToString[i].name) { + StrCopy(serviceName, g_serToString[i].nameString,MAX_SERVICE_LEN); + break; + } + } + if (i == count) { + return PWR_ERR_SERVICE_UNABLE; + } + if (sprintf(servicePath, SERVICE_PATH, g_serToString[i].nameString) < 0) { + return PWR_ERR_FILE_SPRINTF_FAILED; + } + if (access(servicePath, F_OK) != 0) { + return PWR_ERR_SERVICE_NOT_EXIST; + } + return PWR_SUCCESS; +} + static int QueryProcs(const char *keyWords, pid_t procs[], int maxNum, int *procNum) { char cmd[PWR_MAX_STRING_LEN] = GET_US_PROCS_CMD; @@ -321,6 +352,69 @@ static int WriteSmartGridGov(PWR_PROC_SmartGridGov *sgGov) return PWR_SUCCESS; } +static int ReadServiceState(PWR_PROC_ServiceStatus *sStatus, char *serviceName) +{ + char state[PWR_MAX_NAME_LEN]; + char cmd[PWR_MAX_STRING_LEN] = {0}; + char buf[PWR_MAX_STRING_LEN] = {0}; + + if (sprintf(cmd, QUERY_SERVICE_STATE_CMD, serviceName) < 0) { + return PWR_ERR_FILE_SPRINTF_FAILED; + } + + FILE *fp = popen(cmd, "r"); + if (fp == NULL) { + return PWR_ERR_SYS_EXCEPTION; + } + + if (fgets(buf, sizeof(buf) - 1, fp) == NULL) { + return PWR_ERR_COMMON; + } + DeleteChar(buf, '\n'); + + if (strcmp(buf, "inactive (dead)") == 0) { + sStatus->status = PWR_PROC_SRV_ST_INACTIVE; + } else if (strcmp(buf, "activating (auto-restart)") == 0) { + sStatus->status = PWR_PROC_SRV_ST_ACTIVATING; + } else if (strcmp(buf, "active (running)") == 0) { + sStatus->status = PWR_PROC_SRV_ST_RUNNING; + } else if (strcmp(buf, "active (exited)") == 0) { + sStatus->status = PWR_PROC_SRV_ST_EXITED; + } else if (strcmp(buf, "active (waiting)") == 0) { + sStatus->status = PWR_PROC_SRV_ST_WAITING; + } else if (strstr(buf, "failed") != NULL) { + sStatus->status = PWR_PROC_SRV_ST_FAILED; + } else { + sStatus->status = PWR_PROC_SRV_ST_UNKNOWN; + } + + fclose(fp); + return PWR_SUCCESS; +} + +static int ModifyServiceState(PWR_PROC_ServiceState *sState, char *serviceName) +{ + char cmd[PWR_MAX_STRING_LEN] = {0}; + char buf[PWR_MAX_STRING_LEN] = {0}; + char oper[PWR_MAX_NAME_LEN] = {0}; + if (sState->state == PWR_SERVICE_START){ + StrCopy(oper, "start", PWR_MAX_NAME_LEN); + } else { + StrCopy(oper, "stop", PWR_MAX_NAME_LEN); + } + + if (sprintf(cmd, MODIFY_SERVICE_STATE_CMD, oper, serviceName) < 0) { + return PWR_ERR_FILE_SPRINTF_FAILED; + } + + FILE *fp = popen(cmd, "r"); + if (fp == NULL) { + return PWR_ERR_SYS_EXCEPTION; + } + fclose(fp); + return PWR_SUCCESS; +} + // public=========================================================================================== void ProcQueryProcs(PwrMsg *req) { @@ -601,3 +695,50 @@ void ProcSetSmartGridGov(PwrMsg *req) } SendRspToClient(req, WriteSmartGridGov(sgGov), NULL, 0); } + +void ProcGetServiceState(PwrMsg *req) +{ + if (req->head.dataLen < sizeof(PWR_PROC_ServiceStatus) || !req->data) { + SendRspToClient(req, PWR_ERR_SYS_EXCEPTION, NULL, 0); + return; + } + PWR_PROC_ServiceStatus *sStatus = (PWR_PROC_ServiceStatus *)req->data; + if (!sStatus) { + SendRspToClient(req, PWR_ERR_SYS_EXCEPTION, NULL, 0); + return; + } + size_t size = sizeof(PWR_PROC_ServiceStatus); + char serviceName[MAX_SERVICE_LEN] = {0}; + int ret = Check_Service_Exist(sStatus->name, serviceName); + if (ret != PWR_SUCCESS) { + SendRspToClient(req, ret, NULL, 0); + } + ret = ReadServiceState(sStatus, serviceName); + if (ret != PWR_SUCCESS) { + SendRspToClient(req, ret, NULL, 0); + } else { + req->data = NULL; // move the memory to rsp msg + SendRspToClient(req, ret, (char *)sStatus, size); + } +} + +void ProcSetServiceState(PwrMsg *req) +{ + if (req->head.dataLen < sizeof(PWR_PROC_ServiceState) || !req->data) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + PWR_PROC_ServiceState *sState = (PWR_PROC_ServiceState *)req->data; + if (sState->state != PWR_SERVICE_START && sState->state != PWR_SERVICE_STOP) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + char serviceName[MAX_SERVICE_LEN] = {0}; + int ret = Check_Service_Exist(sState->name, serviceName); + if (ret != PWR_SUCCESS) { + SendRspToClient(req, ret, NULL, 0); + } + ret = ModifyServiceState(sState, serviceName); + + SendRspToClient(req, ret, NULL, 0); +} \ No newline at end of file diff --git a/pwrapis/src/server.c b/pwrapis/src/server.c index 95decc1..97ec4b1 100644 --- a/pwrapis/src/server.c +++ b/pwrapis/src/server.c @@ -521,6 +521,8 @@ static OptToFunct g_optToFunct[] = { {PROC_SET_SMART_GRID_PROCS_LEVEL, ProcSetSmartGridProcsLevel}, {PROC_GET_SMART_GRID_GOV, ProcGetSmartGridGov}, {PROC_SET_SMART_GRID_GOV, ProcSetSmartGridGov}, + {PROC_GET_SERVICE_STATE, ProcGetServiceState}, + {PROC_SET_SERVICE_STATE, ProcSetServiceState}, {HBM_GET_SYS_STATE, GetHbmSysState}, {HBM_SET_ALL_POWER_STATE, SetHbmAllPowerState}, }; -- Gitee