未验证 提交 836ccc39 编写于 作者: O openharmony_ci 提交者: Gitee

!1988 需求:init支持selinux策略分离

Merge pull request !1988 from cheng_jinsong/vendor-init
...@@ -28,6 +28,7 @@ extern "C" { ...@@ -28,6 +28,7 @@ extern "C" {
typedef struct { typedef struct {
ListNode cmdExecutor; ListNode cmdExecutor;
int cmdId; int cmdId;
unsigned char careContext;
char *name; char *name;
} PluginCmd; } PluginCmd;
...@@ -39,10 +40,8 @@ typedef struct { ...@@ -39,10 +40,8 @@ typedef struct {
} PluginCmdExecutor; } PluginCmdExecutor;
void PluginExecCmdByName(const char *name, const char *cmdContent); void PluginExecCmdByName(const char *name, const char *cmdContent);
void PluginExecCmdByCmdIndex(int index, const char *cmdContent); // only exec in current context
int PluginExecCmd(const char *name, int argc, const char **argv); int PluginExecCmd(const char *name, int argc, const char **argv);
const char *PluginGetCmdIndex(const char *cmdStr, int *index);
const char *GetPluginCmdNameByIndex(int index);
int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd); int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd);
......
...@@ -21,5 +21,8 @@ ...@@ -21,5 +21,8 @@
{ "name": "AddRebootCmdExecutor" }, { "name": "AddRebootCmdExecutor" },
{ "name": "GetBootEventList" }, { "name": "GetBootEventList" },
{ "name": "WaitForFile" }, { "name": "WaitForFile" },
{ "name": "DoCmdByName" } { "name": "DoCmdByIndex" },
{ "name": "GetMatchCmd" },
{ "name": "AddCareContextCmdExecutor" },
{ "name": "InitSubInitContext" }
] ]
...@@ -121,7 +121,7 @@ void PostTrigger(EventType type, const char *content, uint32_t contentLen); ...@@ -121,7 +121,7 @@ void PostTrigger(EventType type, const char *content, uint32_t contentLen);
* 解析trigger文件。 * 解析trigger文件。
* *
*/ */
int ParseTriggerConfig(const cJSON *fileRoot, int (*checkJobValid)(const char *jobName)); int ParseTriggerConfig(const cJSON *fileRoot, int (*checkJobValid)(const char *jobName), void *context);
/** /**
* 对外接口 * 对外接口
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <time.h> #include <time.h>
#include "cJSON.h" #include "cJSON.h"
#include "init_cmdexecutor.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
extern "C" { extern "C" {
...@@ -68,6 +69,7 @@ struct CmdTable { ...@@ -68,6 +69,7 @@ struct CmdTable {
char name[MAX_CMD_NAME_LEN]; char name[MAX_CMD_NAME_LEN];
unsigned char minArg; unsigned char minArg;
unsigned char maxArg; unsigned char maxArg;
unsigned char careContext;
void (*DoFuncion)(const struct CmdArgs *ctx); void (*DoFuncion)(const struct CmdArgs *ctx);
}; };
...@@ -76,11 +78,20 @@ typedef struct INIT_TIMING_STAT { ...@@ -76,11 +78,20 @@ typedef struct INIT_TIMING_STAT {
struct timespec endTime; struct timespec endTime;
} INIT_TIMING_STAT; } INIT_TIMING_STAT;
typedef enum _initContextType {
INIT_CONTEXT_CHIPSET,
INIT_CONTEXT_MAIN,
} InitContextType;
typedef struct {
InitContextType type;
} ConfigContext;
int GetParamValue(const char *symValue, unsigned int symLen, char *paramValue, unsigned int paramLen); int GetParamValue(const char *symValue, unsigned int symLen, char *paramValue, unsigned int paramLen);
const struct CmdArgs *GetCmdArg(const char *cmdContent, const char *delim, int argsCount); const struct CmdArgs *GetCmdArg(const char *cmdContent, const char *delim, int argsCount);
void FreeCmdArg(struct CmdArgs *cmd); void FreeCmdArg(struct CmdArgs *cmd);
void DoCmdByName(const char *name, const char *cmdContent); // exec in context, if context == null, exec in current context
void DoCmdByIndex(int index, const char *cmdContent); void DoCmdByIndex(int index, const char *cmdContent, const ConfigContext *context);
const char *GetMatchCmd(const char *cmdStr, int *index); const char *GetMatchCmd(const char *cmdStr, int *index);
const char *GetCmdKey(int index); const char *GetCmdKey(int index);
const struct CmdTable *GetCmdTable(int *number); const struct CmdTable *GetCmdTable(int *number);
...@@ -93,6 +104,18 @@ int SetFileCryptPolicy(const char *dir); ...@@ -93,6 +104,18 @@ int SetFileCryptPolicy(const char *dir);
void OpenHidebug(const char *name); void OpenHidebug(const char *name);
long long InitDiffTime(INIT_TIMING_STAT *stat); long long InitDiffTime(INIT_TIMING_STAT *stat);
void StopSubInit(pid_t pid);
int ExecuteCmdInSubInit(const ConfigContext *context, const char *name, const char *cmdContent);
int SetSubInitContext(const ConfigContext *context, const char *service);
int CheckExecuteInSubInit(const ConfigContext *context);
// exec in context, if context == null, exec in current context
void PluginExecCmdByCmdIndex(int index, const char *cmdContent, const ConfigContext *context);
const char *PluginGetCmdIndex(const char *cmdStr, int *index);
const char *GetPluginCmdNameByIndex(int index);
int AddCareContextCmdExecutor(const char *cmdName, CmdExecutor executor);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -31,7 +31,7 @@ typedef struct { ...@@ -31,7 +31,7 @@ typedef struct {
CmdLines *cmdLines; CmdLines *cmdLines;
} Job; } Job;
void ParseAllJobs(const cJSON *fileRoot); void ParseAllJobs(const cJSON *fileRoot, const ConfigContext *context);
void DoJob(const char *jobName); void DoJob(const char *jobName);
void ReleaseAllJobs(void); void ReleaseAllJobs(void);
void DumpAllJobs(void); void DumpAllJobs(void);
......
...@@ -160,6 +160,7 @@ typedef struct Service_ { ...@@ -160,6 +160,7 @@ typedef struct Service_ {
ServiceJobs serviceJobs; ServiceJobs serviceJobs;
cpu_set_t *cpuSet; cpu_set_t *cpuSet;
struct ListNode extDataNode; struct ListNode extDataNode;
ConfigContext context;
} Service; } Service;
#pragma pack() #pragma pack()
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "init_service.h" #include "init_service.h"
#include "cJSON.h" #include "cJSON.h"
#include "init_cmds.h"
#include "list.h" #include "list.h"
#ifdef __cplusplus #ifdef __cplusplus
...@@ -57,7 +58,7 @@ void StartServiceByName(const char *serviceName); ...@@ -57,7 +58,7 @@ void StartServiceByName(const char *serviceName);
void StopServiceByName(const char *serviceName); void StopServiceByName(const char *serviceName);
void StopAllServices(int flags, const char **exclude, int size, void StopAllServices(int flags, const char **exclude, int size,
int (*filter)(const Service *service, const char **exclude, int size)); int (*filter)(const Service *service, const char **exclude, int size));
void ParseAllServices(const cJSON *fileRoot); void ParseAllServices(const cJSON *fileRoot, const ConfigContext *context);
void ReleaseService(Service *service); void ReleaseService(Service *service);
void LoadAccessTokenId(void); void LoadAccessTokenId(void);
Service *AddService(const char *name); Service *AddService(const char *name);
......
...@@ -308,9 +308,9 @@ static int SetOwner(const char *file, const char *ownerStr, const char *groupStr ...@@ -308,9 +308,9 @@ static int SetOwner(const char *file, const char *ownerStr, const char *groupStr
INIT_ERROR_CHECK(groupStr != NULL, return -1, "SetOwner invalid file."); INIT_ERROR_CHECK(groupStr != NULL, return -1, "SetOwner invalid file.");
uid_t owner = DecodeUid(ownerStr); uid_t owner = DecodeUid(ownerStr);
INIT_ERROR_CHECK(owner != (uid_t)-1, return -1, "SetOwner invalid uid :%s.", ownerStr); INIT_ERROR_CHECK(owner != (uid_t)-1, return -1, "SetOwner invalid uid : %s.", ownerStr);
gid_t group = DecodeGid(groupStr); gid_t group = DecodeGid(groupStr);
INIT_ERROR_CHECK(group != (gid_t)-1, return -1, "SetOwner invalid gid :%s.", groupStr); INIT_ERROR_CHECK(group != (gid_t)-1, return -1, "SetOwner invalid gid : %s.", groupStr);
return (chown(file, owner, group) != 0) ? -1 : 0; return (chown(file, owner, group) != 0) ? -1 : 0;
} }
...@@ -565,24 +565,24 @@ static void DoExport(const struct CmdArgs *ctx) ...@@ -565,24 +565,24 @@ static void DoExport(const struct CmdArgs *ctx)
} }
static const struct CmdTable g_cmdTable[] = { static const struct CmdTable g_cmdTable[] = {
{ "start ", 0, 1, DoStart }, { "start ", 0, 1, 0, DoStart },
{ "mkdir ", 1, 4, DoMkDir }, { "mkdir ", 1, 4, 1, DoMkDir },
{ "chmod ", 2, 2, DoChmod }, { "chmod ", 2, 2, 1, DoChmod },
{ "chown ", 3, 3, DoChown }, { "chown ", 3, 3, 1, DoChown },
{ "mount ", 1, 10, DoMount }, { "mount ", 1, 10, 0, DoMount },
{ "export ", 2, 2, DoExport }, { "export ", 2, 2, 0, DoExport },
{ "rm ", 1, 1, DoRm }, { "rm ", 1, 1, 1, DoRm },
{ "rmdir ", 1, 1, DoRmdir }, { "rmdir ", 1, 1, 1, DoRmdir },
{ "write ", 2, 10, DoWrite }, { "write ", 2, 10, 1, DoWrite },
{ "stop ", 1, 1, DoStop }, { "stop ", 1, 1, 0, DoStop },
{ "reset ", 1, 1, DoReset }, { "reset ", 1, 1, 0, DoReset },
{ "copy ", 2, 2, DoCopy }, { "copy ", 2, 2, 1, DoCopy },
{ "reboot ", 0, 1, DoRebootCmd }, { "reboot ", 0, 1, 0, DoRebootCmd },
{ "setrlimit ", 3, 3, DoSetrlimit }, { "setrlimit ", 3, 3, 0, DoSetrlimit },
{ "sleep ", 1, 1, DoSleep }, { "sleep ", 1, 1, 0, DoSleep },
{ "wait ", 1, 2, DoWait }, { "wait ", 1, 2, 1, DoWait },
{ "hostname ", 1, 1, DoSetHostname }, { "hostname ", 1, 1, 1, DoSetHostname },
{ "domainname ", 1, 1, DoSetDomainname } { "domainname ", 1, 1, 1, DoSetDomainname }
}; };
static const struct CmdTable *GetCommCmdTable(int *number) static const struct CmdTable *GetCommCmdTable(int *number)
...@@ -654,19 +654,30 @@ const char *GetMatchCmd(const char *cmdStr, int *index) ...@@ -654,19 +654,30 @@ const char *GetMatchCmd(const char *cmdStr, int *index)
return PluginGetCmdIndex(startCmd, index); return PluginGetCmdIndex(startCmd, index);
} }
const char *GetCmdKey(int index) static const struct CmdTable *GetCmdTableByIndex(int index)
{ {
int cmdCnt = 0; int cmdCnt = 0;
const struct CmdTable *commCmds = GetCommCmdTable(&cmdCnt); const struct CmdTable *commCmds = GetCommCmdTable(&cmdCnt);
const struct CmdTable *cmdTable = NULL;
if (index < cmdCnt) { if (index < cmdCnt) {
return commCmds[index].name; cmdTable = &commCmds[index];
} else {
int number = 0;
const struct CmdTable *cmds = GetCmdTable(&number);
if (index < (cmdCnt + number)) {
cmdTable = &cmds[index - cmdCnt];
}
} }
int number = 0; return cmdTable;
const struct CmdTable *cmds = GetCmdTable(&number); }
if (index < (cmdCnt + number)) {
return cmds[index - cmdCnt].name; const char *GetCmdKey(int index)
{
const struct CmdTable *cmdTable = GetCmdTableByIndex(index);
if (cmdTable != NULL) {
return cmdTable->name;
} }
return NULL; return GetPluginCmdNameByIndex(index);
} }
int GetCmdLinesFromJson(const cJSON *root, CmdLines **cmdLines) int GetCmdLinesFromJson(const cJSON *root, CmdLines **cmdLines)
...@@ -724,58 +735,31 @@ long long InitDiffTime(INIT_TIMING_STAT *stat) ...@@ -724,58 +735,31 @@ long long InitDiffTime(INIT_TIMING_STAT *stat)
return diff; return diff;
} }
void DoCmdByName(const char *name, const char *cmdContent) void DoCmdByIndex(int index, const char *cmdContent, const ConfigContext *context)
{
if (name == NULL || cmdContent == NULL) {
return;
}
INIT_TIMING_STAT cmdTimer;
(void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.startTime);
const struct CmdTable *cmd = GetCmdByName(name);
if (cmd != NULL) {
ExecCmd(cmd, cmdContent);
} else {
PluginExecCmdByName(name, cmdContent);
}
(void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime);
long long diff = InitDiffTime(&cmdTimer);
#ifndef OHOS_LITE
InitCmdHookExecute(name, cmdContent, &cmdTimer);
#endif
if (diff > 200000) { // 200000 > 200ms
INIT_LOGI("Execute command \"%s %s\" took %lld ms", name, cmdContent, diff / BASE_MS_UNIT);
} else {
INIT_LOGV("Execute command \"%s %s\" took %lld ms", name, cmdContent, diff / BASE_MS_UNIT);
}
}
void DoCmdByIndex(int index, const char *cmdContent)
{ {
if (cmdContent == NULL) { if (cmdContent == NULL) {
return; return;
} }
int cmdCnt = 0;
INIT_TIMING_STAT cmdTimer; INIT_TIMING_STAT cmdTimer;
(void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.startTime); (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.startTime);
const struct CmdTable *commCmds = GetCommCmdTable(&cmdCnt);
const char *cmdName = NULL; const char *cmdName = NULL;
if (index < cmdCnt) { const struct CmdTable *cmdTable = GetCmdTableByIndex(index);
cmdName = commCmds[index].name; if (cmdTable != NULL) {
ExecCmd(&commCmds[index], cmdContent); cmdName = cmdTable->name;
} else { if (!cmdTable->careContext || !CheckExecuteInSubInit(context)) {
int number = 0; ExecCmd(cmdTable, cmdContent);
const struct CmdTable *cmds = GetCmdTable(&number);
if (index < (cmdCnt + number)) {
cmdName = cmds[index - cmdCnt].name;
ExecCmd(&cmds[index - cmdCnt], cmdContent);
} else { } else {
PluginExecCmdByCmdIndex(index, cmdContent); ExecuteCmdInSubInit(context, cmdTable->name, cmdContent);
cmdName = GetPluginCmdNameByIndex(index); }
if (cmdName == NULL) { } else {
cmdName = "Unknown"; PluginExecCmdByCmdIndex(index, cmdContent, context);
} cmdName = GetPluginCmdNameByIndex(index);
if (cmdName == NULL) {
cmdName = "Unknown";
} }
} }
(void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime); (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime);
long long diff = InitDiffTime(&cmdTimer); long long diff = InitDiffTime(&cmdTimer);
#ifndef OHOS_LITE #ifndef OHOS_LITE
......
...@@ -508,6 +508,11 @@ int ServiceStart(Service *service) ...@@ -508,6 +508,11 @@ int ServiceStart(Service *service)
#endif #endif
int pid = fork(); int pid = fork();
if (pid == 0) { if (pid == 0) {
// set selinux label by context
if (service->context.type != INIT_CONTEXT_MAIN) {
SetSubInitContext(&service->context, service->name);
}
if (service->attribute & SERVICE_ATTR_MODULE_UPDATE) { if (service->attribute & SERVICE_ATTR_MODULE_UPDATE) {
CheckModuleUpdate(service->pathArgs.count, service->pathArgs.argv); CheckModuleUpdate(service->pathArgs.count, service->pathArgs.argv);
} }
...@@ -602,7 +607,7 @@ static int ExecRestartCmd(Service *service) ...@@ -602,7 +607,7 @@ static int ExecRestartCmd(Service *service)
} }
for (int i = 0; i < service->restartArg->cmdNum; i++) { for (int i = 0; i < service->restartArg->cmdNum; i++) {
INIT_LOGI("ExecRestartCmd cmdLine->cmdContent %s ", service->restartArg->cmds[i].cmdContent); INIT_LOGI("ExecRestartCmd cmdLine->cmdContent %s ", service->restartArg->cmds[i].cmdContent);
DoCmdByIndex(service->restartArg->cmds[i].cmdIndex, service->restartArg->cmds[i].cmdContent); DoCmdByIndex(service->restartArg->cmds[i].cmdIndex, service->restartArg->cmds[i].cmdContent, NULL);
} }
free(service->restartArg); free(service->restartArg);
service->restartArg = NULL; service->restartArg = NULL;
...@@ -752,6 +757,7 @@ int UpdaterServiceFds(Service *service, int *fds, size_t fdCount) ...@@ -752,6 +757,7 @@ int UpdaterServiceFds(Service *service, int *fds, size_t fdCount)
// case 1 // case 1
CloseServiceFds(service, true); CloseServiceFds(service, true);
} }
INIT_ERROR_CHECK(fdCount <= MAX_HOLD_FDS, return -1, "Invalid fdCount %d", fdCount);
service->fds = calloc(fdCount + 1, sizeof(int)); service->fds = calloc(fdCount + 1, sizeof(int));
if (service->fds == NULL) { if (service->fds == NULL) {
INIT_LOGE("Service \' %s \' failed to allocate memory for fds", service->name); INIT_LOGE("Service \' %s \' failed to allocate memory for fds", service->name);
......
...@@ -21,12 +21,29 @@ ...@@ -21,12 +21,29 @@
static void ParseAllImports(const cJSON *root); static void ParseAllImports(const cJSON *root);
InitContextType GetConfigContextType(const char *cfgName)
{
static const char *vendorDir[] = {
"/vendor/etc/init/", "/chipset/etc/init/", "/chip_prod/etc/init/"
};
for (size_t j = 0; j < ARRAY_LENGTH(vendorDir); j++) {
if (strncmp(vendorDir[j], cfgName, strlen(vendorDir[j])) == 0) {
return INIT_CONTEXT_CHIPSET;
}
}
return INIT_CONTEXT_MAIN;
}
static void ParseInitCfgContents(const char *cfgName, const cJSON *root) static void ParseInitCfgContents(const char *cfgName, const cJSON *root)
{ {
INIT_ERROR_CHECK(root != NULL, return, "Root is null"); INIT_ERROR_CHECK(root != NULL, return, "Root is null");
ParseAllServices(root); ConfigContext context = { INIT_CONTEXT_MAIN };
context.type = GetConfigContextType(cfgName);
INIT_LOGV("Parse %s configs in context %d", cfgName, context.type);
ParseAllServices(root, &context);
// parse jobs // parse jobs
ParseAllJobs(root); ParseAllJobs(root, &context);
// parse imports // parse imports
ParseAllImports(root); ParseAllImports(root);
} }
......
...@@ -100,6 +100,8 @@ Service *AddService(const char *name) ...@@ -100,6 +100,8 @@ Service *AddService(const char *name)
service->name = node->name; service->name = node->name;
service->status = SERVICE_IDLE; service->status = SERVICE_IDLE;
service->cpuSet = NULL; service->cpuSet = NULL;
service->pid = -1;
service->context.type = INIT_CONTEXT_MAIN;
OH_ListInit(&service->extDataNode); OH_ListInit(&service->extDataNode);
g_serviceSpace.serviceCount++; g_serviceSpace.serviceCount++;
INIT_LOGV("AddService %s", node->name); INIT_LOGV("AddService %s", node->name);
...@@ -427,32 +429,32 @@ static int AddServiceSocket(cJSON *json, Service *service) ...@@ -427,32 +429,32 @@ static int AddServiceSocket(cJSON *json, Service *service)
sockopt->watcher = NULL; sockopt->watcher = NULL;
ret = ParseSocketFamily(json, sockopt); ret = ParseSocketFamily(json, sockopt);
INIT_ERROR_CHECK(ret == 0, free(sockopt); sockopt = NULL; return SERVICE_FAILURE, INIT_ERROR_CHECK(ret == 0, free(sockopt);
"Failed to parse socket family"); return SERVICE_FAILURE, "Failed to parse socket family");
ret = ParseSocketType(json, sockopt); ret = ParseSocketType(json, sockopt);
INIT_ERROR_CHECK(ret == 0, free(sockopt); sockopt = NULL; return SERVICE_FAILURE, INIT_ERROR_CHECK(ret == 0, free(sockopt);
"Failed to parse socket type"); return SERVICE_FAILURE, "Failed to parse socket type");
ret = ParseSocketProtocol(json, sockopt); ret = ParseSocketProtocol(json, sockopt);
INIT_ERROR_CHECK(ret == 0, free(sockopt); sockopt = NULL; return SERVICE_FAILURE, INIT_ERROR_CHECK(ret == 0, free(sockopt);
"Failed to parse socket protocol"); return SERVICE_FAILURE, "Failed to parse socket protocol");
char *stringValue = GetStringValue(json, "permissions", &strLen); char *stringValue = GetStringValue(json, "permissions", &strLen);
INIT_ERROR_CHECK((stringValue != NULL) && (strLen > 0), free(sockopt); sockopt = NULL; return SERVICE_FAILURE, INIT_ERROR_CHECK((stringValue != NULL) && (strLen > 0), free(sockopt);
"Failed to get string for permissions"); return SERVICE_FAILURE, "Failed to get string for permissions");
sockopt->perm = strtoul(stringValue, 0, OCTAL_BASE); sockopt->perm = strtoul(stringValue, 0, OCTAL_BASE);
stringValue = GetStringValue(json, "uid", &strLen); stringValue = GetStringValue(json, "uid", &strLen);
INIT_ERROR_CHECK((stringValue != NULL) && (strLen > 0), free(sockopt); sockopt = NULL; return SERVICE_FAILURE, INIT_ERROR_CHECK((stringValue != NULL) && (strLen > 0), free(sockopt);
"Failed to get string for uid"); return SERVICE_FAILURE, "Failed to get string for uid");
sockopt->uid = DecodeUid(stringValue); sockopt->uid = DecodeUid(stringValue);
stringValue = GetStringValue(json, "gid", &strLen); stringValue = GetStringValue(json, "gid", &strLen);
INIT_ERROR_CHECK((stringValue != NULL) && (strLen > 0), free(sockopt); sockopt = NULL; return SERVICE_FAILURE, INIT_ERROR_CHECK((stringValue != NULL) && (strLen > 0), free(sockopt);
"Failed to get string for gid"); return SERVICE_FAILURE, "Failed to get string for gid");
sockopt->gid = DecodeGid(stringValue); sockopt->gid = DecodeGid(stringValue);
INIT_ERROR_CHECK((sockopt->uid != (uid_t)-1) && (sockopt->gid != (uid_t)-1), INIT_ERROR_CHECK((sockopt->uid != (uid_t)-1) && (sockopt->gid != (uid_t)-1), free(sockopt);
free(sockopt); sockopt = NULL; return SERVICE_FAILURE, "Invalid uid or gid"); return SERVICE_FAILURE, "Invalid uid or gid");
ret = ParseSocketOption(json, sockopt); ret = ParseSocketOption(json, sockopt);
INIT_ERROR_CHECK(ret == 0, free(sockopt); sockopt = NULL; return SERVICE_FAILURE, INIT_ERROR_CHECK(ret == 0, free(sockopt);
"Failed to parse socket option"); return SERVICE_FAILURE, "Failed to parse socket option");
sockopt->next = NULL; sockopt->next = NULL;
if (service->socketCfg == NULL) { if (service->socketCfg == NULL) {
...@@ -988,16 +990,12 @@ int WatchConsoleDevice(Service *service) ...@@ -988,16 +990,12 @@ int WatchConsoleDevice(Service *service)
return 0; return 0;
} }
void ParseAllServices(const cJSON *fileRoot) void ParseAllServices(const cJSON *fileRoot, const ConfigContext *context)
{ {
int servArrSize = 0; int servArrSize = 0;
cJSON *serviceArr = GetArrayItem(fileRoot, &servArrSize, SERVICES_ARR_NAME_IN_JSON); cJSON *serviceArr = GetArrayItem(fileRoot, &servArrSize, SERVICES_ARR_NAME_IN_JSON);
INIT_CHECK(serviceArr != NULL, return); INIT_CHECK(serviceArr != NULL, return);
INIT_ERROR_CHECK(servArrSize <= MAX_SERVICES_CNT_IN_FILE, return,
"Too many services[cnt %d] detected, should not exceed %d.",
servArrSize, MAX_SERVICES_CNT_IN_FILE);
size_t strLen = 0; size_t strLen = 0;
for (int i = 0; i < servArrSize; ++i) { for (int i = 0; i < servArrSize; ++i) {
cJSON *curItem = cJSON_GetArrayItem(serviceArr, i); cJSON *curItem = cJSON_GetArrayItem(serviceArr, i);
...@@ -1020,11 +1018,12 @@ void ParseAllServices(const cJSON *fileRoot) ...@@ -1020,11 +1018,12 @@ void ParseAllServices(const cJSON *fileRoot)
#endif #endif
} }
service->pid = -1; if (context != NULL) {
service->context.type = context->type;
}
int ret = ParseOneService(curItem, service); int ret = ParseOneService(curItem, service);
if (ret != SERVICE_SUCCESS) { if (ret != SERVICE_SUCCESS) {
ReleaseService(service); ReleaseService(service);
service = NULL;
continue; continue;
} }
ret = ParseServiceSocket(curItem, service); ret = ParseServiceSocket(curItem, service);
......
...@@ -108,8 +108,8 @@ static void DoLoadCfg(const struct CmdArgs *ctx) ...@@ -108,8 +108,8 @@ static void DoLoadCfg(const struct CmdArgs *ctx)
} }
static const struct CmdTable g_cmdTable[] = { static const struct CmdTable g_cmdTable[] = {
{ "exec ", 1, 10, DoExec }, { "exec ", 1, 10, 0, DoExec },
{ "loadcfg ", 1, 1, DoLoadCfg }, { "loadcfg ", 1, 1, 0, DoLoadCfg },
}; };
const struct CmdTable *GetCmdTable(int *number) const struct CmdTable *GetCmdTable(int *number)
...@@ -122,7 +122,7 @@ void PluginExecCmdByName(const char *name, const char *cmdContent) ...@@ -122,7 +122,7 @@ void PluginExecCmdByName(const char *name, const char *cmdContent)
{ {
} }
void PluginExecCmdByCmdIndex(int index, const char *cmdContent) void PluginExecCmdByCmdIndex(int index, const char *cmdContent, const ConfigContext *context)
{ {
} }
...@@ -140,3 +140,18 @@ int SetFileCryptPolicy(const char *dir) ...@@ -140,3 +140,18 @@ int SetFileCryptPolicy(const char *dir)
{ {
return 0; return 0;
} }
int SetSubInitContext(const ConfigContext *context, const char *service)
{
return 0;
}
int ExecuteCmdInSubInit(const ConfigContext *context, const char *name, const char *cmdContent)
{
return 0;
}
int CheckExecuteInSubInit(const ConfigContext *context)
{
return 0;
}
...@@ -81,7 +81,7 @@ static void ParseJob(const cJSON *jobItem, Job *resJob) ...@@ -81,7 +81,7 @@ static void ParseJob(const cJSON *jobItem, Job *resJob)
return; return;
} }
void ParseAllJobs(const cJSON *fileRoot) void ParseAllJobs(const cJSON *fileRoot, const ConfigContext *context)
{ {
if (fileRoot == NULL) { if (fileRoot == NULL) {
INIT_LOGE("ParseAllJobs, input fileRoot is NULL!"); INIT_LOGE("ParseAllJobs, input fileRoot is NULL!");
...@@ -138,7 +138,7 @@ void DoJob(const char *jobName) ...@@ -138,7 +138,7 @@ void DoJob(const char *jobName)
continue; continue;
} }
for (int j = 0; j < cmdLines->cmdNum; ++j) { for (int j = 0; j < cmdLines->cmdNum; ++j) {
DoCmdByIndex(cmdLines->cmds[j].cmdIndex, cmdLines->cmds[j].cmdContent); DoCmdByIndex(cmdLines->cmds[j].cmdIndex, cmdLines->cmds[j].cmdContent, NULL);
} }
} }
} }
......
...@@ -57,6 +57,7 @@ ohos_executable("init") { ...@@ -57,6 +57,7 @@ ohos_executable("init") {
include_dirs = [ include_dirs = [
"//base/startup/init/services/init/include", "//base/startup/init/services/init/include",
"//base/startup/init/services/modules/reboot", "//base/startup/init/services/modules/reboot",
"//base/startup/init/services/modules/init_context",
"${FSCRYPT_PATH}/include/libfscrypt", "${FSCRYPT_PATH}/include/libfscrypt",
] ]
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#define MAX_CMD_ARGC 10 #define MAX_CMD_ARGC 10
static int g_cmdExecutorId = 0; static int g_cmdExecutorId = 0;
static int g_cmdId = 0; static int g_cmdId = 0;
int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd) int AddCmdExecutor_(const char *cmdName, CmdExecutor execCmd, int careContext)
{ {
INIT_ERROR_CHECK(cmdName != NULL, return -1, "Invalid input param"); INIT_ERROR_CHECK(cmdName != NULL, return -1, "Invalid input param");
INIT_LOGV("Add command '%s' executor.", cmdName); INIT_LOGV("Add command '%s' executor.", cmdName);
...@@ -43,6 +43,7 @@ int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd) ...@@ -43,6 +43,7 @@ int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd)
groupNode->data.cmd = cmd; groupNode->data.cmd = cmd;
cmd->cmdId = g_cmdId++; cmd->cmdId = g_cmdId++;
cmd->name = groupNode->name; cmd->name = groupNode->name;
cmd->careContext = careContext;
OH_ListInit(&cmd->cmdExecutor); OH_ListInit(&cmd->cmdExecutor);
} }
if (execCmd == NULL) { if (execCmd == NULL) {
...@@ -57,6 +58,16 @@ int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd) ...@@ -57,6 +58,16 @@ int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd)
return cmdExec->id; return cmdExec->id;
} }
int AddCareContextCmdExecutor(const char *cmdName, CmdExecutor execCmd)
{
return AddCmdExecutor_(cmdName, execCmd, 1);
}
int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd)
{
return AddCmdExecutor_(cmdName, execCmd, 0);
}
void RemoveCmdExecutor(const char *cmdName, int id) void RemoveCmdExecutor(const char *cmdName, int id)
{ {
INIT_ERROR_CHECK(cmdName != NULL, return, "Invalid input param"); INIT_ERROR_CHECK(cmdName != NULL, return, "Invalid input param");
...@@ -82,7 +93,7 @@ void RemoveCmdExecutor(const char *cmdName, int id) ...@@ -82,7 +93,7 @@ void RemoveCmdExecutor(const char *cmdName, int id)
free(cmd); free(cmd);
} }
void PluginExecCmd_(PluginCmd *cmd, const char *cmdContent) static void PluginExecCmd_(PluginCmd *cmd, const char *cmdContent)
{ {
const struct CmdArgs *ctx = GetCmdArg(cmdContent, " ", MAX_CMD_ARGC); const struct CmdArgs *ctx = GetCmdArg(cmdContent, " ", MAX_CMD_ARGC);
if (ctx == NULL) { if (ctx == NULL) {
...@@ -169,15 +180,19 @@ const char *GetPluginCmdNameByIndex(int index) ...@@ -169,15 +180,19 @@ const char *GetPluginCmdNameByIndex(int index)
return cmd->name; return cmd->name;
} }
void PluginExecCmdByCmdIndex(int index, const char *cmdContent) void PluginExecCmdByCmdIndex(int index, const char *cmdContent, const ConfigContext *context)
{ {
PluginCmd *cmd = GetPluginCmdByIndex(index); PluginCmd *cmd = GetPluginCmdByIndex(index);
if (cmd == NULL) { if (cmd == NULL) {
INIT_LOGW("Cannot find plugin command with index %d", index); INIT_LOGW("Cannot find plugin command with index %d", index);
return; return;
} }
INIT_LOGV("Command: %s cmdContent: %s", cmd->name, cmdContent); INIT_LOGV("Command: %s cmdContent: %s %d", cmd->name, cmdContent, cmd->careContext);
PluginExecCmd_(cmd, cmdContent); if (!cmd->careContext || !CheckExecuteInSubInit(context)) {
PluginExecCmd_(cmd, cmdContent);
} else {
ExecuteCmdInSubInit(context, cmd->name, cmdContent);
}
} }
const char *PluginGetCmdIndex(const char *cmdStr, int *index) const char *PluginGetCmdIndex(const char *cmdStr, int *index)
......
...@@ -510,31 +510,31 @@ static void DoMkSandbox(const struct CmdArgs *ctx) ...@@ -510,31 +510,31 @@ static void DoMkSandbox(const struct CmdArgs *ctx)
} }
static const struct CmdTable g_cmdTable[] = { static const struct CmdTable g_cmdTable[] = {
{ "syncexec ", 1, 10, DoSyncExec }, { "syncexec ", 1, 10, 0, DoSyncExec },
{ "exec ", 1, 10, DoExec }, { "exec ", 1, 10, 0, DoExec },
{ "mknode ", 5, 5, DoMakeNode }, { "mknode ", 5, 5, 0, DoMakeNode },
{ "makedev ", 2, 2, DoMakeDevice }, { "makedev ", 2, 2, 0, DoMakeDevice },
{ "symlink ", 2, 2, DoSymlink }, { "symlink ", 2, 2, 1, DoSymlink },
{ "trigger ", 0, 1, DoTriggerCmd }, { "trigger ", 0, 1, 0, DoTriggerCmd },
{ "insmod ", 1, 10, DoInsmod }, { "insmod ", 1, 10, 1, DoInsmod },
{ "setparam ", 2, 2, DoSetParam }, { "setparam ", 2, 2, 0, DoSetParam },
{ "load_persist_params ", 0, 1, DoLoadPersistParams }, { "load_persist_params ", 0, 1, 0, DoLoadPersistParams },
{ "load_param ", 1, 2, DoLoadDefaultParams }, { "load_param ", 1, 2, 0, DoLoadDefaultParams },
{ "load_access_token_id ", 0, 1, DoLoadAccessTokenId }, { "load_access_token_id ", 0, 1, 0, DoLoadAccessTokenId },
{ "ifup ", 1, 1, DoIfup }, { "ifup ", 1, 1, 1, DoIfup },
{ "mount_fstab ", 1, 1, DoMountFstabFile }, { "mount_fstab ", 1, 1, 0, DoMountFstabFile },
{ "umount_fstab ", 1, 1, DoUmountFstabFile }, { "umount_fstab ", 1, 1, 0, DoUmountFstabFile },
{ "restorecon ", 1, 1, DoRestorecon }, { "restorecon ", 1, 1, 1, DoRestorecon },
{ "stopAllServices ", 0, 10, DoStopAllServices }, { "stopAllServices ", 0, 10, 0, DoStopAllServices },
{ "umount ", 1, 1, DoUmount }, { "umount ", 1, 1, 0, DoUmount },
{ "sync ", 0, 1, DoSync }, { "sync ", 0, 1, 0, DoSync },
{ "timer_start", 1, 1, DoTimerStart }, { "timer_start", 1, 1, 0, DoTimerStart },
{ "timer_stop", 1, 1, DoTimerStop }, { "timer_stop", 1, 1, 0, DoTimerStop },
{ "init_global_key ", 1, 1, DoInitGlobalKey }, { "init_global_key ", 1, 1, 0, DoInitGlobalKey },
{ "init_main_user ", 0, 1, DoInitMainUser }, { "init_main_user ", 0, 1, 0, DoInitMainUser },
{ "mkswap", 1, 1, DoMkswap}, { "mkswap", 1, 1, 0, DoMkswap},
{ "swapon", 1, 1, DoSwapon}, { "swapon", 1, 1, 0, DoSwapon},
{ "mksandbox", 1, 1, DoMkSandbox}, { "mksandbox", 1, 1, 0, DoMkSandbox},
}; };
const struct CmdTable *GetCmdTable(int *number) const struct CmdTable *GetCmdTable(int *number)
......
...@@ -92,6 +92,7 @@ static void DumpOneService(const Service *service) ...@@ -92,6 +92,7 @@ static void DumpOneService(const Service *service)
printf("\tservice name: [%s] \n", service->name); printf("\tservice name: [%s] \n", service->name);
printf("\tservice pid: [%d] \n", service->pid); printf("\tservice pid: [%d] \n", service->pid);
printf("\tservice context : [%s] \n", (service->context.type == INIT_CONTEXT_CHIPSET) ? "chipset" : "system");
printf("\tservice crashCnt: [%d] \n", service->crashCnt); printf("\tservice crashCnt: [%d] \n", service->crashCnt);
printf("\tservice attribute: [%u] \n", service->attribute); printf("\tservice attribute: [%u] \n", service->attribute);
printf("\tservice importance: [%d] \n", service->importance); printf("\tservice importance: [%d] \n", service->importance);
......
...@@ -23,9 +23,9 @@ static int CheckJobValid(const char *jobName) ...@@ -23,9 +23,9 @@ static int CheckJobValid(const char *jobName)
return CheckNodeValid(NODE_TYPE_JOBS, jobName); return CheckNodeValid(NODE_TYPE_JOBS, jobName);
} }
void ParseAllJobs(const cJSON *fileRoot) void ParseAllJobs(const cJSON *fileRoot, const ConfigContext *context)
{ {
ParseTriggerConfig(fileRoot, CheckJobValid); ParseTriggerConfig(fileRoot, CheckJobValid, (void *)context);
} }
int DoJobNow(const char *jobName) int DoJobNow(const char *jobName)
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "init_adapter.h" #include "init_adapter.h"
#include "init_log.h" #include "init_log.h"
#include "init_param.h" #include "init_param.h"
#include "init_context.h"
#include "init_service_manager.h" #include "init_service_manager.h"
#include "loop_event.h" #include "loop_event.h"
...@@ -49,6 +50,7 @@ INIT_STATIC void ProcessSignal(const struct signalfd_siginfo *siginfo) ...@@ -49,6 +50,7 @@ INIT_STATIC void ProcessSignal(const struct signalfd_siginfo *siginfo)
service == NULL ? "Unknown" : service->name, sigPID, procStat); service == NULL ? "Unknown" : service->name, sigPID, procStat);
} }
CmdServiceProcessDelClient(sigPID); CmdServiceProcessDelClient(sigPID);
StopSubInit(sigPID);
INIT_LOGI("SigHandler, SIGCHLD received, Service:%s pid:%d uid:%d status:%d.", INIT_LOGI("SigHandler, SIGCHLD received, Service:%s pid:%d uid:%d status:%d.",
service == NULL ? "Unknown" : service->name, service == NULL ? "Unknown" : service->name,
sigPID, siginfo->ssi_uid, procStat); sigPID, siginfo->ssi_uid, procStat);
......
...@@ -17,6 +17,7 @@ group("static_modules") { ...@@ -17,6 +17,7 @@ group("static_modules") {
deps = [ deps = [
"bootchart:libbootchart_static", "bootchart:libbootchart_static",
"bootevent:libbootevent_static", "bootevent:libbootevent_static",
"init_context:initcontext_static",
"init_eng:libiniteng_static", "init_eng:libiniteng_static",
"init_hook:inithook", "init_hook:inithook",
"reboot:libreboot_static", "reboot:libreboot_static",
...@@ -39,6 +40,7 @@ group("modulesgroup") { ...@@ -39,6 +40,7 @@ group("modulesgroup") {
if (!defined(ohos_lite)) { if (!defined(ohos_lite)) {
deps = [ deps = [
"bootchart:bootchart", "bootchart:bootchart",
"init_context:init_context",
"init_eng:init_eng", "init_eng:init_eng",
"reboot:rebootmodule", "reboot:rebootmodule",
"sysevent:eventmodule", "sysevent:eventmodule",
......
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/startup/init/begetd.gni")
import("//build/ohos.gni")
comm_include = [
".",
"..",
"../../init/include",
"../../include",
"../../include/param",
]
ohos_shared_library("init_context") {
sources = [ "init_context.c" ]
include_dirs = comm_include
include_dirs += [ "../../init/include" ]
external_deps = [ "init:libinit_module_engine" ]
if (build_selinux) {
external_deps += [
"selinux:libload_policy",
"selinux:librestorecon",
]
defines = [ "WITH_SELINUX" ]
}
deps = [
"//third_party/bounds_checking_function:libsec_shared",
"//third_party/selinux:libselinux",
]
part_name = "init"
subsystem_name = "startup"
if (target_cpu == "arm64") {
module_install_dir = "lib64/init"
} else {
module_install_dir = "lib/init"
}
}
config("initcontext_static_config") {
include_dirs = comm_include
}
ohos_source_set("initcontext_static") {
sources = [ "init_context_static.c" ]
include_dirs = comm_include
public_configs = [ ":initcontext_static_config" ]
public_configs += [ "../../../interfaces/innerkits/init_module_engine:init_module_engine_exported_config" ]
deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
part_name = "init"
subsystem_name = "startup"
}
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "init_context.h"
#include <poll.h>
#ifdef WITH_SELINUX
#include <policycoreutils.h>
#include <selinux/selinux.h>
#endif
#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include "init_module_engine.h"
#include "plugin_adapter.h"
#include "init_cmds.h"
#include "init_utils.h"
#include "securec.h"
#ifdef STARTUP_INIT_TEST
#define TIMEOUT_DEF 2
#else
#define TIMEOUT_DEF 5
#endif
static SubInitInfo g_subInitInfo[INIT_CONTEXT_MAIN] = {};
static const char *g_subContext[INIT_CONTEXT_MAIN] = {
"u:r:chipset_init:s0"
};
static void SubInitMain(InitContextType type, int readFd, int writeFd);
static void HandleRecvMessage(SubInitInfo *subInfo, char *buffer, uint32_t size);
static int CreateSocketPair(int socket[2]);
static int SubInitSetSelinuxContext(InitContextType type);
static int SubInitStart(InitContextType type)
{
PLUGIN_CHECK(type < INIT_CONTEXT_MAIN, return -1, "Invalid type %d", type);
SubInitInfo *subInfo = &g_subInitInfo[type];
if (subInfo->state != SUB_INIT_STATE_IDLE) {
return 0;
}
int socket[2] = {0};
int ret = CreateSocketPair(socket);
PLUGIN_CHECK(ret == 0, return -1, "Failed to create socket for %d", type);
subInfo->state = SUB_INIT_STATE_STARTING;
pid_t pid = fork();
if (pid < 0) {
close(socket[0]);
close(socket[1]);
subInfo->state = SUB_INIT_STATE_IDLE;
return -1;
}
if (pid == 0) {
SubInitSetSelinuxContext(type);
close(socket[0]);
SubInitMain(type, socket[1], socket[1]);
close(socket[1]);
_exit(PROCESS_EXIT_CODE);
}
close(socket[1]);
subInfo->sendFd = socket[0];
subInfo->recvFd = socket[0];
subInfo->state = SUB_INIT_STATE_RUNNING;
subInfo->subPid = pid;
return 0;
}
static void SubInitStop(pid_t pid)
{
for (size_t i = 0; i < ARRAY_LENGTH(g_subInitInfo); i++) {
if (g_subInitInfo[i].subPid == pid) {
close(g_subInitInfo[i].sendFd);
close(g_subInitInfo[i].recvFd);
g_subInitInfo[i].subPid = 0;
g_subInitInfo[i].state = SUB_INIT_STATE_IDLE;
}
}
}
static int SubInitExecuteCmd(InitContextType type, const char *name, const char *cmdContent)
{
static char buffer[MAX_CMD_LEN] = {0};
PLUGIN_CHECK(type < INIT_CONTEXT_MAIN, return -1, "Invalid type %d", type);
PLUGIN_CHECK(name != NULL, return -1, "Invalid cmd name");
SubInitInfo *subInfo = &g_subInitInfo[type];
if (subInfo->state != SUB_INIT_STATE_RUNNING) {
PLUGIN_LOGW("Sub init %d is not running ", type);
return -1;
}
int len = 0;
if (cmdContent != NULL) {
len = snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "%s %s", name, cmdContent);
} else {
len = snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "%s ", name);
}
PLUGIN_CHECK(len > 0, return -1, "Failed to format cmd %s", name);
buffer[len] = '\0';
PLUGIN_LOGV("send cmd '%s'", buffer);
int ret = send(subInfo->sendFd, buffer, len, 0);
PLUGIN_CHECK(ret > 0, return errno, "Failed to send cmd %s to %d errno %d", name, subInfo->type, errno);
// block and wait result
ssize_t rLen = TEMP_FAILURE_RETRY(read(subInfo->recvFd, buffer, sizeof(buffer)));
while ((rLen < 0) && (errno == EAGAIN)) {
rLen = TEMP_FAILURE_RETRY(read(subInfo->recvFd, buffer, sizeof(buffer)));
}
PLUGIN_CHECK(rLen >= 0 && rLen < sizeof(buffer), return errno,
"Failed to read result from %d for cmd %s errno %d", subInfo->type, name, errno);
// change to result
buffer[rLen] = '\0';
PLUGIN_LOGV("recv cmd result %s", buffer);
errno = 0;
ret = atoi(buffer);
if (errno != 0) {
return errno;
}
return ret;
}
static int CreateSocketPair(int socket[2])
{
int ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, socket);
PLUGIN_CHECK(ret == 0, return -1, "Create socket fail errno %d", errno);
int opt = 1;
struct timeval timeout = {TIMEOUT_DEF, 0};
do {
ret = setsockopt(socket[0], SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
PLUGIN_CHECK(ret == 0, break, "Failed to set opt for %d errno %d", socket[0], errno);
ret = setsockopt(socket[1], SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
PLUGIN_CHECK(ret == 0, break, "Failed to set opt for %d errno %d", socket[1], errno);
ret = setsockopt(socket[0], SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
PLUGIN_CHECK(ret == 0, break, "Failed to set opt for %d errno %d", socket[0], errno);
} while (0);
if (ret != 0) {
close(socket[0]);
close(socket[1]);
}
return ret;
}
static int CheckSocketPermission(const SubInitInfo *subInfo)
{
struct ucred uc = {-1, -1, -1};
socklen_t len = sizeof(uc);
if (getsockopt(subInfo->recvFd, SOL_SOCKET, SO_PEERCRED, &uc, &len) < 0) {
INIT_LOGE("Failed to get socket option. err = %d", errno);
return -1;
}
// Only root is permitted to use control fd of init.
if (uc.uid != 0) { // non-root user
errno = EPERM;
return -1;
}
return 0;
}
static int HandleRecvMessage_(SubInitInfo *subInfo, char *buffer, uint32_t size)
{
if (CheckSocketPermission(subInfo) != 0) {
return -1;
}
ssize_t rLen = TEMP_FAILURE_RETRY(read(subInfo->recvFd, buffer, size));
while ((rLen < 0) && (errno == EAGAIN)) {
rLen = TEMP_FAILURE_RETRY(read(subInfo->recvFd, buffer, size));
}
PLUGIN_CHECK(rLen >= 0, return errno, "Read message for %d fail errno %d", subInfo->type, errno);
buffer[rLen] = '\0';
PLUGIN_LOGI("Exec cmd '%s' in sub init %s", buffer, g_subContext[subInfo->type]);
int index = 0;
const char *cmd = GetMatchCmd(buffer, &index);
PLUGIN_CHECK(cmd != NULL, return -1, "Can not find cmd %s", buffer);
DoCmdByIndex(index, buffer + strlen(cmd) + 1, NULL);
return 0;
}
static void HandleRecvMessage(SubInitInfo *subInfo, char *buffer, uint32_t size)
{
int ret = HandleRecvMessage_(subInfo, buffer, size);
int len = snprintf_s(buffer, size, size - 1, "%d", ret);
PLUGIN_CHECK(len > 0, return, "Failed to format result %d", ret);
buffer[len] = '\0';
ret = send(subInfo->sendFd, buffer, len, 0);
PLUGIN_CHECK(ret > 0, return, "Failed to send result to %d errno %d", subInfo->type, errno);
}
static void SubInitMain(InitContextType type, int readFd, int writeFd)
{
PLUGIN_LOGI("SubInitMain, sub init %s[%d] enter", g_subContext[type], getpid());
char buffer[MAX_CMD_LEN] = {0};
(void)prctl(PR_SET_NAME, "chipset_init");
struct pollfd pfd = {};
pfd.events = POLLIN;
pfd.fd = readFd;
#ifndef STARTUP_INIT_TEST
const int timeout = 30000; // 30000 30s
#else
const int timeout = 1000; // 1000 1s
#endif
SubInitInfo subInfo = {};
subInfo.type = type;
subInfo.recvFd = readFd;
subInfo.sendFd = writeFd;
while (1) {
pfd.revents = 0;
int ret = poll(&pfd, 1, timeout);
if (ret == 0) {
PLUGIN_LOGI("Poll sub init timeout, sub init %d exit", type);
return;
} else if (ret < 0) {
PLUGIN_LOGE("Failed to poll sub init socket!");
return;
}
if (pfd.revents & POLLIN) {
HandleRecvMessage(&subInfo, buffer, sizeof(buffer));
}
}
}
static int SubInitSetSelinuxContext(InitContextType type)
{
PLUGIN_CHECK(type < INIT_CONTEXT_MAIN, return -1, "Invalid type %d", type);
#ifdef WITH_SELINUX
setcon(g_subContext[type]);
#endif
return 0;
}
#ifdef STARTUP_INIT_TEST
SubInitInfo *GetSubInitInfo(InitContextType type)
{
PLUGIN_CHECK(type < INIT_CONTEXT_MAIN, return NULL, "Invalid type %d", type);
return &g_subInitInfo[type];
}
#endif
MODULE_CONSTRUCTOR(void)
{
for (size_t i = 0; i < ARRAY_LENGTH(g_subContext); i++) {
SubInitContext context = {
(InitContextType)i,
SubInitStart,
SubInitStop,
SubInitExecuteCmd,
SubInitSetSelinuxContext
};
InitSubInitContext((InitContextType)i, &context);
}
}
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef STARTUP_INIT_CONTEXT
#define STARTUP_INIT_CONTEXT
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include "init_cmds.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define MAX_CMD_LEN 512
typedef enum {
SUB_INIT_STATE_IDLE,
SUB_INIT_STATE_STARTING,
SUB_INIT_STATE_RUNNING
} SubInitState;
typedef struct {
InitContextType type;
int sendFd;
int recvFd;
pid_t subPid;
SubInitState state;
} SubInitInfo;
typedef struct {
InitContextType type;
int (*startSubInit)(InitContextType type);
void (*stopSubInit)(pid_t pid);
int (*executeCmdInSubInit)(InitContextType type, const char *, const char *);
int (*setSubInitContext)(InitContextType type);
} SubInitContext;
int StartSubInit(InitContextType type);
int InitSubInitContext(InitContextType type, const SubInitContext *context);
#ifdef STARTUP_INIT_TEST
SubInitInfo *GetSubInitInfo(InitContextType type);
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif
\ No newline at end of file
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "init_context.h"
#include "init_module_engine.h"
#include "plugin_adapter.h"
#include "securec.h"
static SubInitContext g_subInitContext[INIT_CONTEXT_MAIN] = { 0 };
static ConfigContext g_currContext = { INIT_CONTEXT_MAIN };
static int g_subInitRunning = 0;
int InitSubInitContext(InitContextType type, const SubInitContext *context)
{
PLUGIN_CHECK(type < INIT_CONTEXT_MAIN, return -1, "Invalid type %d", type);
PLUGIN_CHECK(context != NULL, return -1, "Invalid context %d", type);
g_subInitContext[type].type = type;
g_subInitContext[type].startSubInit = context->startSubInit;
g_subInitContext[type].stopSubInit = context->stopSubInit;
g_subInitContext[type].executeCmdInSubInit = context->executeCmdInSubInit;
g_subInitContext[type].setSubInitContext = context->setSubInitContext;
return 0;
}
void StopSubInit(pid_t pid)
{
if (g_subInitContext[0].stopSubInit != NULL) {
g_subInitContext[0].stopSubInit(pid);
}
}
int StartSubInit(InitContextType type)
{
PLUGIN_CHECK(type < INIT_CONTEXT_MAIN, return -1, "Invalid type %d", type);
if (!g_subInitRunning) {
// install init context
#ifndef STARTUP_INIT_TEST
InitModuleMgrInstall("init_context");
#endif
}
PLUGIN_CHECK(g_subInitContext[type].startSubInit != NULL, return -1, "Invalid context %d", type);
g_subInitRunning = 1;
return g_subInitContext[type].startSubInit(type);
}
int ExecuteCmdInSubInit(const ConfigContext *context, const char *name, const char *cmdContent)
{
PLUGIN_CHECK(context != NULL, return -1, "Invalid context");
PLUGIN_CHECK(name != NULL, return -1, "Invalid name");
PLUGIN_CHECK(context->type < INIT_CONTEXT_MAIN, return -1, "Invalid type %d", context->type);
PLUGIN_LOGV("Execute command '%s %s' in context %d", name, cmdContent, context->type);
StartSubInit(context->type);
PLUGIN_CHECK(g_subInitContext[context->type].executeCmdInSubInit != NULL,
return -1, "Invalid context %d", context->type);
return g_subInitContext[context->type].executeCmdInSubInit(context->type, name, cmdContent);
}
int SetSubInitContext(const ConfigContext *context, const char *service)
{
PLUGIN_CHECK(context != NULL, return -1, "Invalid context");
if (context->type >= INIT_CONTEXT_MAIN) {
g_currContext.type = INIT_CONTEXT_MAIN;
return 0;
}
g_currContext.type = context->type;
PLUGIN_CHECK(g_subInitContext[context->type].setSubInitContext != NULL,
return -1, "Invalid context %d", context->type);
PLUGIN_LOGI("Set selinux context %d for %s", context->type, service);
return g_subInitContext[context->type].setSubInitContext(context->type);
}
int CheckExecuteInSubInit(const ConfigContext *context)
{
return !(context == NULL || context->type == INIT_CONTEXT_MAIN || g_currContext.type != INIT_CONTEXT_MAIN);
}
...@@ -85,12 +85,15 @@ ENG_STATIC void MountEngPartitions(void) ...@@ -85,12 +85,15 @@ ENG_STATIC void MountEngPartitions(void)
BuildMountCmd(mountCmd, MOUNT_CMD_MAX_LEN, "/eng_system", BuildMountCmd(mountCmd, MOUNT_CMD_MAX_LEN, "/eng_system",
"/dev/block/by-name/eng_system", "ext4"); "/dev/block/by-name/eng_system", "ext4");
WaitForFile(ENG_SYSTEM_DEVICE_PATH, WAIT_MAX_SECOND); WaitForFile(ENG_SYSTEM_DEVICE_PATH, WAIT_MAX_SECOND);
DoCmdByName("mount ", mountCmd); int cmdIndex = 0;
(void)GetMatchCmd("mount ", &cmdIndex);
DoCmdByIndex(cmdIndex, mountCmd, NULL);
// Mount eng_chipset // Mount eng_chipset
BuildMountCmd(mountCmd, MOUNT_CMD_MAX_LEN, "/eng_chipset", BuildMountCmd(mountCmd, MOUNT_CMD_MAX_LEN, "/eng_chipset",
"/dev/block/by-name/eng_chipset", "ext4"); "/dev/block/by-name/eng_chipset", "ext4");
WaitForFile(ENG_CHIPSET_DEVICE_PATH, WAIT_MAX_SECOND); WaitForFile(ENG_CHIPSET_DEVICE_PATH, WAIT_MAX_SECOND);
DoCmdByName("mount ", mountCmd); DoCmdByIndex(cmdIndex, mountCmd, NULL);
} }
ENG_STATIC void BindMountFile(const char *source, const char *target) ENG_STATIC void BindMountFile(const char *source, const char *target)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <stdint.h> #include <stdint.h>
#include "cJSON.h" #include "cJSON.h"
#include "init_cmds.h"
#include "init_hashmap.h" #include "init_hashmap.h"
#include "list.h" #include "list.h"
#include "param_message.h" #include "param_message.h"
...@@ -107,6 +108,7 @@ typedef struct TriggerHeader_ { ...@@ -107,6 +108,7 @@ typedef struct TriggerHeader_ {
typedef struct CommandNode_ { typedef struct CommandNode_ {
struct CommandNode_ *next; struct CommandNode_ *next;
ConfigContext cfgContext;
uint32_t cmdKeyIndex; uint32_t cmdKeyIndex;
char content[0]; char content[0];
} CommandNode; } CommandNode;
...@@ -183,7 +185,7 @@ JobNode *UpdateJobTrigger(const TriggerWorkSpace *workSpace, ...@@ -183,7 +185,7 @@ JobNode *UpdateJobTrigger(const TriggerWorkSpace *workSpace,
JobNode *GetTriggerByName(const TriggerWorkSpace *workSpace, const char *triggerName); JobNode *GetTriggerByName(const TriggerWorkSpace *workSpace, const char *triggerName);
void FreeTrigger(const TriggerWorkSpace *workSpace, TriggerNode *trigger); void FreeTrigger(const TriggerWorkSpace *workSpace, TriggerNode *trigger);
void ClearTrigger(const TriggerWorkSpace *workSpace, int8_t type); void ClearTrigger(const TriggerWorkSpace *workSpace, int8_t type);
int AddCommand(JobNode *trigger, uint32_t cmdIndex, const char *content); int AddCommand(JobNode *trigger, uint32_t cmdIndex, const char *content, const ConfigContext *cfgContext);
CommandNode *GetNextCmdNode(const JobNode *trigger, const CommandNode *curr); CommandNode *GetNextCmdNode(const JobNode *trigger, const CommandNode *curr);
void PostParamTrigger(int type, const char *name, const char *value); void PostParamTrigger(int type, const char *name, const char *value);
......
...@@ -370,7 +370,9 @@ INIT_LOCAL_API int CheckParameterSet(const char *name, ...@@ -370,7 +370,9 @@ INIT_LOCAL_API int CheckParameterSet(const char *name,
// do hook cmd // do hook cmd
PARAM_LOGV("Check parameter settings realKey %s cmd: '%s' value: %s", PARAM_LOGV("Check parameter settings realKey %s cmd: '%s' value: %s",
serviceInfo->realKey, serviceInfo->cmdName, (char *)serviceInfo->realKey + serviceInfo->valueOffset); serviceInfo->realKey, serviceInfo->cmdName, (char *)serviceInfo->realKey + serviceInfo->valueOffset);
DoCmdByName(serviceInfo->cmdName, (char *)serviceInfo->realKey + serviceInfo->valueOffset); int cmdIndex = 0;
(void)GetMatchCmd(serviceInfo->cmdName, &cmdIndex);
DoCmdByIndex(cmdIndex, (char *)serviceInfo->realKey + serviceInfo->valueOffset, NULL);
#endif #endif
} }
if (serviceInfo != NULL) { if (serviceInfo != NULL) {
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
static DUMP_PRINTF g_printf = printf; static DUMP_PRINTF g_printf = printf;
int AddCommand(JobNode *trigger, uint32_t cmdKeyIndex, const char *content) int AddCommand(JobNode *trigger, uint32_t cmdKeyIndex, const char *content, const ConfigContext *cfgContext)
{ {
PARAM_CHECK(trigger != NULL, return -1, "trigger is null"); PARAM_CHECK(trigger != NULL, return -1, "trigger is null");
uint32_t size = sizeof(CommandNode); uint32_t size = sizeof(CommandNode);
...@@ -43,7 +43,10 @@ int AddCommand(JobNode *trigger, uint32_t cmdKeyIndex, const char *content) ...@@ -43,7 +43,10 @@ int AddCommand(JobNode *trigger, uint32_t cmdKeyIndex, const char *content)
PARAM_CHECK(ret == EOK, free(node); PARAM_CHECK(ret == EOK, free(node);
return 0, "Failed to copy command"); return 0, "Failed to copy command");
} }
node->cfgContext.type = INIT_CONTEXT_MAIN;
if (cfgContext != NULL) {
node->cfgContext.type = cfgContext->type;
}
if (trigger->firstCmd == NULL) { if (trigger->firstCmd == NULL) {
trigger->firstCmd = node; trigger->firstCmd = node;
trigger->lastCmd = node; trigger->lastCmd = node;
...@@ -488,8 +491,9 @@ static void DumpJobTrigger_(const TriggerWorkSpace *workSpace, const TriggerNode ...@@ -488,8 +491,9 @@ static void DumpJobTrigger_(const TriggerWorkSpace *workSpace, const TriggerNode
int count = 0; int count = 0;
CommandNode *cmd = GetNextCmdNode(node, NULL); CommandNode *cmd = GetNextCmdNode(node, NULL);
while (cmd != NULL && count < maxCmd) { while (cmd != NULL && count < maxCmd) {
PARAM_DUMP(" command name: %s \n", GetCmdKey(cmd->cmdKeyIndex)); PARAM_DUMP(" command name: %s (%s) \n", GetCmdKey(cmd->cmdKeyIndex),
PARAM_DUMP(" command args: %s \n", cmd->content); (cmd->cfgContext.type == INIT_CONTEXT_CHIPSET) ? "chipset" : "system");
PARAM_DUMP(" command args : %s \n", cmd->content);
cmd = GetNextCmdNode(node, cmd); cmd = GetNextCmdNode(node, cmd);
count++; count++;
} }
......
...@@ -37,7 +37,7 @@ static int DoTriggerExecute_(const TriggerNode *trigger, const char *content, ui ...@@ -37,7 +37,7 @@ static int DoTriggerExecute_(const TriggerNode *trigger, const char *content, ui
CommandNode *cmd = GetNextCmdNode((JobNode *)trigger, NULL); CommandNode *cmd = GetNextCmdNode((JobNode *)trigger, NULL);
while (cmd != NULL) { while (cmd != NULL) {
#ifndef STARTUP_INIT_TEST #ifndef STARTUP_INIT_TEST
DoCmdByIndex(cmd->cmdKeyIndex, cmd->content); DoCmdByIndex(cmd->cmdKeyIndex, cmd->content, &cmd->cfgContext);
#endif #endif
cmd = GetNextCmdNode((JobNode *)trigger, cmd); cmd = GetNextCmdNode((JobNode *)trigger, cmd);
} }
...@@ -225,7 +225,7 @@ static void ParseJobHookExecute(const char *name, const cJSON *jobNode) ...@@ -225,7 +225,7 @@ static void ParseJobHookExecute(const char *name, const cJSON *jobNode)
} }
static int ParseTrigger_(const TriggerWorkSpace *workSpace, static int ParseTrigger_(const TriggerWorkSpace *workSpace,
const cJSON *triggerItem, int (*checkJobValid)(const char *jobName)) const cJSON *triggerItem, int (*checkJobValid)(const char *jobName), const ConfigContext *cfgContext)
{ {
PARAM_CHECK(triggerItem != NULL, return -1, "Invalid file"); PARAM_CHECK(triggerItem != NULL, return -1, "Invalid file");
PARAM_CHECK(workSpace != NULL, return -1, "Failed to create trigger list"); PARAM_CHECK(workSpace != NULL, return -1, "Failed to create trigger list");
...@@ -260,16 +260,17 @@ static int ParseTrigger_(const TriggerWorkSpace *workSpace, ...@@ -260,16 +260,17 @@ static int ParseTrigger_(const TriggerWorkSpace *workSpace,
char *content = NULL; char *content = NULL;
ret = GetCommandInfo(cmdLineStr, &cmdKeyIndex, &content); ret = GetCommandInfo(cmdLineStr, &cmdKeyIndex, &content);
PARAM_CHECK(ret == 0, continue, "Command not support %s", cmdLineStr); PARAM_CHECK(ret == 0, continue, "Command not support %s", cmdLineStr);
ret = AddCommand(trigger, (uint32_t)cmdKeyIndex, content); ret = AddCommand(trigger, (uint32_t)cmdKeyIndex, content, cfgContext);
PARAM_CHECK(ret == 0, continue, "Failed to add command %s", cmdLineStr); PARAM_CHECK(ret == 0, continue, "Failed to add command %s", cmdLineStr);
header->cmdNodeCount++; header->cmdNodeCount++;
} }
return 0; return 0;
} }
int ParseTriggerConfig(const cJSON *fileRoot, int (*checkJobValid)(const char *jobName)) int ParseTriggerConfig(const cJSON *fileRoot, int (*checkJobValid)(const char *jobName), void *context)
{ {
PARAM_CHECK(fileRoot != NULL, return -1, "Invalid file"); PARAM_CHECK(fileRoot != NULL, return -1, "Invalid file");
ConfigContext *cfgContext = (ConfigContext *)context;
cJSON *triggers = cJSON_GetObjectItemCaseSensitive(fileRoot, TRIGGER_ARR_NAME_IN_JSON); cJSON *triggers = cJSON_GetObjectItemCaseSensitive(fileRoot, TRIGGER_ARR_NAME_IN_JSON);
if (triggers == NULL || !cJSON_IsArray(triggers)) { if (triggers == NULL || !cJSON_IsArray(triggers)) {
return 0; return 0;
...@@ -279,7 +280,7 @@ int ParseTriggerConfig(const cJSON *fileRoot, int (*checkJobValid)(const char *j ...@@ -279,7 +280,7 @@ int ParseTriggerConfig(const cJSON *fileRoot, int (*checkJobValid)(const char *j
for (int i = 0; i < size && i < TRIGGER_MAX_CMD; ++i) { for (int i = 0; i < size && i < TRIGGER_MAX_CMD; ++i) {
cJSON *item = cJSON_GetArrayItem(triggers, i); cJSON *item = cJSON_GetArrayItem(triggers, i);
ParseTrigger_(&g_triggerWorkSpace, item, checkJobValid); ParseTrigger_(&g_triggerWorkSpace, item, checkJobValid, cfgContext);
/* /*
* execute job parsing hooks * execute job parsing hooks
*/ */
...@@ -385,7 +386,7 @@ int AddCompleteJob(const char *name, const char *condition, const char *cmdConte ...@@ -385,7 +386,7 @@ int AddCompleteJob(const char *name, const char *condition, const char *cmdConte
int cmdKeyIndex = 0; int cmdKeyIndex = 0;
int ret = GetCommandInfo(cmdContent, &cmdKeyIndex, &content); int ret = GetCommandInfo(cmdContent, &cmdKeyIndex, &content);
PARAM_CHECK(ret == 0, return -1, "Command not support %s", cmdContent); PARAM_CHECK(ret == 0, return -1, "Command not support %s", cmdContent);
ret = AddCommand(trigger, (uint32_t)cmdKeyIndex, content); ret = AddCommand(trigger, (uint32_t)cmdKeyIndex, content, NULL); // use default context
PARAM_CHECK(ret == 0, return -1, "Failed to add command %s", cmdContent); PARAM_CHECK(ret == 0, return -1, "Failed to add command %s", cmdContent);
header->cmdNodeCount++; header->cmdNodeCount++;
PARAM_LOGV("AddCompleteJob %s type %d count %d", name, type, header->triggerCount); PARAM_LOGV("AddCompleteJob %s type %d count %d", name, type, header->triggerCount);
......
...@@ -163,8 +163,8 @@ HashNode *OH_HashMapFind(HashMapHandle handle, ...@@ -163,8 +163,8 @@ HashNode *OH_HashMapFind(HashMapHandle handle,
INIT_ERROR_CHECK(handle != NULL, return NULL, "Invalid hash handle"); INIT_ERROR_CHECK(handle != NULL, return NULL, "Invalid hash handle");
INIT_ERROR_CHECK(key != NULL && keyCompare != NULL, return NULL, "Invalid hash key"); INIT_ERROR_CHECK(key != NULL && keyCompare != NULL, return NULL, "Invalid hash key");
HashTab *tab = (HashTab *)handle; HashTab *tab = (HashTab *)handle;
INIT_ERROR_CHECK(hashCode < tab->maxBucket, return NULL, INIT_ERROR_CHECK((hashCode < tab->maxBucket) && (hashCode >= 0), return NULL,
"Invalid hashcode %d %d", tab->maxBucket, hashCode); "Invalid hash code %d %d", tab->maxBucket, hashCode);
return GetHashNodeByKey(tab, tab->buckets[hashCode], key, keyCompare); return GetHashNodeByKey(tab, tab->buckets[hashCode], key, keyCompare);
} }
......
...@@ -187,7 +187,7 @@ char *ReadFileData(const char *fileName) ...@@ -187,7 +187,7 @@ char *ReadFileData(const char *fileName)
char *buffer = NULL; char *buffer = NULL;
int fd = -1; int fd = -1;
fd = open(fileName, O_RDONLY); fd = open(fileName, O_RDONLY);
INIT_ERROR_CHECK(fd >= 0, return NULL, "Failed to read file %s", fileName); INIT_ERROR_CHECK(fd >= 0, return NULL, "Failed to read file %s errno:%d", fileName, errno);
buffer = (char *)calloc(1, MAX_SMALL_BUFFER); // fsmanager not create, can not get fileStat st_size buffer = (char *)calloc(1, MAX_SMALL_BUFFER); // fsmanager not create, can not get fileStat st_size
INIT_ERROR_CHECK(buffer != NULL, close(fd); INIT_ERROR_CHECK(buffer != NULL, close(fd);
return NULL, "Failed to allocate memory for %s", fileName); return NULL, "Failed to allocate memory for %s", fileName);
......
{
"jobs" : [{
"name" : "param:test.randrom.read.start=1",
"condition" : "test.randrom.read.start=1",
"cmds" : [
"param_randrom_write test.randrom.read 100",
"mkdir /data/test_verdor_init 0711 root root",
"write /data/test_verdor_init/test.txt 1",
"ifup lo",
"hostname localhost",
"domainname localdomain",
"symlink /data/test_verdor_init/test.txt /data/test_verdor_init/test_link.txt",
"chmod 0666 /data/test_verdor_init/test.txt",
"chown shell shell /data/test_verdor_init/test.txt",
"symlink /data/test_verdor_init/test.txt /data/test_verdor_init/test_link2.txt",
"copy /data/test_verdor_init/test.txt /data/test_verdor_init/test2.txt",
"wait /data/test_verdor_init/test.txt3 1",
"start group-test-stage1"
]
},
{
"name" : "param:test.randrom.read.start=rm",
"condition" : "test.randrom.read.start=rm",
"cmds" : [
"rm /data/test_verdor_init/test.txt ",
"rm /data/test_verdor_init/test2.txt",
"rmdir /data/test_verdor_init 0711 root root"
]
},
{
"name" : "test_verdor_init_job",
"cmds" : [
"param_randrom_write test.randrom.read 200",
"mkdir /data/test_verdor_init_2 0711 root root"
]
}
],
"services" : [{
"name" : "group-test-stage1",
"start-mode" : "normal",
"path" : ["/system/bin/begetctl", "init", "group", "test", "group-test-stage1"],
"once" : 1,
"jobs" : {
"on-start" : "test_verdor_init_job"
}
}
]
}
...@@ -20,9 +20,10 @@ ...@@ -20,9 +20,10 @@
#include "init_param.h" #include "init_param.h"
#include "modulemgr.h" #include "modulemgr.h"
#include "init_module_engine.h" #include "init_module_engine.h"
#include "init_cmds.h"
#include "securec.h" #include "securec.h"
#define MAX_COUNT 1000 #define MAX_COUNT 1
#define TEST_CMD_NAME "param_randrom_write" #define TEST_CMD_NAME "param_randrom_write"
#define READ_DURATION 100000 #define READ_DURATION 100000
...@@ -54,7 +55,7 @@ static int PluginParamCmdWriteParam(int id, const char *name, int argc, const ch ...@@ -54,7 +55,7 @@ static int PluginParamCmdWriteParam(int id, const char *name, int argc, const ch
MODULE_CONSTRUCTOR(void) MODULE_CONSTRUCTOR(void)
{ {
g_testCmdIndex = AddCmdExecutor(TEST_CMD_NAME, PluginParamCmdWriteParam); g_testCmdIndex = AddCareContextCmdExecutor(TEST_CMD_NAME, PluginParamCmdWriteParam);
} }
MODULE_DESTRUCTOR(void) MODULE_DESTRUCTOR(void)
......
...@@ -393,8 +393,16 @@ ohos_unittest("init_unittest") { ...@@ -393,8 +393,16 @@ ohos_unittest("init_unittest") {
include_dirs += [ include_dirs += [
"//base/startup/init/services/modules/bootevent", "//base/startup/init/services/modules/bootevent",
"//base/startup/init/services/modules/init_context",
"//base/startup/init/services/modules/sysevent", "//base/startup/init/services/modules/sysevent",
] ]
# test for init sub init_context
sources += [
"//base/startup/init/services/modules/init_context/init_context.c",
"//base/startup/init/services/modules/init_context/init_context_static.c",
"//base/startup/init/test/unittest/modules/context_unittest.cpp",
]
cflags_cc = [ "-fexceptions" ] cflags_cc = [ "-fexceptions" ]
} }
...@@ -24,6 +24,13 @@ ...@@ -24,6 +24,13 @@
using namespace testing::ext; using namespace testing::ext;
using namespace std; using namespace std;
static void DoCmdByName(const char *name, const char *cmdContent)
{
int cmdIndex = 0;
(void)GetMatchCmd(name, &cmdIndex);
DoCmdByIndex(cmdIndex, cmdContent, NULL);
}
namespace init_ut { namespace init_ut {
class CmdsUnitTest : public testing::Test { class CmdsUnitTest : public testing::Test {
public: public:
...@@ -200,13 +207,13 @@ HWTEST_F(CmdsUnitTest, TestGetCmdKey, TestSize.Level1) ...@@ -200,13 +207,13 @@ HWTEST_F(CmdsUnitTest, TestGetCmdKey, TestSize.Level1)
HWTEST_F(CmdsUnitTest, TestDoCmdByIndex, TestSize.Level1) HWTEST_F(CmdsUnitTest, TestDoCmdByIndex, TestSize.Level1)
{ {
DoCmdByIndex(1, "/data/init_ut/test_cmd_dir0"); DoCmdByIndex(1, "/data/init_ut/test_cmd_dir0", nullptr);
int ret = access("/data/init_ut/test_cmd_dir0", F_OK); int ret = access("/data/init_ut/test_cmd_dir0", F_OK);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
const int execPos = 17; const int execPos = 17;
DoCmdByIndex(execPos, "sleep 1"); DoCmdByIndex(execPos, "sleep 1", nullptr);
DoCmdByIndex(23, "test"); // 23 is cmd index DoCmdByIndex(23, "test", nullptr); // 23 is cmd index
} }
HWTEST_F(CmdsUnitTest, TestGetCmdLinesFromJson, TestSize.Level1) HWTEST_F(CmdsUnitTest, TestGetCmdLinesFromJson, TestSize.Level1)
......
...@@ -90,6 +90,13 @@ static TestHashNode *TestCreateHashNode(const char *value) ...@@ -90,6 +90,13 @@ static TestHashNode *TestCreateHashNode(const char *value)
return node; return node;
} }
static void DoCmdByName(const char *name, const char *cmdContent)
{
int cmdIndex = 0;
(void)GetMatchCmd(name, &cmdIndex);
DoCmdByIndex(cmdIndex, cmdContent, NULL);
}
namespace init_ut { namespace init_ut {
class InitGroupManagerUnitTest : public testing::Test { class InitGroupManagerUnitTest : public testing::Test {
public: public:
...@@ -217,7 +224,8 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService, TestSize.Level1) ...@@ -217,7 +224,8 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService, TestSize.Level1)
cJSON *fileRoot = cJSON_Parse(serviceStr); cJSON *fileRoot = cJSON_Parse(serviceStr);
ASSERT_NE(nullptr, fileRoot); ASSERT_NE(nullptr, fileRoot);
ParseAllServices(fileRoot); ConfigContext context = { INIT_CONTEXT_MAIN };
ParseAllServices(fileRoot, &context);
cJSON_Delete(fileRoot); cJSON_Delete(fileRoot);
Service *service = GetServiceByName("test-service"); Service *service = GetServiceByName("test-service");
...@@ -276,7 +284,8 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddServiceDeny, TestSize.Level1) ...@@ -276,7 +284,8 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddServiceDeny, TestSize.Level1)
cJSON *fileRoot = cJSON_Parse(serviceStr); cJSON *fileRoot = cJSON_Parse(serviceStr);
ASSERT_NE(nullptr, fileRoot); ASSERT_NE(nullptr, fileRoot);
ParseAllServices(fileRoot); ConfigContext context = { INIT_CONTEXT_MAIN };
ParseAllServices(fileRoot, &context);
cJSON_Delete(fileRoot); cJSON_Delete(fileRoot);
Service *service = GetServiceByName("test-service5"); Service *service = GetServiceByName("test-service5");
...@@ -309,7 +318,8 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService2, TestSize.Level1) ...@@ -309,7 +318,8 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService2, TestSize.Level1)
cJSON *fileRoot = cJSON_Parse(serviceStr); cJSON *fileRoot = cJSON_Parse(serviceStr);
ASSERT_NE(nullptr, fileRoot); ASSERT_NE(nullptr, fileRoot);
ParseAllServices(fileRoot); ConfigContext context = { INIT_CONTEXT_MAIN };
ParseAllServices(fileRoot, &context);
cJSON_Delete(fileRoot); cJSON_Delete(fileRoot);
char cmdStr[] = "all#bootevent"; char cmdStr[] = "all#bootevent";
char cmdStr1[] = "parameter_service"; char cmdStr1[] = "parameter_service";
......
...@@ -30,6 +30,13 @@ ...@@ -30,6 +30,13 @@
#include "init_hook.h" #include "init_hook.h"
#include "plugin_adapter.h" #include "plugin_adapter.h"
static void DoCmdByName(const char *name, const char *cmdContent)
{
int cmdIndex = 0;
(void)GetMatchCmd(name, &cmdIndex);
DoCmdByIndex(cmdIndex, cmdContent, NULL);
}
using namespace testing::ext; using namespace testing::ext;
using namespace std; using namespace std;
namespace init_ut { namespace init_ut {
...@@ -313,7 +320,8 @@ HWTEST_F(ServiceUnitTest, TestServiceBootEventHook, TestSize.Level1) ...@@ -313,7 +320,8 @@ HWTEST_F(ServiceUnitTest, TestServiceBootEventHook, TestSize.Level1)
cJSON *fileRoot = cJSON_Parse(serviceStr); cJSON *fileRoot = cJSON_Parse(serviceStr);
ASSERT_NE(nullptr, fileRoot); ASSERT_NE(nullptr, fileRoot);
PluginExecCmd("clear", 0, nullptr); PluginExecCmd("clear", 0, nullptr);
ParseAllServices(fileRoot); ConfigContext context = { INIT_CONTEXT_MAIN };
ParseAllServices(fileRoot, &context);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), NULL); (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), NULL);
serviceInfoContext.reserved = NULL; serviceInfoContext.reserved = NULL;
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), NULL); (void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), NULL);
......
...@@ -72,7 +72,7 @@ HWTEST_F(ModuleMgrUnitTest, PluginAddCmd, TestSize.Level1) ...@@ -72,7 +72,7 @@ HWTEST_F(ModuleMgrUnitTest, PluginAddCmd, TestSize.Level1)
PluginExecCmdByName(cmdName, nullptr); PluginExecCmdByName(cmdName, nullptr);
PluginExecCmdByName(cmdName, cmdContentNotValid); PluginExecCmdByName(cmdName, cmdContentNotValid);
g_cmdExecId = -1; g_cmdExecId = -1;
PluginExecCmdByCmdIndex(cmdIndex, cmdContent); PluginExecCmdByCmdIndex(cmdIndex, cmdContent, nullptr);
ASSERT_EQ(cmdExecId1, g_cmdExecId); ASSERT_EQ(cmdExecId1, g_cmdExecId);
const char *argv[] = {"test.value"}; const char *argv[] = {"test.value"};
PluginExecCmd("install", 1, argv); PluginExecCmd("install", 1, argv);
......
...@@ -157,8 +157,9 @@ void DoCmd(const TestCmdLine *resCmd) ...@@ -157,8 +157,9 @@ void DoCmd(const TestCmdLine *resCmd)
if (resCmd == nullptr) { if (resCmd == nullptr) {
return; return;
} }
int cmdIndex = 0;
DoCmdByName(resCmd->name, resCmd->cmdContent); (void)GetMatchCmd(resCmd->name, &cmdIndex);
DoCmdByIndex(cmdIndex, resCmd->cmdContent, NULL);
} }
/* /*
...@@ -927,7 +928,7 @@ HWTEST_F(StartupInitUTest, cmdFuncDoLoadCfgTest_003, TestSize.Level0) ...@@ -927,7 +928,7 @@ HWTEST_F(StartupInitUTest, cmdFuncDoLoadCfgTest_003, TestSize.Level0)
HWTEST_F(StartupInitUTest, cmdJobTest_001, TestSize.Level0) HWTEST_F(StartupInitUTest, cmdJobTest_001, TestSize.Level0)
{ {
// functions do not crash // functions do not crash
ParseAllJobs(nullptr); ParseAllJobs(nullptr, nullptr);
DoJob(nullptr); DoJob(nullptr);
DoJob("job name does not exist"); DoJob("job name does not exist");
ReleaseAllJobs(); ReleaseAllJobs();
...@@ -953,7 +954,8 @@ HWTEST_F(StartupInitUTest, cmdJobTest_002, TestSize.Level0) ...@@ -953,7 +954,8 @@ HWTEST_F(StartupInitUTest, cmdJobTest_002, TestSize.Level0)
if (jobItem == nullptr) { if (jobItem == nullptr) {
return; return;
} }
ParseAllJobs(jobItem); ConfigContext context = { INIT_CONTEXT_MAIN };
ParseAllJobs(jobItem, &context);
DoJob("pre-init"); DoJob("pre-init");
DoJob("init"); DoJob("init");
DoJob("post-init"); DoJob("post-init");
......
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "init_context.h"
#include "param_stub.h"
#include "securec.h"
using namespace std;
using namespace testing::ext;
namespace init_ut {
class InitContextUnitTest : public testing::Test {
public:
static void SetUpTestCase(void) {};
static void TearDownTestCase(void) {};
void SetUp() {};
void TearDown() {};
};
HWTEST_F(InitContextUnitTest, InitSubContextTest_01, TestSize.Level1)
{
int ret = StartSubInit(INIT_CONTEXT_CHIPSET);
EXPECT_EQ(ret, 0);
ret = StartSubInit(INIT_CONTEXT_MAIN);
EXPECT_NE(ret, 0);
}
HWTEST_F(InitContextUnitTest, InitSubContextTest_02, TestSize.Level1)
{
ConfigContext context = { INIT_CONTEXT_CHIPSET };
int ret = ExecuteCmdInSubInit(&context, "mkdir", STARTUP_INIT_UT_PATH"/testsubcontext");
EXPECT_EQ(ret, 0);
ret = ExecuteCmdInSubInit(&context, "mkdir", STARTUP_INIT_UT_PATH"/testsubcontext1");
EXPECT_EQ(ret, 0);
ret = ExecuteCmdInSubInit(&context, "mkdir", STARTUP_INIT_UT_PATH"/testsubcontext2");
EXPECT_EQ(ret, 0);
context.type = INIT_CONTEXT_MAIN;
ret = ExecuteCmdInSubInit(&context, "mkdir", STARTUP_INIT_UT_PATH"/testsubcontext");
EXPECT_NE(ret, 0);
}
HWTEST_F(InitContextUnitTest, InitSubContextTest_03, TestSize.Level1)
{
int ret = StartSubInit(INIT_CONTEXT_CHIPSET);
EXPECT_EQ(ret, 0);
SubInitInfo *subInfo = GetSubInitInfo(INIT_CONTEXT_CHIPSET);
if (subInfo == NULL) {
EXPECT_EQ(1, 0);
} else {
EXPECT_EQ(2, subInfo->state);
StopSubInit(subInfo->subPid);
}
}
HWTEST_F(InitContextUnitTest, InitSubContextTest_04, TestSize.Level1)
{
int ret = StartSubInit(INIT_CONTEXT_CHIPSET);
EXPECT_EQ(ret, 0);
SubInitInfo *subInfo = GetSubInitInfo(INIT_CONTEXT_CHIPSET);
if (subInfo != NULL) {
EXPECT_EQ(2, subInfo->state);
StopSubInit(subInfo->subPid);
} else {
EXPECT_EQ(1, 0);
}
// close
subInfo = GetSubInitInfo(INIT_CONTEXT_CHIPSET);
if (subInfo != NULL) {
EXPECT_EQ(0, subInfo->state);
}
}
HWTEST_F(InitContextUnitTest, InitSubContextTest_05, TestSize.Level1)
{
ConfigContext context = { INIT_CONTEXT_CHIPSET };
int ret = ExecuteCmdInSubInit(&context, "mkdir-2", STARTUP_INIT_UT_PATH"/testsubcontext");
EXPECT_EQ(ret, 0);
}
HWTEST_F(InitContextUnitTest, InitSubContextTest_06, TestSize.Level1)
{
ConfigContext context = { INIT_CONTEXT_CHIPSET };
int index = 0;
const char *cmd = GetMatchCmd("mkdir ", &index);
if (cmd == nullptr || strstr(cmd, "mkdir ") == nullptr) {
EXPECT_EQ(1, 0);
return;
}
DoCmdByIndex(index, STARTUP_INIT_UT_PATH"/testsubcontext", &context);
}
HWTEST_F(InitContextUnitTest, InitSubContextTest_07, TestSize.Level1)
{
ConfigContext context = { INIT_CONTEXT_MAIN };
int index = 0;
const char *cmd = GetMatchCmd("mkdir ", &index);
if (cmd == nullptr || strstr(cmd, "mkdir ") == nullptr) {
EXPECT_EQ(1, 0);
return;
}
DoCmdByIndex(index, STARTUP_INIT_UT_PATH"/testsubcontext", &context);
}
} // namespace init_ut
...@@ -139,7 +139,10 @@ HWTEST_F(TraceUnitTest, TraceTest_004, TestSize.Level1) ...@@ -139,7 +139,10 @@ HWTEST_F(TraceUnitTest, TraceTest_004, TestSize.Level1)
{ {
std::string cmdArgs = "/system/etc/init_trace.cfg "; std::string cmdArgs = "/system/etc/init_trace.cfg ";
cmdArgs += STARTUP_INIT_UT_PATH"/system/etc/init_trace.cfg"; cmdArgs += STARTUP_INIT_UT_PATH"/system/etc/init_trace.cfg";
DoCmdByName("copy ", cmdArgs.c_str()); int cmdIndex = 0;
(void)GetMatchCmd("copy ", &cmdIndex);
DoCmdByIndex(cmdIndex, cmdArgs.c_str(), NULL);
// start trace // start trace
PluginExecCmdByName("init_trace", "start"); PluginExecCmdByName("init_trace", "start");
// for run 1 s // for run 1 s
......
...@@ -87,7 +87,7 @@ public: ...@@ -87,7 +87,7 @@ public:
INIT_ERROR_CHECK(fileBuf != nullptr, return -1, "Failed to read file content %s", configFile); INIT_ERROR_CHECK(fileBuf != nullptr, return -1, "Failed to read file content %s", configFile);
cJSON *fileRoot = cJSON_Parse(fileBuf); cJSON *fileRoot = cJSON_Parse(fileBuf);
INIT_ERROR_CHECK(fileRoot != nullptr, return -1, "Failed to parse json file %s", configFile); INIT_ERROR_CHECK(fileRoot != nullptr, return -1, "Failed to parse json file %s", configFile);
ParseTriggerConfig(fileRoot, nullptr); ParseTriggerConfig(fileRoot, nullptr, nullptr);
cJSON_Delete(fileRoot); cJSON_Delete(fileRoot);
free(fileBuf); free(fileBuf);
fileBuf = nullptr; fileBuf = nullptr;
...@@ -137,9 +137,9 @@ public: ...@@ -137,9 +137,9 @@ public:
// add command // add command
int cmdIndex = 0; int cmdIndex = 0;
GetMatchCmd("reboot ", &cmdIndex); GetMatchCmd("reboot ", &cmdIndex);
int ret = AddCommand(trigger, cmdIndex, nullptr); int ret = AddCommand(trigger, cmdIndex, nullptr, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = AddCommand(trigger, cmdIndex, "update: aaaaaaa"); ret = AddCommand(trigger, cmdIndex, "update: aaaaaaa", nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
return 0; return 0;
} }
...@@ -160,9 +160,9 @@ public: ...@@ -160,9 +160,9 @@ public:
// add command // add command
int cmdIndex = 0; int cmdIndex = 0;
GetMatchCmd("reboot ", &cmdIndex); GetMatchCmd("reboot ", &cmdIndex);
int ret = AddCommand(trigger, cmdIndex, nullptr); int ret = AddCommand(trigger, cmdIndex, nullptr, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = AddCommand(trigger, cmdIndex, "update: aaaaaaa"); ret = AddCommand(trigger, cmdIndex, "update: aaaaaaa", nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
return 0; return 0;
} }
...@@ -361,7 +361,7 @@ public: ...@@ -361,7 +361,7 @@ public:
EXPECT_EQ(trigger, node); EXPECT_EQ(trigger, node);
const uint32_t cmdIndex = 100; const uint32_t cmdIndex = 100;
ret = AddCommand(trigger, cmdIndex, value); ret = AddCommand(trigger, cmdIndex, value, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
// 修改命令为测试执行 // 修改命令为测试执行
RegisterTriggerExec(TRIGGER_PARAM, TestCmdExec); RegisterTriggerExec(TRIGGER_PARAM, TestCmdExec);
...@@ -383,7 +383,7 @@ public: ...@@ -383,7 +383,7 @@ public:
JobNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); JobNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName);
EXPECT_EQ(trigger, node); EXPECT_EQ(trigger, node);
const uint32_t cmdIndex = 102; const uint32_t cmdIndex = 102;
ret = AddCommand(trigger, cmdIndex, value); ret = AddCommand(trigger, cmdIndex, value, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
RegisterTriggerExec(TRIGGER_PARAM, TestCmdExec); RegisterTriggerExec(TRIGGER_PARAM, TestCmdExec);
SystemWriteParam(param, value); SystemWriteParam(param, value);
...@@ -408,7 +408,7 @@ public: ...@@ -408,7 +408,7 @@ public:
return -1; return -1;
} }
const uint32_t cmdIndex = 103; const uint32_t cmdIndex = 103;
ret = AddCommand(trigger, cmdIndex, value); ret = AddCommand(trigger, cmdIndex, value, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE); TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE);
SystemWriteParam(param, value); SystemWriteParam(param, value);
...@@ -439,7 +439,7 @@ public: ...@@ -439,7 +439,7 @@ public:
return -1; return -1;
} }
const uint32_t cmdIndex = 105; const uint32_t cmdIndex = 105;
ret = AddCommand(trigger, cmdIndex, value); ret = AddCommand(trigger, cmdIndex, value, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE); TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE);
SystemWriteParam(param, value); SystemWriteParam(param, value);
...@@ -464,7 +464,7 @@ public: ...@@ -464,7 +464,7 @@ public:
const char *value = "5555"; const char *value = "5555";
JobNode *trigger = AddTrigger(TRIGGER_BOOT, boot, nullptr, 0); JobNode *trigger = AddTrigger(TRIGGER_BOOT, boot, nullptr, 0);
const int testCmdIndex = 1105; const int testCmdIndex = 1105;
int ret = AddCommand(trigger, testCmdIndex, value); int ret = AddCommand(trigger, testCmdIndex, value, nullptr);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
if (trigger == nullptr) { if (trigger == nullptr) {
return -1; return -1;
...@@ -476,7 +476,7 @@ public: ...@@ -476,7 +476,7 @@ public:
EXPECT_GE(ret, 0); EXPECT_GE(ret, 0);
trigger = AddTrigger(TRIGGER_UNKNOW, triggerName, buffer, 0); trigger = AddTrigger(TRIGGER_UNKNOW, triggerName, buffer, 0);
const int testCmdIndex2 = 105; const int testCmdIndex2 = 105;
ret = AddCommand(trigger, testCmdIndex2, value); ret = AddCommand(trigger, testCmdIndex2, value, nullptr);
RegisterTriggerExec(TRIGGER_UNKNOW, TestCmdExec); RegisterTriggerExec(TRIGGER_UNKNOW, TestCmdExec);
SystemWriteParam(param, value); SystemWriteParam(param, value);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册