From 0b5c400e76f0ade4324599973d4f2fff64fb5a3a Mon Sep 17 00:00:00 2001 From: zhong_ning Date: Tue, 13 Jul 2021 22:24:42 +0800 Subject: [PATCH] modify l2 init Signed-off-by: zhong_ning --- services/etc/init.cfg | 8 +- services/etc/init.usb.cfg | 9 +- services/include/init_cmds.h | 19 +++ services/include/init_utils.h | 7 - services/param/include/trigger_checker.h | 9 + services/param/include/trigger_manager.h | 17 +- services/param/trigger/trigger_checker.c | 60 ++++--- services/param/trigger/trigger_manager.c | 120 +++++++++----- services/param/trigger/trigger_processor.c | 7 + services/src/init_cmds.c | 181 +++++++++++++++++++-- services/src/init_import.c | 78 +-------- services/src/init_utils.c | 72 ++------ 12 files changed, 362 insertions(+), 225 deletions(-) diff --git a/services/etc/init.cfg b/services/etc/init.cfg index 25a1e2a94..e04db0622 100755 --- a/services/etc/init.cfg +++ b/services/etc/init.cfg @@ -3,12 +3,12 @@ "/init.environ.cfg", "/init.usb.cfg", "/init.${ro.hardware}.cfg", - "/init.Hi3516DV300.cfg", "/init.usb.configfs.cfg", "/init.${ro.zygote}.cfg", - "/init.Hi3516DV300.usb.cfg", "/init.usb.configfs.cfg", - "/init.usb.cfg" + "/init.usb.cfg", + "/init.Hi3516DV300.usb.cfg", + "/init.Hi3516DV300.cfg" ], "jobs" : [{ "name" : "pre-init", @@ -173,6 +173,8 @@ "write /proc/sys/abi/swp 1", "symlink /proc/self/fd /dev/fd", "export DOWNLOAD_CACHE /data/cache", + "setrlimit RLIMIT_NICE 40 40", + "setrlimit RLIMIT_NOFILE 32768 32768", "write /sys/class/leds/vibrator/trigger \"transient\"", "write /dev/cpu_variant:${ro.bionic.arch} ${ro.bionic.cpu_variant}", "chmod 0444 /dev/cpu_variant:${ro.bionic.arch}", diff --git a/services/etc/init.usb.cfg b/services/etc/init.usb.cfg index 2dbac3d11..5cf0ddb6b 100755 --- a/services/etc/init.usb.cfg +++ b/services/etc/init.usb.cfg @@ -7,8 +7,7 @@ "chown system system /sys/class/android_usb/android0/f_rndis/ethaddr", "chmod 0660 /sys/class/android_usb/android0/f_rndis/ethaddr", "mkdir /data/misc/adb 02750 system shell", - "mkdir /data/adb 0700 root root", - "start adbd" + "mkdir /data/adb 0700 root root" ] }, { "name" : "boot", @@ -105,6 +104,12 @@ "start adbd", "setparam sys.usb.state ${sys.usb.config}" ] + }, { + "name" : "boot && param:persist.sys.usb.config=*", + "condition" : "boot && persist.sys.usb.config=*", + "cmds" : [ + "setparam sys.usb.config ${persist.sys.usb.config}" + ] }, { "name" : "param:sys.usb.typec.mode=dfp", "condition" : "sys.usb.typec.mode=dfp", diff --git a/services/include/init_cmds.h b/services/include/init_cmds.h index e7777f4d4..bdf88120d 100644 --- a/services/include/init_cmds.h +++ b/services/include/init_cmds.h @@ -27,12 +27,31 @@ extern "C" { #define MAX_CMD_CNT_IN_ONE_JOB 200 #define MAX_COPY_BUF_SIZE 256 #define DEFAULT_COPY_ARGS_CNT 2 + +#ifndef OHOS_LITE +// Limit max length of parameter value to 96 +#define MAX_PARAM_VALUE_LEN 96 +// Limit max length of parameter name to 96 +#define MAX_PARAM_NAME_LEN 96 +#endif + // one cmd line typedef struct { char name[MAX_CMD_NAME_LEN + 1]; char cmdContent[MAX_CMD_CONTENT_LEN + 1]; } CmdLine; +struct CmdArgs { + int argc; + char **argv; +}; + +#ifndef OHOS_LITE +int GetParamValue(char *symValue, char *paramValue, unsigned int paramLen); +#endif +struct CmdArgs* GetCmd(const char *cmdContent, const char *delim); +void FreeCmd(struct CmdArgs **cmd); + void ParseCmdLine(const char* cmdStr, CmdLine* resCmd); void DoCmd(const CmdLine* curCmd); diff --git a/services/include/init_utils.h b/services/include/init_utils.h index 502cd34f4..3dcdbcbda 100644 --- a/services/include/init_utils.h +++ b/services/include/init_utils.h @@ -26,13 +26,6 @@ extern "C" { #define OCTAL_BASE 8 #define DECIMAL_BASE 10 -struct CmdArgs { - int argc; - char **argv; -}; - -struct CmdArgs* GetCmd(const char *cmdContent, const char *delim); -void FreeCmd(struct CmdArgs **cmd); int DecodeUid(const char *name); void CheckAndCreateDir(const char *fileName); char* ReadFileToBuf(const char *configFile); diff --git a/services/param/include/trigger_checker.h b/services/param/include/trigger_checker.h index e3b9a3ed2..8bba9e1e4 100644 --- a/services/param/include/trigger_checker.h +++ b/services/param/include/trigger_checker.h @@ -26,6 +26,10 @@ extern "C" { #endif #endif +#define MAX_TRIGGER_CMD_NAME_LEN 32 +#define MAX_TRIGGER_NAME_LEN 128 +#define MAX_TRIGGER_TYPE_LEN 16 + #define SUPPORT_DATA_BUFFER_MAX 128 #define CONDITION_EXTEND_LEN 32 @@ -42,7 +46,11 @@ typedef struct { u_int32_t endIndex; } LogicData; +struct tagTriggerNode; + typedef struct { + char triggerContent[MAX_TRIGGER_NAME_LEN]; + int (*triggerExecuter)(struct tagTriggerNode *trigger, u_int32_t index); int dataNumber; int endIndex; int dataUnit; @@ -59,6 +67,7 @@ void CalculatorFree(LogicCalculator *calculator); int ConvertInfixToPrefix(const char *condition, char *prefix, u_int32_t prefixLen); int ComputeCondition(LogicCalculator *calculator, const char *condition); int GetValueFromContent(const char *content, u_int32_t contentSize, u_int32_t start, char *value, u_int32_t valueSize); +char *GetMatchedSubCondition(const char *condition, const char *input, int length); #ifdef __cplusplus #if __cplusplus diff --git a/services/param/include/trigger_manager.h b/services/param/include/trigger_manager.h index 4dcbf6e03..dc3362b8f 100644 --- a/services/param/include/trigger_manager.h +++ b/services/param/include/trigger_manager.h @@ -23,6 +23,7 @@ #include "cJSON.h" #include "init_log.h" #include "param_manager.h" +#include "trigger_checker.h" #include "securec.h" #ifdef __cplusplus @@ -35,10 +36,6 @@ extern "C" { #define TRIGGER_ARR_NAME_IN_JSON "jobs" #define CMDS_ARR_NAME_IN_JSON "cmds" -#define MAX_TRIGGER_CMD_NAME_LEN 32 -#define MAX_TRIGGER_NAME_LEN 64 -#define MAX_TRIGGER_TYPE_LEN 16 - #define TRIGGER_NODE_IN_QUEUE(trigger) \ (atomic_load_explicit(&(trigger)->serial, memory_order_relaxed) & 0x01) #define TRIGGER_NODE_SET_QUEUE_FLAG(trigger) \ @@ -48,7 +45,7 @@ extern "C" { typedef enum { TRIGGER_BOOT = 0, - TRIGGER_PROPERTY, + TRIGGER_PARAM, TRIGGER_UNKNOW, TRIGGER_MAX }TriggerType; @@ -60,7 +57,7 @@ typedef struct CommandNode { char content[0]; } CommandNode; -typedef struct { +typedef struct tagTriggerNode { atomic_uint_least32_t serial; atomic_uint_least32_t next; atomic_uint_least32_t firstCmd; @@ -100,8 +97,8 @@ typedef struct TriggerWorkSpace { int InitTriggerWorkSpace(TriggerWorkSpace *workSpace); int ParseTrigger(TriggerWorkSpace *workSpace, cJSON *triggerItem); -typedef int (*TRIGGER_MATCH)(TriggerNode *trigger, void *content, u_int32_t contentSize); -typedef int (*PARAM_CHECK_DONE) (TriggerNode *trigger, u_int32_t index); +typedef int (*TRIGGER_MATCH)(LogicCalculator *calculator, TriggerNode *trigger, const char *content, u_int32_t contentSize); +typedef int (*PARAM_CHECK_DONE)(TriggerNode *trigger, u_int32_t index); typedef int (*CMD_EXECUTE) (TriggerNode *trigger, const char *cmdName, const char *command); TriggerNode *GetTriggerByName(TriggerWorkSpace *workSpace, const char *triggerName, u_int32_t *triggerIndex); @@ -110,11 +107,15 @@ int CheckTrigger(TriggerWorkSpace *workSpace, int type, void *content, u_int32_t contentSize, PARAM_CHECK_DONE triggerExecuter); int CheckParamTrigger(TriggerWorkSpace *workSpace, const char *content, u_int32_t contentSize, PARAM_CHECK_DONE triggerExecuter); +int CheckAndExecuteTrigger(TriggerWorkSpace *workSpace, const char *content, PARAM_CHECK_DONE triggerExecuter); TriggerNode *ExecuteQueuePop(TriggerWorkSpace *workSpace); int ExecuteQueuePush(TriggerWorkSpace *workSpace, TriggerNode *trigger, u_int32_t index); int ExecuteQueueSize(TriggerWorkSpace *workSpace); +u_int32_t AddTrigger(TriggerWorkSpace *workSpace, int type, const char *name, const char *condition); +u_int32_t AddCommand(TriggerWorkSpace *workSpace, TriggerNode *trigger, const char *cmdName, const char *content); + TriggerWorkSpace *GetTriggerWorkSpace(); #ifdef __cplusplus diff --git a/services/param/trigger/trigger_checker.c b/services/param/trigger/trigger_checker.c index 947635d36..c2de5e234 100644 --- a/services/param/trigger/trigger_checker.c +++ b/services/param/trigger/trigger_checker.c @@ -16,7 +16,7 @@ #include "trigger_checker.h" #include #include "trigger_manager.h" -#include "param_service.h" +#include "init_param.h" #define LABEL "Trigger" // 申请整块能存作为计算的节点 @@ -43,7 +43,8 @@ int CalculatorInit(LogicCalculator *calculator, int dataNumber, int dataUnit, in calculator->inputContent = calculator->data + dataSize; dataSize += SUPPORT_DATA_BUFFER_MAX; calculator->readContent = calculator->data + dataSize; - return 0; + return memset_s(calculator->triggerContent, + sizeof(calculator->triggerContent), 0, sizeof(calculator->triggerContent)); } void CalculatorFree(LogicCalculator *calculator) @@ -149,27 +150,35 @@ static int ComputeSubCondition(LogicCalculator *calculator, LogicData *data, con return LOGIC_DATA_TEST_FLAG(data, LOGIC_DATA_FLAGS_TRUE); } // 解析条件 - int ret = GetValueFromContent(condition + data->startIndex, - data->endIndex - data->startIndex, 0, calculator->conditionName, SUPPORT_DATA_BUFFER_MAX); - PARAM_CHECK(ret == 0, return -1, "Failed parse content name"); - ret = GetValueFromContent(condition + data->startIndex, data->endIndex - data->startIndex, - strlen(calculator->conditionName) + 1, calculator->conditionContent, SUPPORT_DATA_BUFFER_MAX); - PARAM_CHECK(ret == 0, return -1, "Failed parse content value"); - // check name - if (strcmp(calculator->conditionName, calculator->inputName) == 0) { - if (strcmp(calculator->conditionContent, "*") == 0) { - return 1; - } - if (strcmp(calculator->conditionContent, calculator->inputContent) == 0) { + char *subStr = strstr(condition + data->startIndex, "="); + if (subStr != NULL && ((u_int32_t)(subStr - condition) > data->endIndex)) { + if (strncmp(condition + data->startIndex, calculator->triggerContent, strlen(calculator->triggerContent)) == 0) { return 1; } - }/* else { - u_int32_t len = SUPPORT_DATA_BUFFER_MAX; - ret = SystemReadParam(calculator->conditionName, calculator->readContent, &len); - if (ret == 0 && strcmp(calculator->conditionContent, calculator->readContent) == 0) { - return 1; + } else { + int ret = GetValueFromContent(condition + data->startIndex, + data->endIndex - data->startIndex, 0, calculator->conditionName, SUPPORT_DATA_BUFFER_MAX); + PARAM_CHECK(ret == 0, return -1, "Failed parse content name"); + ret = GetValueFromContent(condition + data->startIndex, data->endIndex - data->startIndex, + strlen(calculator->conditionName) + 1, calculator->conditionContent, SUPPORT_DATA_BUFFER_MAX); + PARAM_CHECK(ret == 0, return -1, "Failed parse content value"); + // check name + if (calculator->inputName && strcmp(calculator->conditionName, calculator->inputName) == 0) { + if (strcmp(calculator->conditionContent, "*") == 0) { + return 1; + } + if (strcmp(calculator->conditionContent, calculator->inputContent) == 0) { + return 1; + } + } else { + u_int32_t len = SUPPORT_DATA_BUFFER_MAX; + ret = SystemReadParam(calculator->conditionName, calculator->readContent, &len); + if (ret == 0 && (strcmp(calculator->conditionContent, "*") == 0 || + strcmp(calculator->conditionContent, calculator->readContent) == 0)) { + return 1; + } } - }*/ + } return 0; } @@ -289,4 +298,15 @@ int ConvertInfixToPrefix(const char *condition, char *prefix, u_int32_t prefixLe prefix[prefixIndex] = '\0'; CalculatorFree(&calculator); return 0; +} + +char *GetMatchedSubCondition(const char *condition, const char *input, int length) +{ + const char *p = condition; + for(;(p = strchr(p, *input)) != 0; p++) { + if(strncmp(p, input, length) == 0) { + return (char*)p; + } + } + return NULL; } \ No newline at end of file diff --git a/services/param/trigger/trigger_manager.c b/services/param/trigger/trigger_manager.c index d44607530..4c78c6f03 100644 --- a/services/param/trigger/trigger_manager.c +++ b/services/param/trigger/trigger_manager.c @@ -90,7 +90,7 @@ static CommandNode *GetCmdByIndex(TriggerWorkSpace *workSpace, TriggerNode *trig return (CommandNode *)(workSpace->area->data + index); } -static u_int32_t AddCommand(TriggerWorkSpace *workSpace, TriggerNode *trigger, const char *cmdName, const char *content) +u_int32_t AddCommand(TriggerWorkSpace *workSpace, TriggerNode *trigger, const char *cmdName, const char *content) { PARAM_CHECK(workSpace != NULL && trigger != NULL, return 0, "list is null"); u_int32_t size = sizeof(CommandNode) + strlen(cmdName) + 1; @@ -141,7 +141,7 @@ static TriggerNode *GetTriggerByIndex(TriggerWorkSpace *workSpace, u_int32_t ind return (TriggerNode *)(workSpace->area->data + index); } -static u_int32_t AddTrigger(TriggerWorkSpace *workSpace, int type, const char *name, const char *condition) +u_int32_t AddTrigger(TriggerWorkSpace *workSpace, int type, const char *name, const char *condition) { PARAM_CHECK(workSpace != NULL && name != NULL, return 0, "list is null"); const char *tmpCond = condition; @@ -161,14 +161,8 @@ static u_int32_t AddTrigger(TriggerWorkSpace *workSpace, int type, const char *n node->name[strlen(name)] = '\0'; if (tmpCond != NULL) { - if (type == TRIGGER_PROPERTY) { - ret = ConvertInfixToPrefix(tmpCond, node->condition, conditionSize); - PARAM_CHECK(ret == 0, return 0, "Failed to memcpy_s for trigger"); - } else { - ret = memcpy_s(node->condition, strlen(tmpCond) + 1, tmpCond, strlen(tmpCond)); - PARAM_CHECK(ret == 0, return 0, "Failed to memcpy_s for trigger"); - node->condition[strlen(tmpCond)] = '\0'; - } + ret = ConvertInfixToPrefix(tmpCond, node->condition, conditionSize); + PARAM_CHECK(ret == 0, return 0, "Failed to memcpy_s for trigger"); } else { node->condition[0] = '\0'; } @@ -197,18 +191,18 @@ static u_int32_t AddTrigger(TriggerWorkSpace *workSpace, int type, const char *n static int GetTriggerIndex(const char *type) { if (strncmp("param:", type, strlen("param:")) == 0) { - return TRIGGER_PROPERTY; - } else { - return TRIGGER_BOOT; + return TRIGGER_PARAM; } -} - -static int CheckBootTriggerMatch(TriggerNode *trigger, void *content, u_int32_t contentSize) -{ - if (strncmp(trigger->name, (char *)content, contentSize) == 0) { - return 1; + static const char *triggerType[] = { + "pre-init", "boot", "early-init", "init", "early-init", "late-init", "post-init", + "early-fs", "post-fs", "late-fs", "post-fs-data" + }; + for (size_t i = 0; i < sizeof(triggerType) / sizeof(char*); i++) { + if (strcmp(triggerType[i], type) == 0) { + return TRIGGER_BOOT; + } } - return 0; + return TRIGGER_UNKNOW; } int ParseTrigger(TriggerWorkSpace *workSpace, cJSON *triggerItem) @@ -306,23 +300,50 @@ int ExecuteQueueSize(TriggerWorkSpace *workSpace) return workSpace->executeQueue.endIndex - workSpace->executeQueue.startIndex; } -int CheckTrigger(TriggerWorkSpace *workSpace, - int type, void *content, u_int32_t contentSize, PARAM_CHECK_DONE triggerExecuter) +static int CheckBootTriggerMatch(LogicCalculator *calculator, + TriggerNode *trigger, const char *content, u_int32_t contentSize) +{ + if (strncmp(trigger->name, (char *)content, contentSize) == 0) { + return 1; + } + return 0; +} + +static int CheckParamTriggerMatch(LogicCalculator *calculator, + TriggerNode *trigger, const char *content, u_int32_t contentSize) +{ + if (calculator->inputName != NULL) { // 存在input数据时,先过滤非input的 + if (GetMatchedSubCondition(trigger->condition, content, strlen(calculator->inputName) + 1) == NULL) { + return 0; + } + } + return ComputeCondition(calculator, trigger->condition); +} + +static int CheckOtherTriggerMatch(LogicCalculator *calculator, + TriggerNode *trigger, const char *content, u_int32_t contentSize) +{ + return ComputeCondition(calculator, trigger->condition); +} + +static int CheckTrigger_(TriggerWorkSpace *workSpace, + LogicCalculator *calculator, int type, const char *content, u_int32_t contentSize) { static TRIGGER_MATCH triggerCheckMatch[TRIGGER_MAX] = { - CheckBootTriggerMatch, NULL, NULL + CheckBootTriggerMatch, CheckParamTriggerMatch, CheckOtherTriggerMatch }; - PARAM_LOGI("ExecuteTrigger check content %s", (char*)content); - PARAM_CHECK(workSpace != NULL, return -1, "Trigger not init"); + PARAM_LOGI("CheckTrigger_ content %s ", content); + PARAM_CHECK(calculator != NULL, return -1, "Failed to check calculator"); PARAM_CHECK(CHECK_INDEX_VALID(workSpace, type), return -1, "Invalid type %d", type); PARAM_CHECK((u_int32_t)type < sizeof(triggerCheckMatch) / sizeof(triggerCheckMatch[0]), return -1, "Failed to get check function"); - PARAM_CHECK(triggerCheckMatch[type] != NULL, return 0, "Failed to get check function"); + PARAM_CHECK(triggerCheckMatch[type] != NULL, return -1, "Failed to get check function"); + u_int32_t index = workSpace->header[type].firstTrigger; TriggerNode *trigger = GetTriggerByIndex(workSpace, workSpace->header[type].firstTrigger); while (trigger != NULL) { - if (triggerCheckMatch[type](trigger, content, contentSize) == 1) { // 等于1 则认为匹配 - triggerExecuter(trigger, index); + if (triggerCheckMatch[type](calculator, trigger, content, contentSize) == 1) { // 等于1 则认为匹配 + calculator->triggerExecuter(trigger, index); } index = trigger->next; trigger = GetTriggerByIndex(workSpace, trigger->next); @@ -330,6 +351,17 @@ int CheckTrigger(TriggerWorkSpace *workSpace, return 0; } +int CheckTrigger(TriggerWorkSpace *workSpace, + int type, void *content, u_int32_t contentSize, PARAM_CHECK_DONE triggerExecuter) +{ + PARAM_CHECK(workSpace != NULL && content != NULL && triggerExecuter != NULL, + return -1, "Failed arg for trigger"); + + LogicCalculator calculator; + calculator.triggerExecuter = triggerExecuter; + return CheckTrigger_(workSpace, &calculator, type, (char *)content, contentSize); +} + int CheckParamTrigger(TriggerWorkSpace *workSpace, const char *content, u_int32_t contentSize, PARAM_CHECK_DONE triggerExecuter) { @@ -344,18 +376,28 @@ int CheckParamTrigger(TriggerWorkSpace *workSpace, ret = GetValueFromContent(content, contentSize, strlen(calculator.inputName) + 1, calculator.inputContent, SUPPORT_DATA_BUFFER_MAX); PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed parse content value"); - PARAM_LOGI("CheckParamTrigger content %s ", content); - u_int32_t index = workSpace->header[TRIGGER_PROPERTY].firstTrigger; - TriggerNode *trigger = GetTriggerByIndex(workSpace, workSpace->header[TRIGGER_PROPERTY].firstTrigger); - while (trigger != NULL) { - ret = ComputeCondition(&calculator, trigger->condition); - if (ret == 1) { - triggerExecuter(trigger, index); - } - index = trigger->next; - trigger = GetTriggerByIndex(workSpace, trigger->next); - } + calculator.triggerExecuter = triggerExecuter; + CheckTrigger_(workSpace, &calculator, TRIGGER_PARAM, content, contentSize); + CalculatorFree(&calculator); + return 0; +} + +int CheckAndExecuteTrigger(TriggerWorkSpace *workSpace, const char *content, PARAM_CHECK_DONE triggerExecuter) +{ + PARAM_CHECK(workSpace != NULL && content != NULL && triggerExecuter != NULL, + return -1, "Failed arg for param trigger"); + LogicCalculator calculator; + CalculatorInit(&calculator, 100, sizeof(LogicData), 1); + + int ret = memcpy_s(calculator.triggerContent, sizeof(calculator.triggerContent), content, strlen(content)); + PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed to memcpy"); + + calculator.triggerExecuter = triggerExecuter; + calculator.inputName = NULL; + calculator.inputContent = NULL; + // 执行完成后,对第三类trigger检查,执行必须是在本阶段执行的trigger + CheckTrigger_(workSpace, &calculator, TRIGGER_UNKNOW, content, 0); CalculatorFree(&calculator); return 0; } diff --git a/services/param/trigger/trigger_processor.c b/services/param/trigger/trigger_processor.c index 5c241b6bb..99486cf88 100644 --- a/services/param/trigger/trigger_processor.c +++ b/services/param/trigger/trigger_processor.c @@ -52,6 +52,11 @@ static int DoTiggerCheckResult(TriggerNode *trigger, u_int32_t triggerIndex) return 0; } +static int ExecuteTiggerImmediately(TriggerNode *trigger, u_int32_t triggerIndex) +{ + return ExecuteTrigger(&g_triggerWorkSpace, trigger, DoCmdExecute); +} + void ExecuteQueueWork(u_int32_t maxCount) { u_int32_t executeCount = 0; @@ -59,6 +64,8 @@ void ExecuteQueueWork(u_int32_t maxCount) while (trigger != NULL) { ExecuteTrigger(&g_triggerWorkSpace, trigger, DoCmdExecute); TRIGGER_NODE_CLEAR_QUEUE_FLAG(trigger); + CheckAndExecuteTrigger(&g_triggerWorkSpace, trigger->name, ExecuteTiggerImmediately); + executeCount++; if (executeCount > maxCount) { break; diff --git a/services/src/init_cmds.c b/services/src/init_cmds.c index 66a55eabd..50dc77a31 100644 --- a/services/src/init_cmds.c +++ b/services/src/init_cmds.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -33,13 +34,13 @@ #include #include "init_jobs.h" #include "init_log.h" +#ifndef OHOS_LITE +#include "init_param.h" +#endif #include "init_reboot.h" #include "init_service_manager.h" #include "init_utils.h" #include "securec.h" -#ifndef OHOS_LITE -#include "init_param.h" -#endif #define DEFAULT_DIR_MODE 0755 // mkdir, default mode #define SPACES_CNT_IN_CMD_MAX 10 // mount, max number of spaces in cmdline @@ -52,6 +53,7 @@ #define MAX_BUFFER 256 #define AUTHORITY_MAX_SIZE 128 #define WAIT_MAX_COUNT 10 +#define MAX_EACH_CMD_LENGTH 30 static const char *g_supportCfg[] = { "/etc/patch.cfg", @@ -82,8 +84,120 @@ static const char* g_supportedCmds[] = { "load_persist_params ", "load_param ", "reboot ", + "setrlimit ", }; +#ifndef OHOS_LITE +int GetParamValue(char *symValue, char *paramValue, unsigned int paramLen) +{ + if ((symValue == NULL) || (paramValue == NULL) || (paramLen == 0)) { + return -1; + } + char tmpName[MAX_PARAM_NAME_LEN] = {0}; + char tmpValue[MAX_PARAM_VALUE_LEN] = {0}; + unsigned int tmpLen = 0; + char *p = NULL; + char *tmpptr = NULL; + p = strchr(symValue, '$'); + if (p == NULL) { // not has '$' copy the original string + INIT_CHECK_ONLY_RETURN(strncpy_s(paramValue, paramLen, symValue, + paramLen - 1) == EOK, return -1); + return 0; + } + tmpLen = p - symValue; + if (tmpLen > 0) { // copy '$' front string + INIT_CHECK_ONLY_RETURN(strncpy_s(paramValue, paramLen, symValue, tmpLen) == EOK, return -1); + } + p++; + if (*p == '{') { + p++; + char *right = strchr(p, '}'); + if (right == NULL) { + INIT_LOGE("Invalid cfg file name, miss '}'.\n"); + return -1; + } + tmpLen = right - p; + if (tmpLen > MAX_PARAM_NAME_LEN) { + INIT_LOGE("Parameter name longer than %d\n", MAX_PARAM_NAME_LEN); + return -1; + } + INIT_CHECK_ONLY_RETURN(strncpy_s(tmpName, MAX_PARAM_NAME_LEN, p, tmpLen) == EOK, return -1); + int ret = SystemReadParam(tmpName, tmpValue, &tmpLen); // get param + if (ret != 0) { + INIT_LOGE("Failed to read parameter \" %s \"\n", tmpName); + return -1; + } + // change param to new string + INIT_CHECK_ONLY_RETURN(strncat_s(paramValue, paramLen, tmpValue, MAX_PARAM_VALUE_LEN) == EOK, return -1); + tmpptr = right + 1; + tmpLen = paramLen - (tmpptr - symValue); + if (*tmpptr != '\0') { // copy last string + INIT_CHECK_ONLY_RETURN(strncat_s(paramValue, paramLen, tmpptr, tmpLen) == EOK, return -1); + } + INIT_LOGI("paramValue is %s \n", paramValue); + return 0; + } else { + INIT_LOGE("Invalid cfg file name, miss '{'.\n"); + return -1; + } +} +#endif + +struct CmdArgs* GetCmd(const char *cmdContent, const char *delim) +{ + struct CmdArgs *ctx = (struct CmdArgs *)malloc(sizeof(struct CmdArgs)); + INIT_CHECK_ONLY_RETURN(ctx != NULL, return NULL); + + ctx->argv = (char**)malloc(sizeof(char*) * MAX_CMD_NAME_LEN); + INIT_CHECK_ONLY_RETURN(ctx->argv != NULL, FreeCmd(&ctx); return NULL); + + char tmpCmd[MAX_BUFFER]; + INIT_CHECK_ONLY_RETURN(strncpy_s(tmpCmd, strlen(cmdContent) + 1, cmdContent, strlen(cmdContent)) == EOK, + FreeCmd(&ctx); + return NULL); + tmpCmd[strlen(cmdContent)] = '\0'; + + char *buffer = NULL; + char *token = strtok_r(tmpCmd, delim, &buffer); + ctx->argc = 0; + while (token != NULL) { +#ifndef OHOS_LITE + ctx->argv[ctx->argc] = calloc(sizeof(char *), MAX_EACH_CMD_LENGTH + MAX_PARAM_VALUE_LEN); + INIT_CHECK_ONLY_RETURN(ctx->argv[ctx->argc] != NULL, FreeCmd(&ctx); return NULL); + INIT_CHECK_ONLY_RETURN(GetParamValue(token, ctx->argv[ctx->argc], MAX_EACH_CMD_LENGTH + MAX_PARAM_VALUE_LEN) == 0, + FreeCmd(&ctx); + return NULL); +#else + ctx->argv[ctx->argc] = calloc(sizeof(char *), MAX_EACH_CMD_LENGTH); + INIT_CHECK_ONLY_RETURN(ctx->argv[ctx->argc] != NULL, FreeCmd(&ctx); return NULL); + INIT_CHECK_ONLY_RETURN(strncpy_s(ctx->argv[ctx->argc], strlen(cmdContent) + 1, token, strlen(token)) == EOK, + FreeCmd(&ctx); + return NULL); +#endif + if (ctx->argc > MAX_CMD_NAME_LEN - 1) { + INIT_LOGE("GetCmd failed, max cmd number is 10.\n"); + FreeCmd(&ctx); + return NULL; + } + token = strtok_r(NULL, delim, &buffer); + ctx->argc += 1; + } + ctx->argv[ctx->argc] = NULL; + return ctx; +} + +void FreeCmd(struct CmdArgs **cmd) +{ + struct CmdArgs *tmpCmd = *cmd; + INIT_CHECK_ONLY_RETURN(tmpCmd != NULL, return); + for (int i = 0; i < tmpCmd->argc; ++i) { + INIT_CHECK_ONLY_RETURN(tmpCmd->argv[i] == NULL, free(tmpCmd->argv[i])); + } + INIT_CHECK_ONLY_RETURN(tmpCmd->argv == NULL, free(tmpCmd->argv)); + free(tmpCmd); + return; +} + void ParseCmdLine(const char* cmdStr, CmdLine* resCmd) { size_t cmdLineLen = 0; @@ -217,20 +331,9 @@ static void DoMkDir(const char* cmdContent) } mode_t mode = DEFAULT_DIR_MODE; - for (size_t i = 0; i < strlen(ctx->argv[0]); ++i) { - if (ctx->argv[0][i] == '/') { - ctx->argv[0][i] = '\0'; - if (access(ctx->argv[0], 0) != 0 ) { - mkdir(ctx->argv[0], mode); - } - ctx->argv[0][i]='/'; - } - } - if (access(ctx->argv[0], 0) != 0) { - if (mkdir(ctx->argv[0], mode) != 0 && errno != EEXIST) { - INIT_LOGE("DoMkDir %s failed, err %d.\n", ctx->argv[0], errno); - goto out; - } + if (mkdir(ctx->argv[0], mode) != 0 && errno != EEXIST) { + INIT_LOGE("DoMkDir, failed for %s, err %d.\n", cmdContent, errno); + goto out; } if (ctx->argc > 1) { @@ -653,6 +756,45 @@ out: return; } +static void DoSetrlimit(const char *cmdContent) +{ + char *resource[] = { + "RLIMIT_CPU", "RLIMIT_FSIZE", "RLIMIT_DATA", "RLIMIT_STACK", "RLIMIT_CORE", "RLIMIT_RSS", + "RLIMIT_NPROC", "RLIMIT_NOFILE", "RLIMIT_MEMLOCK", "RLIMIT_AS", "RLIMIT_LOCKS", "RLIMIT_SIGPENDING", + "RLIMIT_MSGQUEUE", "RLIMIT_NICE", "RLIMIT_RTPRIO", "RLIMIT_RTTIME", "RLIM_NLIMITS" + }; + // format: setrlimit resource curValue maxValue + struct CmdArgs *ctx = GetCmd(cmdContent, " "); + int setrlimitCmdNumber = 3; + int rlimMaxPos = 2; + if (ctx == NULL || ctx->argv == NULL || ctx->argc != setrlimitCmdNumber) { + INIT_LOGE("DoSetrlimit: invalid arguments\n"); + goto out; + } + + struct rlimit limit; + limit.rlim_cur = atoi(ctx->argv[1]); + limit.rlim_max = atoi(ctx->argv[rlimMaxPos]); + int rcs = -1; + for (unsigned int i = 0 ; i < sizeof(resource) / sizeof(char*); ++i) { + if (strcmp(ctx->argv[0], resource[i]) == 0) { + rcs = (int)i; + } + } + if (rcs == -1) { + INIT_LOGE("DoSetrlimit failed, resouces :%s not support.\n", ctx->argv[0]); + goto out; + } + int ret = setrlimit(rcs, &limit); + if (ret) { + INIT_LOGE("DoSetrlimit failed : %d\n", errno); + goto out; + } +out: + FreeCmd(&ctx); + return; +} + static void DoRm(const char *cmdContent) { // format: rm /xxx/xxx/xxx @@ -675,7 +817,8 @@ static void DoExport(const char *cmdContent) { // format: export xxx /xxx/xxx/xxx struct CmdArgs *ctx = GetCmd(cmdContent, " "); - if (ctx == NULL || ctx->argv == NULL || ctx->argc != 2) { + int exportCmdNumber = 2; + if (ctx == NULL || ctx->argv == NULL || ctx->argc != exportCmdNumber) { INIT_LOGE("DoExport: invalid arguments\n"); goto out; } @@ -852,6 +995,8 @@ void DoCmdByName(const char *name, const char *cmdContent) DoRm(cmdContent); } else if (strncmp(name, "export ", strlen("export ")) == 0) { DoExport(cmdContent); + } else if (strncmp(name, "setrlimit ", strlen("setrlimit ")) == 0) { + DoSetrlimit(cmdContent); } else if (strncmp(name, "exec ", strlen("exec ")) == 0) { DoExec(cmdContent); #ifndef __LITEOS__ diff --git a/services/src/init_import.c b/services/src/init_import.c index 628370325..aff687940 100644 --- a/services/src/init_import.c +++ b/services/src/init_import.c @@ -17,92 +17,26 @@ #include #include #include "cJSON.h" +#include "init_cmds.h" #include "init_log.h" -#ifndef OHOS_LITE -#include "init_param.h" -#endif #include "init_read_cfg.h" #include "securec.h" #define IMPORT_ARR_NAME_IN_JSON "import" -// Only OHOS l2 support parameter. #ifndef OHOS_LITE -// Limit max length of parameter value to 96 -#define IMPORT_PARAM_VALUE_LEN 96 -// Limit max length of parameter name to 96 -#define IMPORT_PARAM_NAME_LEN 96 - -static int ExtractCfgFile(char **cfgFile, const char *content) +static int ExtractCfgFile(char **cfgFile, char *content) { - char *p = NULL; - size_t contentLen = strlen(content); - if (cfgFile == NULL || content == NULL) { + if ((!cfgFile) || (!content)) { return -1; } - // without "$", which means filename without parameter. - if ((p = strchr(content, '$')) == NULL) { - *cfgFile = malloc(contentLen + 1); - if (*cfgFile == NULL) { - INIT_LOGW("Failed to allocate memory to import cfg file. err = %d\n", errno); - return -1; - } - if (strncpy_s(*cfgFile, contentLen + 1, content, contentLen) != EOK) { - INIT_LOGW("Failed to copy cfg file name.\n"); - return -1; - } - return 0; - } - size_t cfgFileLen = strlen(content) + IMPORT_PARAM_VALUE_LEN + 1; + size_t cfgFileLen = strlen(content) + MAX_PARAM_VALUE_LEN + 1; if ((*cfgFile = malloc(cfgFileLen)) == NULL) { INIT_LOGW("Failed to allocate memory to import cfg file. err = %d\n", errno); return -1; } - - // Copy head of import item. - if (strncpy_s(*cfgFile, cfgFileLen, content, p - content) != EOK) { - INIT_LOGE("Failed to copy head of cfg file name\n"); - return -1; - } - // Skip '$' - p++; - if (*p == '{') { - p++; - char *right = strchr(p, '}'); - if (right == NULL) { - INIT_LOGE("Invalid cfg file name, miss '}'.\n"); - return -1; - } - if (right - p > IMPORT_PARAM_NAME_LEN) { - INIT_LOGE("Parameter name longer than %d\n", IMPORT_PARAM_NAME_LEN); - return -1; - } - char paramName[IMPORT_PARAM_NAME_LEN] = {}; - char paramValue[IMPORT_PARAM_VALUE_LEN] = {}; - unsigned int valueLen = IMPORT_PARAM_VALUE_LEN; - if (strncpy_s(paramName, IMPORT_PARAM_NAME_LEN - 1, p, right - p) != EOK) { - INIT_LOGE("Failed to copy parameter name\n"); - return -1; - } - if (SystemReadParam(paramName, paramValue, &valueLen) < 0) { - INIT_LOGE("Failed to read parameter \" %s \"\n", paramName); - return -1; - } - if (strncat_s(*cfgFile, cfgFileLen, paramValue, IMPORT_PARAM_VALUE_LEN) != EOK) { - INIT_LOGE("Failed to concatenate parameter\n"); - return -1; - } - // OK, parameter was handled, now concatenate rest of import content. - // Skip '}' - right++; - if (strncat_s(*cfgFile, cfgFileLen, right, contentLen - (right - content)) != EOK) { - INIT_LOGE("Failed to concatenate rest of import content\n"); - return -1; - } - return 0; - } - INIT_LOGE("Cannot extract import config file from \" %s \"\n", content); - return -1; + int ret = GetParamValue(content, *cfgFile, cfgFileLen); + return ret; } #endif diff --git a/services/src/init_utils.c b/services/src/init_utils.c index b378e9455..9dfcc0b26 100644 --- a/services/src/init_utils.c +++ b/services/src/init_utils.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include -#include "init_cmds.h" #include "init_log.h" #include "init_utils.h" #include "securec.h" @@ -41,72 +41,32 @@ #else #define LOG_FILE_NAME "/data/startup_log.txt" #endif -#define MAX_BUFFER 256 -#define MAX_EACH_CMD_LENGTH 30 + #define MAX_JSON_FILE_LEN 102400 // max init.cfg size 100KB #define CONVERT_MICROSEC_TO_SEC(x) ((x) / 1000 / 1000.0) -struct CmdArgs* GetCmd(const char *cmdContent, const char *delim) +int DecodeUid(const char *name) { - struct CmdArgs *ctx = (struct CmdArgs *)malloc(sizeof(struct CmdArgs)); - INIT_CHECK_ONLY_RETURN(ctx != NULL, return NULL); - - ctx->argv = (char**)malloc(sizeof(char*) * MAX_CMD_NAME_LEN); - INIT_CHECK_ONLY_RETURN(ctx->argv != NULL, FreeCmd(&ctx); return NULL); - - char tmpCmd[MAX_BUFFER]; - INIT_CHECK_ONLY_RETURN(strncpy_s(tmpCmd, strlen(cmdContent) + 1, cmdContent, strlen(cmdContent)) == EOK, - FreeCmd(&ctx); - return NULL); - tmpCmd[strlen(cmdContent)] = '\0'; - - char *buffer = NULL; - char *token = strtok_r(tmpCmd, delim, &buffer); - ctx->argc = 0; - while (token != NULL) { - ctx->argv[ctx->argc] = calloc(sizeof(char *), MAX_EACH_CMD_LENGTH); - INIT_CHECK_ONLY_RETURN(ctx->argv[ctx->argc] != NULL, FreeCmd(&ctx); return NULL); - - INIT_CHECK_ONLY_RETURN(strncpy_s(ctx->argv[ctx->argc], strlen(cmdContent) + 1, token, strlen(token)) == EOK, - FreeCmd(&ctx); - return NULL); - if (ctx->argc > MAX_CMD_NAME_LEN - 1) { - INIT_LOGE("GetCmd failed, max cmd number is 10.\n"); - FreeCmd(&ctx); - return NULL; + bool digitFlag = true; + for (unsigned int i = 0; i < strlen(name); ++i) { + if (isalpha(name[i])) { + digitFlag = false; + break; } - token = strtok_r(NULL, delim, &buffer); - ctx->argc += 1; } - ctx->argv[ctx->argc] = NULL; - return ctx; -} - -void FreeCmd(struct CmdArgs **cmd) -{ - struct CmdArgs *tmpCmd = *cmd; - INIT_CHECK_ONLY_RETURN(tmpCmd != NULL, return); - for (int i = 0; i < tmpCmd->argc; ++i) { - INIT_CHECK_ONLY_RETURN(tmpCmd->argv[i] == NULL, free(tmpCmd->argv[i])); - } - INIT_CHECK_ONLY_RETURN(tmpCmd->argv == NULL, free(tmpCmd->argv)); - free(tmpCmd); - return; -} - -int DecodeUid(const char *name) -{ - if (isalpha(name[0])) { + if (digitFlag) { + errno = 0; + uid_t result = strtoul(name, 0, 10); + if (errno != 0) { + return -1; + } + return result; + } else { struct passwd *pwd = getpwnam(name); if (!pwd) { return -1; } return pwd->pw_uid; - } else if (isdigit(name[0])) { - uid_t result = strtoul(name, 0, 10); - return result; - } else { - return -1; } } -- Gitee