提交 6af95970 编写于 作者: O openharmony_ci 提交者: Gitee

!47 fix init bug

Merge pull request !47 from 钟柠/init1
......@@ -16,7 +16,7 @@
#ifndef INIT_REBOOT_API_H
#define INIT_REBOOT_API_H
int DoRebootApi(const char *cmdContent);
int DoReboot(const char *cmdContent);
#endif
......@@ -14,7 +14,7 @@
import("//build/ohos.gni")
ohos_static_library("libreboot") {
sources = [
"//base/startup/init_lite/interfaces/innerkits/reboot/init_reboot_api.c",
"//base/startup/init_lite/interfaces/innerkits/reboot/init_reboot.c",
]
include_dirs = [
......
......@@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "init_reboot_api.h"
#include "init_reboot.h"
#include <stdio.h>
#include <string.h>
......@@ -20,13 +20,13 @@
#include "securec.h"
#include "init_log.h"
#define SYS_POWER_CTRL "sys.powerctrl."
#define SYS_POWER_CTRL "sys.powerctrl="
#define MAX_REBOOT_NAME_SIZE 100
#define MAX_REBOOT_VAUE_SIZE 500
int DoRebootApi(const char *cmdContent)
int DoReboot(const char *cmdContent)
{
char name[MAX_REBOOT_VAUE_SIZE];
char value[MAX_REBOOT_VAUE_SIZE];
if (cmdContent == NULL) {
INIT_LOGE("DoReboot api error, cmdContent is NULL.\n");
return -1;
......@@ -36,12 +36,12 @@ int DoRebootApi(const char *cmdContent)
INIT_LOGE("DoReboot api error, cmdContent = %s, length = %d.\n", cmdContent, length);
return -1;
}
if (snprintf_s(name, MAX_REBOOT_NAME_SIZE, MAX_REBOOT_NAME_SIZE - 1, "%s%s", SYS_POWER_CTRL, "reboot") < 0) {
if (snprintf_s(value, MAX_REBOOT_NAME_SIZE, MAX_REBOOT_NAME_SIZE - 1, "%s%s", "reboot,", cmdContent) < 0) {
INIT_LOGE("DoReboot api error, MAX_REBOOT_NAME_SIZE is not enough\n");
return -1;
}
if (SystemSetParameter(name, cmdContent) != 0) {
INIT_LOGE("DoRebootApi SystemSetParameter error\n");
if (SystemSetParameter("sys.powerctrl", value) != 0) {
INIT_LOGE("DoReboot Api SystemSetParameter error\n");
return -1;
}
return 0;
......
......@@ -14,10 +14,15 @@
import("//build/ohos.gni")
ohos_static_library("libsocket") {
sources = [
"//base/startup/init_lite/interfaces/innerkits/socket/init_socket_api.c",
"//base/startup/init_lite/interfaces/innerkits/socket/init_socket.c",
]
include_dirs = [ "//base/startup/init_lite/interfaces/innerkits/include" ]
include_dirs = [
"//base/startup/init_lite/interfaces/innerkits/include",
"//base/startup/init_lite/services/log",
]
deps = []
deps = [
"//base/startup/init_lite/services/log:init_log",
]
}
......@@ -13,7 +13,7 @@
* limitations under the License.
*/
#include "init_socket_api.h"
#include "init_socket.h"
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
......@@ -27,6 +27,7 @@
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/un.h>
#include "init_log.h"
#define N_DEC 10
#define MAX_SOCKET_ENV_PREFIX_LEN 64
......
......@@ -142,7 +142,7 @@ if (defined(ohos_lite)) {
}
ohos_prebuilt_etc("init.cfg") {
source = "//device/hisilicon/hi3516dv300/updater/init.cfg"
source = "//base/startup/init_lite/services/etc/init.cfg"
part_name = "init"
}
......@@ -151,17 +151,24 @@ if (defined(ohos_lite)) {
part_name = "init"
}
ohos_prebuilt_etc("init.Hi3516DV300.cfg") {
source = "//device/hisilicon/hi3516dv300/build/rootfs/init.Hi3516DV300.cfg"
part_name = "init"
}
group("startup_init") {
deps = [
":init",
":init.cfg",
":passwd",
":init.Hi3516DV300.cfg",
":updaterueventd",
"//base/startup/init_lite/services/param:getparam",
"//base/startup/init_lite/services/param:paramclient",
"//base/startup/init_lite/services/param:paramservice",
"//base/startup/init_lite/services/param:setparam",
"//base/startup/init_lite/services/reboot:reboot",
"//base/startup/init_lite/interfaces/innerkits/socket:libsocket",
]
}
}
此差异已折叠。
......@@ -21,6 +21,18 @@
#include <sys/types.h>
#include <unistd.h>
#define MAX_SOCK_NAME_LEN 16
#define SOCK_OPT_NUMS 6
enum SockOptionTab
{
SERVICE_SOCK_NAME = 0,
SERVICE_SOCK_TYPE,
SERVICE_SOCK_PERM,
SERVICE_SOCK_UID,
SERVICE_SOCK_GID,
SERVICE_SOCK_SETOPT
};
struct ServiceSocket;
struct ServiceSocket
{
......@@ -30,6 +42,7 @@ struct ServiceSocket
gid_t gid; // gid
bool passcred; // setsocketopt
mode_t perm; // Setting permissions
int sockFd;
struct ServiceSocket *next;
};
......
......@@ -22,6 +22,10 @@ extern "C" {
#endif
#endif
#define BINARY_BASE 2
#define OCTAL_BASE 8
#define DECIMAL_BASE 10
struct CmdArgs {
int argc;
char **argv;
......@@ -32,6 +36,7 @@ void FreeCmd(struct CmdArgs **cmd);
int DecodeUid(const char *name);
void CheckAndCreateDir(const char *fileName);
char* ReadFileToBuf(const char *configFile);
int SplitString(char *srcPtr, char **dstPtr, int maxNum);
#ifdef __cplusplus
#if __cplusplus
......
......@@ -37,13 +37,6 @@ typedef enum {
*/
void InitParamService();
/**
* 对Init接口
* 启动trigger服务。
*
*/
void StartTriggerService();
/**
* Init 接口
* 启动参数服务,在main启动的最后调用,阻赛当前线程
......@@ -98,7 +91,7 @@ int SystemReadParam(const char *name, char *value, unsigned int *len);
* 触发一个trigger操作。
*
*/
void PostTrigger(EventType type, void *content, u_int32_t contentLen);
void PostTrigger(EventType type, const char *content, u_int32_t contentLen);
/**
* 对Init接口
......
......@@ -26,6 +26,7 @@ extern "C" {
#endif
#define PARAM_VALUE_LEN_MAX 96
#define PARAM_NAME_LEN_MAX 96
typedef u_int32_t ParamHandle;
typedef struct {
......
......@@ -42,23 +42,19 @@ void InitLog(const char *tag, InitLogLevel logLevel, const char *fileName, int l
if (logLevel < g_logLevel) {
return;
}
va_list vargs;
va_start(vargs, fmt);
char tmpFmt[MAX_FORMAT_SIZE];
if (vsnprintf_s(tmpFmt, MAX_FORMAT_SIZE, MAX_FORMAT_SIZE, fmt, vargs) == -1) {
return;
}
// 可以替换stdout这个为对应的文件句柄
time_t logTime;
time(&logTime);
struct tm *t = gmtime(&logTime);
char logInfo[MAX_LOG_SIZE];
if (snprintf_s(logInfo, MAX_LOG_SIZE, MAX_LOG_SIZE, "%s %d-%d-%d %d:%d %s:%d [%s] [pid=%d] %s", tag,
(t->tm_year + BASE_YEAR), (t->tm_mon + 1), t->tm_mday, t->tm_hour, t->tm_min, fileName, line,
LOG_LEVEL_STR[logLevel], getpid(), tmpFmt) == -1) {
return;
}
printf("%s", logInfo );
fprintf(stdout, "[%d-%d-%d %d:%d][pid=%d][%s:%d][%s][%s] ",
(t->tm_year + BASE_YEAR), (t->tm_mon + 1), t->tm_mday, t->tm_hour, t->tm_min,
getpid(), fileName, line, tag, LOG_LEVEL_STR[logLevel]);
va_list list;
va_start(list, fmt);
vfprintf(stdout, fmt, list);
va_end(list);
fflush(stdout);
#if 0
int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC | O_APPEND );
if (fd < 1) {
......@@ -72,6 +68,5 @@ void InitLog(const char *tag, InitLogLevel logLevel, const char *fileName, int l
}
close(fd);
#endif
va_end(vargs);
}
......@@ -54,8 +54,6 @@ typedef enum InitLogLevel {
void InitLog(const char *tag, InitLogLevel logLevel, const char *fileName, int line, const char *fmt, ...);
void SetLogLevel(InitLogLevel logLevel);
void Logger(InitLogLevel level, const char *format, ...);
#endif
#define INIT_ERROR_CHECK(ret, statement, format, ...) \
......@@ -84,7 +82,7 @@ int JudgeLevel(const InitLogLevel level) { return return; }
__FILE_NAME__, __LINE__, ##__VA_ARGS__)
#else
#define STARTUP_LOG(LEVEL, LABEL, Level, fmt, ...) \
printf("[%s:%d][%s:%d] " fmt "\n", LABEL, getpid(), __FILE_NAME__, __LINE__, ##__VA_ARGS__);
InitLog(LABEL, LEVEL, (__FILE_NAME__), (__LINE__), fmt "\n", ##__VA_ARGS__)
#endif
#define STARTUP_LOGI(LABEL, fmt, ...) STARTUP_LOG(INIT_INFO, LABEL, Info, fmt, ##__VA_ARGS__)
......
......@@ -41,11 +41,6 @@ typedef struct {
char content[0];
} TriggerDataEvent;
typedef struct TriggerExecute {
TriggerEvent event;
TriggerNode *trigger;
} TriggerExecute;
#ifdef __cplusplus
#if __cplusplus
}
......
......@@ -333,7 +333,7 @@ int CheckControlParamPerms(ParamWorkSpace *workSpace,
int CheckParamName(const char *name, int info)
{
size_t nameLen = strlen(name);
if (nameLen >= PARAM_VALUE_LEN_MAX) {
if (nameLen >= PARAM_NAME_LEN_MAX) {
return PARAM_CODE_INVALID_NAME;
}
......
......@@ -223,6 +223,8 @@ int StartParamService()
PARAM_CHECK(ret == 0, return ret, "Failed to uv_pipe_init %d", ret);
ret = uv_pipe_bind(&pipeServer, PIPE_NAME);
PARAM_CHECK(ret == 0, return ret, "Failed to uv_pipe_bind %d %s", ret, uv_err_name(ret));
ret = chmod(PIPE_NAME, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
PARAM_CHECK(ret == 0, return ret, "Failed to chmod %s, err %d. \n", PIPE_NAME, errno);
ret = uv_listen((uv_stream_t*)&pipeServer, SOMAXCONN, OnConnection);
PARAM_CHECK(ret == 0, return ret, "Failed to uv_listen %d %s", ret, uv_err_name(ret));
......@@ -236,16 +238,13 @@ int SystemWriteParam(const char *name, const char *value)
PARAM_CHECK(name != NULL && value != NULL, return -1, "The name is null");
PARAM_LOGI("SystemWriteParam name %s value: %s", name, value);
int ret = WriteParamWithCheck(&g_paramWorkSpace, &g_paramWorkSpace.label, name, value);
//PARAM_LOGI("SystemWriteParam name %s value: %s", name, value);
if (ret == 0) {
ret = WritePersistParam(name, value);
PARAM_CHECK(ret == 0, return ret, "Failed to set param");
} else {
PARAM_LOGE("Failed to set param %d name %s %s", ret, name, value);
}
PARAM_CHECK(ret == 0, return ret, "Failed to set param %s", name);
ret = WritePersistParam(name, value);
PARAM_CHECK(ret == 0, return ret, "Failed to set persist param %s", name);
// notify event to process trigger
PostParamTrigger(name, value);
return 0;
return ret;
}
int SystemReadParam(const char *name, char *value, unsigned int *len)
......
......@@ -178,10 +178,6 @@ int GetValueFromContent(const char *content, u_int32_t contentSize, u_int32_t st
u_int32_t contentIndex = start;
u_int32_t currIndex = 0;
while (contentIndex < contentSize && currIndex < valueSize) {
if (isspace(content[contentIndex])) {
contentIndex++;
continue;
}
if (content[contentIndex] == '=') {
value[currIndex++] = '\0';
return 0;
......
......@@ -245,7 +245,7 @@ int ParseTrigger(TriggerWorkSpace *workSpace, cJSON *triggerItem)
PARAM_LOGE("Warning parseTrigger %s %s", name, condition);
}
}
PARAM_LOGE("ParseTrigger %s %u", name, offset);
PARAM_LOGI("ParseTrigger %s %u", name, offset);
// 添加命令行
cJSON* cmdItems = cJSON_GetObjectItem(triggerItem, CMDS_ARR_NAME_IN_JSON);
......@@ -278,7 +278,7 @@ int ParseTrigger(TriggerWorkSpace *workSpace, cJSON *triggerItem)
int ExecuteTrigger(TriggerWorkSpace *workSpace, TriggerNode *trigger, CMD_EXECUTE cmdExecuter)
{
PARAM_CHECK(workSpace != NULL && trigger != NULL && cmdExecuter != NULL, return -1, "Invalid param");
PARAM_LOGI("ExecuteCmds trigger %s", trigger->name);
PARAM_LOGI("ExecuteTrigger trigger %s", trigger->name);
CommandNode *cmd = GetCmdByIndex(workSpace, trigger, trigger->firstCmd);
while (cmd != NULL) {
cmdExecuter(trigger, cmd->name, cmd->content);
......
......@@ -23,24 +23,18 @@
#include "uv.h"
#define LABEL "Trigger"
#define SYS_POWER_CTRL "sys.powerctrl."
static int g_triggerServiceStart = 0;
#define MAX_TRIGGER_COUNT_RUN_ONCE 10
#define SYS_POWER_CTRL "sys.powerctrl="
static TriggerWorkSpace g_triggerWorkSpace = {};
static int DoCmdExecute(TriggerNode *trigger, const char *cmdName, const char *command)
{
PARAM_CHECK(trigger != NULL && cmdName != NULL && command != NULL, return -1, "Invalid param");
PARAM_LOGI("DoCmdExecute trigger %s cmd %s %s", trigger->name, cmdName, command);
if (strncmp(cmdName, TRIGGER_CMD, strlen(TRIGGER_CMD)) == 0) {
u_int32_t triggerIndex = 0;
TriggerNode *node = GetTriggerByName(&g_triggerWorkSpace, command, &triggerIndex);
if (node != NULL && !TRIGGER_NODE_IN_QUEUE(node)) { // 不在队列中
PARAM_LOGI("DoCmdExecute trigger %s", node->name);
TRIGGER_NODE_SET_QUEUE_FLAG(node);
ExecuteQueuePush(&g_triggerWorkSpace, node, triggerIndex);
}
DoTriggerExec(command);
return 0;
}
PARAM_LOGI("DoCmdExecute trigger %s cmd %s %s", trigger->name, cmdName, command);
DoCmdByName(cmdName, command);
return 0;
}
......@@ -60,7 +54,6 @@ static int DoTiggerCheckResult(TriggerNode *trigger, u_int32_t triggerIndex)
void ExecuteQueueWork(u_int32_t maxCount)
{
PARAM_LOGI("ExecuteQueueWork %d %d", getpid(), gettid());
u_int32_t executeCount = 0;
TriggerNode *trigger = ExecuteQueuePop(&g_triggerWorkSpace);
while (trigger != NULL) {
......@@ -95,7 +88,7 @@ static void CheckTriggers(int type, void *content, u_int32_t contentLen)
static void ProcessAfterEvent(uv_work_t *req, int status)
{
free(req);
ExecuteQueueWork(UINT32_MAX);
ExecuteQueueWork(MAX_TRIGGER_COUNT_RUN_ONCE);
}
static void ProcessEvent(uv_work_t *req)
......@@ -106,15 +99,16 @@ static void ProcessEvent(uv_work_t *req)
static const char *GetCmdInfo(const char *content, u_int32_t contentSize, char **cmdParam)
{
char cmd[MAX_CMD_NAME_LEN + 1] = { 0 };
int ret = GetValueFromContent(content, contentSize, 0, cmd, sizeof(cmd));
PARAM_CHECK(ret == 0, return NULL, "Failed parse cmd");
u_int32_t cmdLen = strlen(cmd);
PARAM_CHECK(cmdLen < MAX_CMD_NAME_LEN, return NULL, "Failed parse cmd");
cmd[cmdLen] = ' ';
cmd[cmdLen + 1] = '\0';
*cmdParam = (char *)content + cmdLen + 1;
return GetMatchCmd(cmd);
static const char *ctrlCmds[][2] = {
{"reboot", "reboot "}
};
for (size_t i = 0; i < sizeof(ctrlCmds) / sizeof(ctrlCmds[0]); i++) {
if (strncmp(content, ctrlCmds[i][0], strlen(ctrlCmds[i][0])) == 0) {
*cmdParam = (char *)content;
return GetMatchCmd(ctrlCmds[i][1]);
}
}
return NULL;
}
static void SendTriggerEvent(TriggerDataEvent *event)
......@@ -128,10 +122,6 @@ static void SendTriggerEvent(TriggerDataEvent *event)
} else {
PARAM_LOGE("SendTriggerEvent cmd %s not found", event->content);
}
}
else if (event->type == EVENT_BOOT || g_triggerServiceStart == 0) {
CheckTriggers(event->type, event->content, event->contentSize);
ExecuteQueueWork(UINT32_MAX); // 需要立刻执行
} else {
uv_queue_work(uv_default_loop(), &event->request, ProcessEvent, ProcessAfterEvent);
event = NULL;
......@@ -156,9 +146,9 @@ void PostParamTrigger(const char *name, const char *value)
PARAM_LOGI("PostParamTrigger %s success", name);
}
void PostTrigger(EventType type, void *content, u_int32_t contentLen)
void PostTrigger(EventType type, const char *content, u_int32_t contentLen)
{
PARAM_LOGI("PostTrigger %d", type);
PARAM_LOGI("PostTrigger %d %s", type, content);
PARAM_CHECK(content != NULL && contentLen > 0, return, "Invalid param");
TriggerDataEvent *event = (TriggerDataEvent *)malloc(sizeof(TriggerDataEvent) + contentLen + 1);
PARAM_CHECK(event != NULL, return, "Failed to alloc memory");
......@@ -171,12 +161,6 @@ void PostTrigger(EventType type, void *content, u_int32_t contentLen)
PARAM_LOGI("PostTrigger %d success", type);
}
void StartTriggerService()
{
PARAM_LOGI("StartTriggerService ");
g_triggerServiceStart = 1;
}
int ParseTriggerConfig(cJSON *fileRoot)
{
PARAM_CHECK(fileRoot != NULL, return -1, "Invalid file");
......@@ -206,7 +190,6 @@ void DoTriggerExec(const char *content)
TRIGGER_NODE_SET_QUEUE_FLAG(trigger);
ExecuteQueuePush(&g_triggerWorkSpace, trigger, triggerIndex);
}
ExecuteQueueWork(UINT32_MAX); // 需要立刻执行
}
TriggerWorkSpace *GetTriggerWorkSpace()
......
......@@ -16,7 +16,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "init_reboot_api.h"
#include "init_reboot.h"
int main(int argc, char* argv[])
{
......@@ -32,14 +32,14 @@ int main(int argc, char* argv[])
}
int ret = 0;
if (argc == 2) {
ret = DoRebootApi(argv[1]);
ret = DoReboot(argv[1]);
} else {
ret = DoRebootApi("NoArgument");
ret = DoReboot("NoArgument");
}
if (ret != 0) {
printf("[reboot command] DoRebootApi return error\n");
printf("[reboot command] DoReboot Api return error\n");
} else {
printf("[reboot command] DoRebootApi return ok\n");
printf("[reboot command] DoReboot Api return ok\n");
}
while (1) {
pause();
......
......@@ -85,7 +85,7 @@ static int GetServiceStringCaps(const cJSON* filedJ, Service* curServ)
for (; i < curServ->servPerm.capsCnt; ++i) {
if (cJSON_GetArrayItem(filedJ, i) == NULL || !cJSON_GetStringValue(cJSON_GetArrayItem(filedJ, i))
|| strlen(cJSON_GetStringValue(cJSON_GetArrayItem(filedJ, i))) <= 0) { // check all errors
INIT_LOGE("GetServiceStringCaps, parse item[%d] as string, error.\n", i);
INIT_LOGE("[init] service=%s, parse item[%d] as string, error.\n", curServ->name, i);
break;
}
char* fieldStr = cJSON_GetStringValue(cJSON_GetArrayItem(filedJ, i));
......@@ -99,12 +99,12 @@ static int GetServiceStringCaps(const cJSON* filedJ, Service* curServ)
if (j < mapSize) {
curServ->servPerm.caps[i] = g_capStrCapNum[j].CapNum;
} else {
INIT_LOGE("GetServiceStringCaps, fieldStr = %s, error.\n", fieldStr);
INIT_LOGE("[init] service=%s, CapbilityName=%s, error.\n", curServ->name, fieldStr);
break;
}
if (curServ->servPerm.caps[i] > CAP_LAST_CAP && curServ->servPerm.caps[i] != FULL_CAP) {
// resources will be released by function: ReleaseServiceMem
INIT_LOGE("GetServiceStringCaps, cap = %d, error.\n", curServ->servPerm.caps[i]);
INIT_LOGE("[init] service=%s, cap = %d, error.\n", curServ->name, curServ->servPerm.caps[i]);
return SERVICE_FAILURE;
}
}
......@@ -121,7 +121,7 @@ int GetServiceCaps(const cJSON* curArrItem, Service* curServ)
return SERVICE_SUCCESS;
}
if (!cJSON_IsArray(filedJ)) {
INIT_LOGE("GetServiceCaps, caps is not a list, error.\n");
INIT_LOGE("[init] service=%s, caps is not a list, error.\n", curServ->name);
return SERVICE_FAILURE;
}
// caps array does not exist, means do not need any capability
......@@ -130,13 +130,13 @@ int GetServiceCaps(const cJSON* curArrItem, Service* curServ)
return SERVICE_SUCCESS;
}
if (capsCnt > MAX_CAPS_CNT_FOR_ONE_SERVICE) {
INIT_LOGE("GetServiceCaps, too many caps[cnt %d] for one service, should not exceed %d.\n",
capsCnt, MAX_CAPS_CNT_FOR_ONE_SERVICE);
INIT_LOGE("[init], service=%s, too many caps[cnt %d] for one service, max is %d.\n",
curServ->name, capsCnt, MAX_CAPS_CNT_FOR_ONE_SERVICE);
return SERVICE_FAILURE;
}
curServ->servPerm.caps = (unsigned int*)malloc(sizeof(unsigned int) * capsCnt);
if (curServ->servPerm.caps == NULL) {
INIT_LOGE("GetServiceCaps, malloc error.\n");
INIT_LOGE("[init] GetServiceCaps, service=%s, malloc error.\n", curServ->name);
return SERVICE_FAILURE;
}
curServ->servPerm.capsCnt = capsCnt;
......@@ -145,13 +145,13 @@ int GetServiceCaps(const cJSON* curArrItem, Service* curServ)
cJSON* capJ = cJSON_GetArrayItem(filedJ, i);
if (!cJSON_IsNumber(capJ) || cJSON_GetNumberValue(capJ) < 0) {
// resources will be released by function: ReleaseServiceMem
INIT_LOGE("GetServiceCaps, capJ is not a number or capJ < 0, error.\n");
INIT_LOGI("[init], service=%s, Capbility is not a number or < 0, error.\n", curServ->name);
break;
}
curServ->servPerm.caps[i] = (unsigned int)cJSON_GetNumberValue(capJ);
if (curServ->servPerm.caps[i] > CAP_LAST_CAP && curServ->servPerm.caps[i] != FULL_CAP) { // CAP_LAST_CAP = 37
// resources will be released by function: ReleaseServiceMem
INIT_LOGE("GetServiceCaps, caps = %d, error.\n", curServ->servPerm.caps[i]);
INIT_LOGE("[init] service=%s, caps = %d, error.\n", curServ->name, curServ->servPerm.caps[i]);
return SERVICE_FAILURE;
}
}
......
......@@ -18,16 +18,99 @@
#include <unistd.h>
#include "cJSON.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)
{
char *p = NULL;
size_t contentLen = strlen(content);
if (cfgFile == NULL || content == NULL) {
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;
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;
}
#endif
void ParseAllImports(cJSON *root)
{
cJSON *importAttr = cJSON_GetObjectItemCaseSensitive(root, IMPORT_ARR_NAME_IN_JSON);
char *cfgFile = NULL;
if (!cJSON_IsArray(importAttr)) {
INIT_LOGE("ParseAllImports, import item is not array!\n");
return;
}
int importAttrSize = cJSON_GetArraySize(importAttr);
......@@ -38,13 +121,29 @@ void ParseAllImports(cJSON *root)
INIT_LOGE("Invalid type of import item. should be string\n");
return;
}
char *importFile = cJSON_GetStringValue(importItem);
if (importFile == NULL) {
char *importContent = cJSON_GetStringValue(importItem);
if (importContent == NULL) {
INIT_LOGE("cannot get import config file\n");
return;
}
INIT_LOGD("ready to import %s...\n", importFile);
ParseInitCfg(importFile);
// Only OHOS L2 support parameter.
#ifndef OHOS_LITE
if (ExtractCfgFile(&cfgFile, importContent) < 0) {
INIT_LOGW("Failed to import from %s\n", importContent);
if (cfgFile != NULL) {
free(cfgFile);
cfgFile = NULL;
}
continue;
}
#else
cfgFile = importContent;
#endif
INIT_LOGI("Import %s...\n", cfgFile);
ParseInitCfg(cfgFile);
// Do not forget to free memory.
free(cfgFile);
cfgFile = NULL;
}
INIT_LOGD("parse import file done\n");
return;
......
......@@ -46,11 +46,10 @@ static void ParseInitCfgContents(cJSON *root)
{
// parse services
ParseAllServices(root);
#ifdef OHOS_LITE
// parse jobs
ParseAllJobs(root);
#ifndef OHOS_LITE
#else
ParseTriggerConfig(root);
#endif
......@@ -66,6 +65,10 @@ void ParseInitCfg(const char *configFile)
}
char *fileBuf = ReadFileToBuf(configFile);
if (fileBuf == NULL) {
INIT_LOGE("Read %s failed\n", configFile);
return;
}
cJSON* fileRoot = cJSON_Parse(fileBuf);
free(fileBuf);
fileBuf = NULL;
......@@ -100,7 +103,7 @@ static void ReadCfgs(const char *dirPath)
if (strstr(dp->d_name, ".cfg") == NULL) {
continue;
}
INIT_LOGE("fileName :%s.\n", fileName);
INIT_LOGI("ReadCfgs :%s from %s success.\n", fileName, dirPath);
ParseInitCfg(fileName);
}
}
......@@ -128,29 +131,31 @@ void InitReadCfg()
DumpAllServices();
// DumpAllJobs();
#ifdef OHOS_LITE
// do jobs
DoJob("pre-init");
#ifndef __LINUX__
#ifdef OHOS_LITE
TriggerStage(EVENT1, EVENT1_WAITTIME, QS_STAGE1);
#endif
#endif
DoJob("init");
#ifndef __LINUX__
#ifdef OHOS_LITE
TriggerStage(EVENT2, EVENT2_WAITTIME, QS_STAGE2);
#endif
#endif
DoJob("post-init");
#ifndef __LINUX__
#ifdef OHOS_LITE
TriggerStage(EVENT3, EVENT3_WAITTIME, QS_STAGE3);
InitStageFinished();
#endif
#endif
ReleaseAllJobs();
#else
PostTrigger(EVENT_BOOT, "pre-init", strlen("pre-init"));
PostTrigger(EVENT_BOOT, "init", strlen("init"));
PostTrigger(EVENT_BOOT, "post-init", strlen("post-init"));
#endif
}
......@@ -109,10 +109,18 @@ void DoReboot(const char *value)
INIT_LOGI("[init] DoReboot value = %s\n", value);
if (strlen(value) > MAX_VALUE_LENGTH) {
INIT_LOGE("DoReboot reboot value error, value = %s.\n", value);
INIT_LOGE("[init] DoReboot reboot value error, value = %s.\n", value);
return;
}
const char *valueData = NULL;
if (strncmp(value, "reboot,", strlen("reboot,")) != 0) {
INIT_LOGE("[init] DoReboot reboot value = %s, must started with reboot ,error.\n", value);
return;
} else {
valueData = value + strlen("reboot,");
}
if (GetMountStatusForMountPoint("/vendor")) {
if (umount("/vendor") != 0) {
INIT_LOGE("DoReboot umount vendor failed! errno = %d.\n", errno);
......@@ -125,7 +133,7 @@ void DoReboot(const char *value)
}
StopAllServicesBeforeReboot();
// "shutdown"
if (strncmp(value, "shutdown", sizeof("shutdown")) == 0) {
if (strncmp(valueData, "shutdown", strlen("shutdown")) == 0) {
int ret = reboot(RB_POWER_OFF);
if (ret != 0) {
INIT_LOGE("DoReboot reboot(RB_POWER_OFF) failed! syscall ret %d, err %d.\n", ret, errno);
......@@ -144,8 +152,8 @@ void DoReboot(const char *value)
snprintf(msg.command, MAX_COMMAND_SIZE, "%s", "boot_updater");
msg.command[commandSize] = 0;
if (strlen(value) > strlen("updater:") && strncmp(value, "updater:", strlen("updater:")) == 0) {
const char *p = value + strlen("updater:");
if (strlen(valueData) > strlen("updater:") && strncmp(valueData, "updater:", strlen("updater:")) == 0) {
const char *p = valueData + strlen("updater:");
if (snprintf(msg.update, MAX_UPDATE_SIZE, "%s", p) > MAX_UPDATE_SIZE) {
INIT_LOGE("[init] DoReboot updater: RBMiscWriteUpdaterMessage error\n");
return;
......@@ -162,7 +170,7 @@ void DoReboot(const char *value)
}
return;
}
if (strlen(value) == strlen("updater") && strncmp(value, "updater", strlen("updater")) == 0) {
if (strlen(valueData) == strlen("updater") && strncmp(valueData, "updater", strlen("updater")) == 0) {
ret = RBMiscWriteUpdaterMessage(miscFile, &msg);
if(true != ret) {
INIT_LOGE("[init] DoReboot updater RBMiscWriteUpdaterMessage error\n");
......@@ -174,7 +182,7 @@ void DoReboot(const char *value)
}
return;
}
if (strlen(value) == strlen("NoArgument") && strncmp(value, "NoArgument", strlen("NoArgument")) == 0) {
if (strlen(valueData) == strlen("NoArgument") && strncmp(valueData, "NoArgument", strlen("NoArgument")) == 0) {
ret = reboot(RB_AUTOBOOT);
if (ret != 0) {
INIT_LOGE("DoReboot updater: reboot(RB_AUTOBOOT) failed! syscall ret %d, err %d.\n", ret, errno);
......
......@@ -189,7 +189,6 @@ int ServiceStart(Service *service)
}
service->pid = pid;
INIT_LOGI("start service %s succeed, pid %d.\n", service->name, service->pid);
return SERVICE_SUCCESS;
}
......
......@@ -423,57 +423,12 @@ static int GetUidStringNumber(const cJSON *curArrItem, Service *curServ)
return SERVICE_FAILURE;
}
static int SplitString(char *srcPtr, char **dstPtr)
{
if (!srcPtr) {
return -1;
}
char *buf = NULL;
dstPtr[0] = strtok_r(srcPtr, " ", &buf);
int i = 0;
while (dstPtr[i])
{
i++;
dstPtr[i] = strtok_r(NULL, " ", &buf);
}
dstPtr[i] = "\0";
int num = i;
for (int j = 0; j < num; j++) {
INIT_LOGI("dstPtr[%d] is %s \n", j, dstPtr[j]);
}
return num;
}
#define MAX_SOCK_NAME_LEN 16
#define SOCK_OPT_NUMS 6
enum SockOptionTab
{
SERVICE_SOCK_NAME = 0,
SERVICE_SOCK_TYPE,
SERVICE_SOCK_PERM,
SERVICE_SOCK_UID,
SERVICE_SOCK_GID,
SERVICE_SOCK_SETOPT
};
static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket *sockopt)
{
INIT_LOGI("ParseServiceSocket\n");
if (optNum != SOCK_OPT_NUMS) {
return -1;
}
sockopt->name = (char *)calloc(MAX_SOCK_NAME_LEN, sizeof(char));
if (sockopt->name == NULL) {
return -1;
}
if (opt[SERVICE_SOCK_NAME] == NULL) {
return -1;
}
int ret = memcpy_s(sockopt->name, MAX_SOCK_NAME_LEN, opt[SERVICE_SOCK_NAME], MAX_SOCK_NAME_LEN - 1);
if (ret != 0) {
return -1;
}
if (opt[SERVICE_SOCK_TYPE] == NULL) {
return -1;
}
......@@ -484,8 +439,7 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket
if (opt[SERVICE_SOCK_PERM] == NULL) {
return -1;
}
sockopt->perm = strtoul(opt[SERVICE_SOCK_PERM], 0, 8); //¡Áa?¡¥?a8????
sockopt->perm = strtoul(opt[SERVICE_SOCK_PERM], 0, OCTAL_BASE);
if (opt[SERVICE_SOCK_UID] == NULL) {
return -1;
}
......@@ -494,7 +448,6 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket
return -1;
}
sockopt->uid = uuid;
if (opt[SERVICE_SOCK_GID] == NULL) {
return -1;
}
......@@ -503,15 +456,44 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket
return -1;
}
sockopt->gid = ggid;
if (opt[SERVICE_SOCK_SETOPT] == NULL) {
return -1;
}
sockopt->passcred = strncmp(opt[SERVICE_SOCK_SETOPT], "passcred", strlen(opt[SERVICE_SOCK_SETOPT])) == 0 ? true : false;
if (opt[SERVICE_SOCK_NAME] == NULL) {
return -1;
}
sockopt->name = (char *)calloc(MAX_SOCK_NAME_LEN, sizeof(char));
if (sockopt->name == NULL) {
return -1;
}
int ret = memcpy_s(sockopt->name, MAX_SOCK_NAME_LEN, opt[SERVICE_SOCK_NAME], MAX_SOCK_NAME_LEN - 1);
if (ret != 0) {
free(sockopt->name);
return -1;
}
sockopt->next = NULL;
sockopt->sockFd = -1;
return 0;
}
static void FreeServiceSocket(struct ServiceSocket *sockopt)
{
if (!sockopt) {
return;
}
struct ServiceSocket *tmpSock = NULL;
while (sockopt) {
tmpSock = sockopt;
if (sockopt->name != NULL) {
free(sockopt->name);
sockopt->name = NULL;
}
sockopt = tmpSock->next;
free(tmpSock);
}
return;
}
static int GetServiceSocket(const cJSON* curArrItem, Service* curServ)
{
INIT_LOGI("GetServiceSocket \n");
......@@ -532,7 +514,7 @@ static int GetServiceSocket(const cJSON* curArrItem, Service* curServ)
}
char *sockStr = cJSON_GetStringValue(sockJ);
char *tmpStr[SOCK_OPT_NUMS] = {NULL,};
int num = SplitString(sockStr, tmpStr);
int num = SplitString(sockStr, tmpStr, SOCK_OPT_NUMS);
if (num != SOCK_OPT_NUMS) {
return SERVICE_FAILURE;
}
......@@ -571,12 +553,16 @@ static int GetServiceOnRestart(const cJSON* curArrItem, Service* curServ)
}
curServ->onRestart->cmdLine = (CmdLine *)calloc(cmdCnt, sizeof(CmdLine));
if (curServ->onRestart->cmdLine == NULL) {
free(curServ->onRestart);
return SERVICE_FAILURE;
}
curServ->onRestart->cmdNum = cmdCnt;
for (int i = 0; i < cmdCnt; ++i) {
cJSON* cmdJ = cJSON_GetArrayItem(filedJ, i);
if (!cJSON_IsString(cmdJ) || !cJSON_GetStringValue(cmdJ)) {
free(curServ->onRestart->cmdLine);
free(curServ->onRestart);
curServ->onRestart = NULL;
return SERVICE_FAILURE;
}
char *cmdStr = cJSON_GetStringValue(cmdJ);
......@@ -674,10 +660,14 @@ void ParseAllServices(const cJSON* fileRoot)
tmp[i].attribute & SERVICE_ATTR_DISABLED ? 1 : 0);
}
if (GetServiceSocket(curItem, &tmp[i]) != SERVICE_SUCCESS) {
// free list
INIT_LOGE("GetServiceSocket fail \n");
if (tmp[i].socketCfg != NULL) {
FreeServiceSocket(tmp[i].socketCfg);
tmp[i].socketCfg = NULL;
}
}
if (GetServiceOnRestart(curItem, &tmp[i]) != SERVICE_SUCCESS) {
// free
INIT_LOGE("GetServiceOnRestart fail \n");
}
}
// Increase service counter.
......@@ -754,12 +744,14 @@ void ReapServiceByPID(int pid)
{
for (int i = 0; i < g_servicesCnt; i++) {
if (g_services[i].pid == pid) {
#ifdef OHOS_LITE
if (g_services[i].attribute & SERVICE_ATTR_IMPORTANT) {
// important process exit, need to reboot system
g_services[i].pid = -1;
StopAllServices();
RebootSystem();
}
#endif
ServiceReap(&g_services[i]);
break;
}
......
......@@ -33,9 +33,12 @@ static int CreateSocket(struct ServiceSocket *sockopt)
if (!sockopt || !sockopt->name) {
return -1;
}
int sockFd = socket(PF_UNIX, sockopt->type, 0);
if (sockFd < 0) {
if (sockopt->sockFd >= 0) {
close(sockopt->sockFd);
sockopt->sockFd = -1;
}
sockopt->sockFd = socket(PF_UNIX, sockopt->type, 0);
if (sockopt->sockFd < 0) {
INIT_LOGE("socket fail %d \n", errno);
return -1;
}
......@@ -47,39 +50,41 @@ static int CreateSocket(struct ServiceSocket *sockopt)
sockopt->name);
if (access(addr.sun_path, F_OK)) {
INIT_LOGE("%s already exist, remove it\n", addr.sun_path);
unlink(addr.sun_path);
if (unlink(addr.sun_path) != 0) {
INIT_LOGE("ulink fail err %d \n", errno);
}
}
if (sockopt->passcred) {
int on = 1;
if (setsockopt(sockFd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
if (setsockopt(sockopt->sockFd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
unlink(addr.sun_path);
close(sockFd);
close(sockopt->sockFd);
return -1;
}
}
if (bind(sockFd, (struct sockaddr *)&addr, sizeof(addr))) {
if (bind(sockopt->sockFd, (struct sockaddr *)&addr, sizeof(addr))) {
INIT_LOGE("Create socket for service %s failed: %d\n", sockopt->name, errno);
unlink(addr.sun_path);
close(sockFd);
close(sockopt->sockFd);
return -1;
}
if (lchown(addr.sun_path, sockopt->uid, sockopt->gid)) {
unlink(addr.sun_path);
close(sockFd);
close(sockopt->sockFd);
INIT_LOGE("lchown fail %d \n", errno);
return -1;
}
if (fchmodat(AT_FDCWD, addr.sun_path, sockopt->perm, AT_SYMLINK_NOFOLLOW)) {
unlink(addr.sun_path);
close(sockFd);
close(sockopt->sockFd);
INIT_LOGE("fchmodat fail %d \n", errno);
return -1;
}
INIT_LOGI("CreateSocket success \n");
return sockFd;
return sockopt->sockFd;
}
static int SetSocketEnv(int fd, char *name)
......@@ -117,51 +122,3 @@ int DoCreateSocket(struct ServiceSocket *sockopt)
return 0;
}
int GetControlFromEnv(char *path)
{
if (path == NULL) {
return -1;
}
char *cp = path;
while (*cp) {
if (!isalnum(*cp)) *cp = '_';
++cp;
}
const char *val = getenv(path);
if (val == NULL) {
return -1;
}
errno = 0;
int fd = strtol(val, NULL, 10);
if (errno) {
return -1;
}
if (fcntl(fd, F_GETFD) < 0) {
return -1;
}
return fd;
}
int GetControlSocket(const char *name)
{
if (name == NULL) {
return -1;
}
char path[128] = {0};
snprintf(path, sizeof(path), HOS_SOCKET_ENV_PREFIX"%s", name);
int fd = GetControlFromEnv(path);
struct sockaddr_un addr;
socklen_t addrlen = sizeof(addr);
int ret = getsockname(fd, (struct sockaddr*)&addr, &addrlen);
if (ret < 0) {
return -1;
}
char sockDir[128] = {0};
snprintf(sockDir, sizeof(sockDir), HOS_SOCKET_DIR"/%s", name);
if (strncmp(sockDir, addr.sun_path, strlen(sockDir)) == 0) {
return fd;
}
return -1;
}
......@@ -92,30 +92,6 @@ void FreeCmd(struct CmdArgs **cmd)
return;
}
void Logger(InitLogLevel level, const char *format, ...)
{
FILE* pFile = fopen(LOG_FILE_NAME, "a");
static char *logLeveInfo[] = { "VERBOSE", "INFO", "WARN", "ERROR", "FATAL" };
if (level >= sizeof(logLeveInfo) / sizeof(char*) || pFile == NULL) {
return;
}
time_t t;
struct tm *localTimer;
time(&t);
localTimer = localtime (&t);
fprintf(pFile, "[%d/%d/%d %d:%d:%d][%s]", localTimer->tm_year + 1900, localTimer->tm_mon, localTimer->tm_mday,
localTimer->tm_hour, localTimer->tm_min, localTimer->tm_sec, logLeveInfo[level]);
va_list list;
va_start(list, format);
vfprintf(pFile, format, list);
va_end(list);
fprintf(pFile, "%s", " \n");
fflush(pFile);
fclose(pFile);
}
int DecodeUid(const char *name)
{
if (isalpha(name[0])) {
......@@ -153,14 +129,17 @@ char* ReadFileToBuf(const char *configFile)
do {
if (stat(configFile, &fileStat) != 0 ||
fileStat.st_size <= 0 || fileStat.st_size > MAX_JSON_FILE_LEN) {
INIT_LOGE("Unexpected config file \" %s \", check if it exist. if exist, check file size\n", configFile);
break;
}
fd = fopen(configFile, "r");
if (fd == NULL) {
INIT_LOGE("Open %s failed. err = %d\n", configFile, errno);
break;
}
buffer = (char*)malloc(fileStat.st_size + 1);
if (buffer == NULL) {
INIT_LOGE("Failed to allocate memory for config file, err = %d\n", errno);
break;
}
......@@ -177,4 +156,24 @@ char* ReadFileToBuf(const char *configFile)
fd = NULL;
}
return buffer;
}
\ No newline at end of file
}
int SplitString(char *srcPtr, char **dstPtr, int maxNum)
{
if ((!srcPtr) || (!dstPtr)){
return -1;
}
char *buf = NULL;
dstPtr[0] = strtok_r(srcPtr, " ", &buf);
int i = 0;
while (dstPtr[i] != NULL && (i < maxNum)) {
i++;
dstPtr[i] = strtok_r(NULL, " ", &buf);
}
dstPtr[i] = "\0";
int num = i;
for (int j = 0; j < num; j++) {
INIT_LOGI("dstPtr[%d] is %s \n", j, dstPtr[j]);
}
return num;
}
......@@ -15,6 +15,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef OHOS_DEBUG
......@@ -84,7 +85,7 @@ int main(int argc, char * const argv[])
// 2. Mount basic filesystem and create common device node.
MountBasicFs();
CreateDeviceNode();
MakeSocketDir("/dev/unix/socket/", 0755);
MakeSocketDir("/dev/unix/socket/", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
#endif
// 3. signal register
......@@ -111,7 +112,7 @@ int main(int argc, char * const argv[])
#ifdef OHOS_DEBUG
struct timespec tmCfg;
if (clock_gettime(CLOCK_REALTIME, &tmCfg) != 0) {
INIT_LOGE("main, after cfg, get time failed! err %d.\n", errno);
INIT_LOGE("main, get time failed! err %d.\n", errno);
}
#endif // OHOS_DEBUG
......@@ -123,7 +124,6 @@ int main(int argc, char * const argv[])
INIT_LOGI("main, entering wait.\n");
#ifndef OHOS_LITE
StartTriggerService();
StartParamService();
#endif
while (1) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册