Bugfix: 优化bootevent度量开机启动耗时

1) 去掉无效的init_trace静态插件
2)去掉InitAddServiceHook在INIT_SERVICE_FORK_BEFORE阶段的无效记录时间戳
3)优化INIT_CMD_RECORD的hook,只对耗时超过100ms的命令加入到bootevents列表
4)每次开机都记录同名的startup.bootevent文件,防止开机次数过多,产生过多垃圾文件
5)简化bootevent的clear命令处理逻辑
6)记录每个bootevent时间点到系统参数中
7)支持为系统应用预置bootevents

Signed-off-by: handyohos <zhangxiaotian@huawei.com>
Change-Id: I7cdc269fe1a0eb8e4394de010f1f71e6c16b5a6c

#I7XYNX
This commit is contained in:
handyohos 2023-09-05 17:56:10 +08:00
parent 749ff1b9f4
commit b5ac43a708
20 changed files with 256 additions and 247 deletions

View File

@ -222,8 +222,6 @@ int InitAddJobParseHook(JobParseHook hook);
*/
int InitAddServiceHook(ServiceHook hook, int hookState);
int InitAddClearServiceHook(ServiceHook hook);
#ifdef __cplusplus
#if __cplusplus
}

View File

@ -23,4 +23,4 @@ sys_param=4096
bootevent_param=4096
startup_init_param=40960
hiviewdfx_profiler_param=2048
ohos_boot_param = 4096
ohos_boot_param = 8192

View File

@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <time.h>
#include "beget_ext.h"
@ -104,6 +105,8 @@ int GetParameterFromCmdLine(const char *paramName, char *value, size_t valueLen)
*/
int StrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase);
long long GetUptimeInMicroSeconds(const struct timespec *uptime);
#ifdef __cplusplus
#if __cplusplus
}

View File

@ -42,8 +42,8 @@ extern "C" {
void SystemInit(void);
void LogInit(void);
void SystemPrepare(void);
void SystemConfig(void);
void SystemPrepare(long long uptime);
void SystemConfig(const char *uptime);
void SystemRun(void);
void SystemExecuteRcs(void);

View File

@ -46,7 +46,7 @@ void LogInit(void)
return;
}
void SystemPrepare(void)
void SystemPrepare(long long uptime)
{
}
@ -56,7 +56,7 @@ void ParseInitCfgByPriority(void)
ReadFileInDir("/vendor/etc/init", ".cfg", ParseInitCfg, NULL);
}
void SystemConfig(void)
void SystemConfig(const char *uptime)
{
InitServiceSpace();
#ifdef LITEOS_SUPPORT

View File

@ -15,16 +15,24 @@
#include <signal.h>
#include "init.h"
#include "init_log.h"
#include "init_utils.h"
static const pid_t INIT_PROCESS_PID = 1;
int main(int argc, char * const argv[])
{
const char *uptime = NULL;
long long upTimeInMicroSecs = 0;
int isSecondStage = 0;
(void)signal(SIGPIPE, SIG_IGN);
// Number of command line parameters is 2
if (argc == 2 && (strcmp(argv[1], "--second-stage") == 0)) {
if (argc > 1 && (strcmp(argv[1], "--second-stage") == 0)) {
isSecondStage = 1;
if (argc > 2) {
uptime = argv[2];
}
} else {
upTimeInMicroSecs = GetUptimeInMicroSeconds(NULL);
}
if (getpid() != INIT_PROCESS_PID) {
INIT_LOGE("Process id error %d!", getpid());
@ -32,13 +40,13 @@ int main(int argc, char * const argv[])
}
EnableInitLog(INIT_INFO);
if (isSecondStage == 0) {
SystemPrepare();
SystemPrepare(upTimeInMicroSecs);
} else {
LogInit();
}
SystemInit();
SystemExecuteRcs();
SystemConfig();
SystemConfig(uptime);
SystemRun();
return 0;
}

View File

@ -174,7 +174,7 @@ static int StartUeventd(char **requiredDevices, int num)
return 0;
}
static void StartInitSecondStage(void)
static void StartInitSecondStage(long long uptime)
{
int requiredNum = 0;
Fstab *fstab = LoadRequiredFstab();
@ -210,10 +210,13 @@ static void StartInitSecondStage(void)
INIT_LOGI("Start init second stage.");
SwitchRoot("/usr");
char buf[64];
snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%lld", uptime);
// Execute init second stage
char * const args[] = {
"/bin/init",
"--second-stage",
buf,
NULL,
};
if (execv("/bin/init", args) != 0) {
@ -222,7 +225,7 @@ static void StartInitSecondStage(void)
}
}
void SystemPrepare(void)
void SystemPrepare(long long uptime)
{
MountBasicFs();
CreateDeviceNode();
@ -235,7 +238,7 @@ void SystemPrepare(void)
// two stages of init.
// If we are in updater mode, only one stage of init.
if (InUpdaterMode() == 0) {
StartInitSecondStage();
StartInitSecondStage(uptime);
}
}
@ -388,7 +391,19 @@ void ParseInitCfgByPriority(void)
FreeCfgFiles(files);
}
void SystemConfig(void)
static void WriteUptimeSysParam(const char *param, const char *uptime)
{
char buf[64];
if (uptime == NULL) {
snprintf_s(buf, sizeof(buf), sizeof(buf) - 1,
"%lld", GetUptimeInMicroSeconds(NULL));
uptime = buf;
}
SystemWriteParam(param, uptime);
}
void SystemConfig(const char *uptime)
{
INIT_TIMING_STAT timingStat;
@ -424,6 +439,10 @@ void SystemConfig(void)
// parse parameters
HookMgrExecute(GetBootStageHookMgr(), INIT_PRE_PARAM_LOAD, (void *)&timingStat, (void *)&options);
InitLoadParamFiles();
// Write kernel uptime into system parameter
WriteUptimeSysParam("ohos.boot.time.kernel", uptime);
// read config
HookMgrExecute(GetBootStageHookMgr(), INIT_PRE_CFG_LOAD, (void *)&timingStat, (void *)&options);
ReadConfig();
@ -443,5 +462,6 @@ void SystemConfig(void)
void SystemRun(void)
{
WriteUptimeSysParam("ohos.boot.time.init", NULL);
StartParamService();
}

View File

@ -29,10 +29,7 @@ group("static_modules") {
if (build_selinux) {
deps += [ "selinux:libselinuxadp_static" ]
}
deps += [
"trace:inittrace_cfg",
"trace:libinittrace_static",
]
deps += [ "trace:inittrace_cfg" ]
}
}

View File

@ -22,6 +22,7 @@ config("bootevent_static_config") {
"//base/startup/init/services/param/include",
"//base/startup/init/services/include/param",
"//third_party/bounds_checking_function/include/",
"//base/customization/config_policy/interfaces/inner_api/include",
]
}

View File

@ -16,6 +16,7 @@
#include <stdbool.h>
#include "init_module_engine.h"
#include "init_group_manager.h"
#include "init_cmdexecutor.h"
#include "trigger_manager.h"
#include "init_log.h"
@ -26,10 +27,21 @@
#include "securec.h"
#include "init_utils.h"
#include "init_cmds.h"
#include "config_policy_utils.h"
static int GetBootEventEnable(void)
{
char bootEventOpen[6] = ""; // 6 is length of bool value
uint32_t len = sizeof(bootEventOpen);
SystemReadParam("persist.init.bootevent.enable", bootEventOpen, &len);
if (strcmp(bootEventOpen, "true") == 0 || strcmp(bootEventOpen, "1") == 0) {
return 1;
}
return 0;
}
static int g_bootEventNum = 0;
// check bootevent enable
static int g_bootEventEnable = 1;
static ListNode bootEventList = {&bootEventList, &bootEventList};
static int BootEventParaListCompareProc(ListNode *node, void *data)
@ -53,6 +65,33 @@ static int ParseBooteventCompareProc(ListNode *node, void *data)
return -1;
}
static int AddBootEventItem(BOOT_EVENT_PARAM_ITEM *item, const char *paramName)
{
OH_ListInit(&item->node);
for (int i = 0; i < BOOTEVENT_MAX; i++) {
item->timestamp[i].tv_nsec = 0;
item->timestamp[i].tv_sec = 0;
}
item->paramName = strdup(paramName);
if (item->paramName == NULL) {
return -1;
}
item->flags = BOOTEVENT_TYPE_SERVICE;
OH_ListAddTail(&bootEventList, (ListNode *)&item->node);
g_bootEventNum++;
return 0;
}
static int AddBootEventItemByName(const char *paramName)
{
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)calloc(1, sizeof(BOOT_EVENT_PARAM_ITEM));
if (item == NULL) {
return -1;
}
return AddBootEventItem(item, paramName);
}
static int AddServiceBootEvent(const char *serviceName, const char *paramName)
{
ServiceExtData *extData = NULL;
@ -64,6 +103,7 @@ static int AddServiceBootEvent(const char *serviceName, const char *paramName)
if (found != NULL) {
return -1;
}
// Find an empty bootevent data position
for (int i = HOOK_ID_BOOTEVENT; i < HOOK_ID_BOOTEVENT_MAX; i++) {
extData = AddServiceExtData(serviceName, i, NULL, sizeof(BOOT_EVENT_PARAM_ITEM));
if (extData != NULL) {
@ -74,28 +114,21 @@ static int AddServiceBootEvent(const char *serviceName, const char *paramName)
INIT_CHECK(extData != NULL, return -1);
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)extData->data;
OH_ListInit(&item->node);
for (int i = 0; i < BOOTEVENT_MAX; i++) {
item->timestamp[i].tv_nsec = 0;
item->timestamp[i].tv_sec = 0;
}
item->paramName = strdup(paramName);
if (item->paramName == NULL) {
if (AddBootEventItem(item, paramName) != 0) {
DelServiceExtData(serviceName, extData->dataId);
INIT_LOGI("strdup failed");
return -1;
}
item->flags = BOOTEVENT_TYPE_SERVICE;
OH_ListAddTail(&bootEventList, (ListNode *)&item->node);
return 0;
}
static void AddInitBootEvent(const char *bootEventName)
{
ListNode *found = NULL;
found = OH_ListFind(&bootEventList, (void *)bootEventName, ParseBooteventCompareProc);
BOOT_EVENT_PARAM_ITEM *found = NULL;
found = (BOOT_EVENT_PARAM_ITEM *)OH_ListFind(&bootEventList, (void *)bootEventName, ParseBooteventCompareProc);
if (found != NULL) {
(void)clock_gettime(CLOCK_MONOTONIC, &(((BOOT_EVENT_PARAM_ITEM *)found)->timestamp[BOOTEVENT_READY]));
(void)clock_gettime(CLOCK_MONOTONIC, &(found->timestamp[BOOTEVENT_READY]));
return;
}
@ -167,16 +200,8 @@ static int BootEventTraversal(ListNode *node, void *root)
static int SaveServiceBootEvent()
{
INIT_CHECK(GetBootEventEnable(), return 0);
time_t nowTime = time(NULL);
INIT_CHECK_RETURN_VALUE(nowTime > 0, -1);
struct tm *p = localtime(&nowTime);
INIT_CHECK_RETURN_VALUE(p != NULL, -1);
char bootEventFileName[BOOT_EVENT_FILEPATH_MAX_LEN] = "";
INIT_CHECK_RETURN_VALUE(snprintf_s(bootEventFileName, BOOT_EVENT_FILEPATH_MAX_LEN, BOOT_EVENT_FILEPATH_MAX_LEN - 1,
BOOTEVENT_OUTPUT_PATH"%d%d%d-%d%d.bootevent",
1900 + p->tm_year, p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min) >= 0, -1); // 1900 is start year
CheckAndCreatFile(bootEventFileName, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
FILE *tmpFile = fopen(bootEventFileName, "wr");
CheckAndCreatFile(BOOTEVENT_OUTPUT_PATH "bootup.trace", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
FILE *tmpFile = fopen(BOOTEVENT_OUTPUT_PATH "bootup.trace", "wr");
INIT_CHECK_RETURN_VALUE(tmpFile != NULL, -1);
cJSON *root = cJSON_CreateArray();
INIT_CHECK(root != NULL, (void)fclose(tmpFile);
@ -218,50 +243,89 @@ static void SetServiceBooteventHookMgr(const char *name, int state)
#endif
}
static void BootEventParaFireByName(const char *paramName)
static void BootCompleteClearAll(void)
{
ListNode *found = NULL;
char *bootEventValue = strrchr(paramName, '.');
INIT_CHECK(bootEventValue != NULL, return);
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
while (node != NULL) {
if (node->data.service == NULL) {
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
continue;
}
for (int i = HOOK_ID_BOOTEVENT; i < HOOK_ID_BOOTEVENT_MAX; i++) {
ServiceExtData *extData = GetServiceExtData(node->name, i);
if (extData == NULL) {
return;
}
free(((BOOT_EVENT_PARAM_ITEM *)extData->data)->paramName);
OH_ListRemove(&((BOOT_EVENT_PARAM_ITEM *)extData->data)->node);
DelServiceExtData(node->name, i);
}
}
// clear init boot event
OH_ListRemoveAll(&bootEventList, BootEventDestroy);
g_bootEventNum = 0;
}
static void WriteBooteventSysParam(const char *paramName)
{
char buf[64];
long long uptime;
char name[PARAM_NAME_LEN_MAX];
uptime = GetUptimeInMicroSeconds(NULL);
snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%lld", uptime);
snprintf_s(name, sizeof(name), sizeof(name) - 1, "ohos.boot.time.%s", paramName);
SystemWriteParam(name, buf);
}
static int BootEventParaFireByName(const char *paramName)
{
BOOT_EVENT_PARAM_ITEM *found = NULL;
char *bootEventValue = strrchr(paramName, '.');
INIT_CHECK(bootEventValue != NULL, return 0);
bootEventValue[0] = '\0';
found = OH_ListFind(&bootEventList, (void *)paramName, BootEventParaListCompareProc);
if (found == NULL) {
return;
}
int ret = ((BOOT_EVENT_PARAM_ITEM *)found)->timestamp[BOOTEVENT_READY].tv_sec;
INIT_CHECK(ret == 0, return);
WriteBooteventSysParam(paramName);
found = (BOOT_EVENT_PARAM_ITEM *)OH_ListFind(&bootEventList, (void *)paramName, BootEventParaListCompareProc);
if (found == NULL) {
return 0;
}
// Already fired
if (found->timestamp[BOOTEVENT_READY].tv_sec > 0) {
return 0;
}
INIT_CHECK_RETURN_VALUE(clock_gettime(CLOCK_MONOTONIC,
&(found->timestamp[BOOTEVENT_READY])) == 0, 0);
INIT_CHECK_ONLY_RETURN(clock_gettime(CLOCK_MONOTONIC,
&(((BOOT_EVENT_PARAM_ITEM *)found)->timestamp[BOOTEVENT_READY])) == 0);
g_bootEventNum--;
SetServiceBooteventHookMgr(paramName, 2); // 2: bootevent service has ready
// Check if all boot event params are fired
if (g_bootEventNum > 0) {
return;
return 0;
}
// All parameters are fired, set boot completed now ...
INIT_LOGI("All boot events are fired, boot complete now ...");
SystemWriteParam(BOOT_EVENT_BOOT_COMPLETED, "true");
g_bootEventEnable = BOOT_EVENT_FINISH;
SaveServiceBootEvent();
// report complete event
ReportSysEvent();
const char *clearBootEventArgv[] = {"bootevent"};
// clear servie extra data
PluginExecCmd("clear", ARRAY_LENGTH(clearBootEventArgv), clearBootEventArgv);
BootCompleteClearAll();
#ifndef STARTUP_INIT_TEST
HookMgrExecute(GetBootStageHookMgr(), INIT_BOOT_COMPLETE, NULL, NULL);
#endif
AutorunModuleMgrUnInstall("init_bootDetector");
return;
RemoveCmdExecutor("bootevent", -1);
return 1;
}
#define BOOT_EVENT_FIELD_NAME "bootevents"
static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx)
{
INIT_CHECK(g_bootEventEnable != 0, return);
int cnt;
cJSON *bootEvents = cJSON_GetObjectItem(serviceParseCtx->serviceNode, BOOT_EVENT_FIELD_NAME);
@ -279,7 +343,6 @@ static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx)
INIT_LOGI("Add service bootEvent failed %s", serviceParseCtx->serviceName);
return;
}
g_bootEventNum++;
SetServiceBooteventHookMgr(serviceParseCtx->serviceName, 1); // 1: bootevent service is starting
return;
}
@ -293,47 +356,15 @@ static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx)
INIT_LOGI("Add service bootEvent failed %s", serviceParseCtx->serviceName);
continue;
}
g_bootEventNum++;
SetServiceBooteventHookMgr(serviceParseCtx->serviceName, 1); // 1: bootevent service is starting
}
}
static void AddCmdBootEvent(int argc, const char **argv)
{
if (argc < 4) { // 4 is min args cmd boot event required
return;
}
BOOT_EVENT_PARAM_ITEM *item = calloc(1, sizeof(BOOT_EVENT_PARAM_ITEM));
INIT_CHECK(item != NULL, return);
OH_ListInit(&item->node);
item->timestamp[BOOTEVENT_FORK] = ((INIT_TIMING_STAT *)argv[3])->startTime; // 3 args
item->timestamp[BOOTEVENT_READY] = ((INIT_TIMING_STAT *)argv[3])->endTime; // 3 args
int cmdLen = strlen(argv[1]) + strlen(argv[2]) + 1; // 2 args 1 '\0'
item->paramName = calloc(1, cmdLen);
if (item->paramName == NULL) {
free(item);
return;
}
for (int i = 1; i < 3; i++) { // 3 cmd content end
INIT_CHECK_ONLY_ELOG(strcat_s(item->paramName, cmdLen, argv[i]) >= 0, "combine cmd args failed");
}
item->flags = BOOTEVENT_TYPE_CMD;
OH_ListAddTail(&bootEventList, (ListNode *)&item->node);
return;
}
static int DoBootEventCmd(int id, const char *name, int argc, const char **argv)
{
if (g_bootEventEnable == BOOT_EVENT_FINISH) {
return 0;
}
// clear init boot events that recorded before persist param read
if (g_bootEventEnable == 0) {
const char *clearBootEventArgv[] = {"bootevent"};
PluginExecCmd("clear", ARRAY_LENGTH(clearBootEventArgv), clearBootEventArgv);
OH_ListRemoveAll(&bootEventList, BootEventDestroy);
g_bootEventEnable = BOOT_EVENT_FINISH;
static int finished = 0;
if (finished) {
return 0;
}
@ -343,75 +374,70 @@ static int DoBootEventCmd(int id, const char *name, int argc, const char **argv)
return 0;
}
AddInitBootEvent(argv[1]);
} else if (strcmp(argv[0], "cmd") == 0) {
AddCmdBootEvent(argc, argv);
} else {
// argv[0] samgr.ready.true
BootEventParaFireByName(argv[0]);
finished = BootEventParaFireByName(argv[0]);
}
return 0;
}
static int32_t g_executorId = -1;
static int ParamSetBootEventHook(const HOOK_INFO *hookInfo, void *cookie)
static void AddReservedBooteventsByFile(const char *name)
{
if (g_executorId == -1) {
g_executorId = AddCmdExecutor("bootevent", DoBootEventCmd);
}
return 0;
}
char buf[MAX_PATH_LEN];
static void ClearServiceBootEvent(SERVICE_INFO_CTX *serviceCtx)
{
if (serviceCtx->reserved == NULL || strcmp(serviceCtx->reserved, "bootevent") == 0) {
for (int i = HOOK_ID_BOOTEVENT; i < HOOK_ID_BOOTEVENT_MAX; i++) {
ServiceExtData *extData = GetServiceExtData(serviceCtx->serviceName, i);
if (extData == NULL) {
return;
}
free(((BOOT_EVENT_PARAM_ITEM *)extData->data)->paramName);
OH_ListRemove(&((BOOT_EVENT_PARAM_ITEM *)extData->data)->node);
DelServiceExtData(serviceCtx->serviceName, i);
g_bootEventNum--;
}
// clear service extra data first
FILE *file = fopen(name, "r");
if (file == NULL) {
return;
}
if (strcmp(serviceCtx->reserved, "clearInitBootevent") == 0) {
// clear init boot event
OH_ListRemoveAll(&bootEventList, BootEventDestroy);
g_bootEventNum = 0;
while (fgets((void *)buf, sizeof(buf) - 1, file)) {
buf[sizeof(buf) - 1] = '\0';
char *end = strchr(buf, '\r');
if (end != NULL) {
*end = '\0';
}
end = strchr(buf, '\n');
if (end != NULL) {
*end = '\0';
}
INIT_LOGI("Got priv-app bootevent: %s", buf);
AddBootEventItemByName(buf);
}
return;
fclose(file);
}
static void AddReservedBootevents(void) {
CfgFiles *files = GetCfgFiles("etc/init/priv_app.bootevents");
for (int i = MAX_CFG_POLICY_DIRS_CNT - 1; files && i >= 0; i--) {
if (files->paths[i]) {
AddReservedBooteventsByFile(files->paths[i]);
}
}
FreeCfgFiles(files);
}
static int ParamSetBootEventHook(const HOOK_INFO *hookInfo, void *cookie)
{
AddReservedBootevents();
AddCmdExecutor("bootevent", DoBootEventCmd);
return 0;
}
static void SetServiceBootEventFork(SERVICE_INFO_CTX *serviceCtx)
{
INIT_CHECK(g_bootEventEnable != 0, return);
BOOT_EVENT_PARAM_ITEM *item;
for (int i = HOOK_ID_BOOTEVENT; i < HOOK_ID_BOOTEVENT_MAX; i++) {
ServiceExtData *extData = GetServiceExtData(serviceCtx->serviceName, i);
if (extData == NULL) {
return;
}
item = (BOOT_EVENT_PARAM_ITEM *)extData->data;
if (serviceCtx->reserved != NULL) {
((BOOT_EVENT_PARAM_ITEM *)extData->data)->pid = *((int *)serviceCtx->reserved);
continue;
item->pid = *((int *)serviceCtx->reserved);
}
INIT_CHECK_ONLY_RETURN(clock_gettime(CLOCK_MONOTONIC,
&(((BOOT_EVENT_PARAM_ITEM *)extData->data)->timestamp[BOOTEVENT_FORK])) == 0);
&(item->timestamp[BOOTEVENT_FORK])) == 0);
}
return;
}
int GetBootEventEnable(void)
{
char bootEventOpen[6] = ""; // 6 is length of bool value
uint32_t len = sizeof(bootEventOpen);
SystemReadParam("persist.init.bootevent.enable", bootEventOpen, &len);
if (strcmp(bootEventOpen, "true") == 0 || strcmp(bootEventOpen, "1") == 0) {
return 1;
}
return 0;
}
ListNode *GetBootEventList(void)
@ -419,20 +445,54 @@ ListNode *GetBootEventList(void)
return &bootEventList;
}
static void AddCmdBootEvent(INIT_CMD_INFO *cmdCtx)
{
INIT_TIMING_STAT *timeStat = (INIT_TIMING_STAT *)cmdCtx->reserved;
long long diff = InitDiffTime(timeStat);
// If not time cost, just ignore
if (diff < SAVEINITBOOTEVENTMSEC) {
return;
}
BOOT_EVENT_PARAM_ITEM *item = calloc(1, sizeof(BOOT_EVENT_PARAM_ITEM));
if (item == NULL) {
return;
}
OH_ListInit(&item->node);
item->timestamp[BOOTEVENT_FORK] = timeStat->startTime;
item->timestamp[BOOTEVENT_READY] = timeStat->endTime;
int cmdLen = strlen(cmdCtx->cmdName) + strlen(cmdCtx->cmdContent) + 1; // 2 args 1 '\0'
item->paramName = calloc(1, cmdLen);
if (item->paramName == NULL) {
free(item);
return;
}
INIT_CHECK_ONLY_ELOG(snprintf_s(item->paramName, cmdLen, cmdLen - 1, "%s%s",
cmdCtx->cmdName, cmdCtx->cmdContent) >= 0,
"combine cmd args failed");
item->flags = BOOTEVENT_TYPE_CMD;
OH_ListAddTail(&bootEventList, (ListNode *)&item->node);
}
static int RecordInitCmd(const HOOK_INFO *info, void *cookie)
{
INIT_CMD_INFO *cmdCtx = (INIT_CMD_INFO *)cookie;
const char *bootEventArgv[] = {"cmd", cmdCtx->cmdName, cmdCtx->cmdContent, cmdCtx->reserved};
return DoBootEventCmd(0, NULL, ARRAY_LENGTH(bootEventArgv), bootEventArgv);
if (cookie == NULL) {
return 0;
}
AddCmdBootEvent((INIT_CMD_INFO *)cookie);
return 0;
}
MODULE_CONSTRUCTOR(void)
{
// Add hook to record time-cost commands
HOOK_INFO info = {INIT_CMD_RECORD, 0, RecordInitCmd, NULL};
HookMgrAddEx(GetBootStageHookMgr(), &info);
InitAddServiceHook(SetServiceBootEventFork, INIT_SERVICE_FORK_BEFORE);
InitAddServiceHook(SetServiceBootEventFork, INIT_SERVICE_FORK_AFTER);
InitAddClearServiceHook(ClearServiceBootEvent);
// Add hook to parse all services with bootevents
InitAddServiceParseHook(ServiceParseBootEventHook);
// Add hook to record start time for services with bootevents
InitAddServiceHook(SetServiceBootEventFork, INIT_SERVICE_FORK_AFTER);
InitAddGlobalInitHook(0, ParamSetBootEventHook);
}

3
services/modules/bootevent/bootevent.h Normal file → Executable file
View File

@ -37,7 +37,7 @@ extern "C" {
#define SECTONSEC 1000000000
#define USTONSEC 1000
#define SAVEINITBOOTEVENTMSEC 100000
#define BOOTEVENT_OUTPUT_PATH "/data/service/el0/startup/init/"
#define BOOTEVENT_OUTPUT_PATH "/data/log/startup/"
enum {
BOOTEVENT_FORK,
@ -53,7 +53,6 @@ typedef struct tagBOOT_EVENT_PARAM_ITEM {
int flags;
} BOOT_EVENT_PARAM_ITEM;
int GetBootEventEnable(void);
ListNode *GetBootEventList(void);
#ifdef __cplusplus

View File

@ -85,24 +85,6 @@ ServiceExtData *GetServiceExtData(const char *serviceName, uint32_t id)
return GetServiceExtData_(service, id);
}
static int ServiceClearHookWrapper(const HOOK_INFO *hookInfo, void *executionContext)
{
SERVICE_INFO_CTX *ctx = (SERVICE_INFO_CTX *)executionContext;
ServiceHook realHook = (ServiceHook)hookInfo->hookCookie;
realHook(ctx);
return 0;
};
int InitAddClearServiceHook(ServiceHook hook)
{
HOOK_INFO info;
info.stage = INIT_SERVICE_CLEAR;
info.prio = 0;
info.hook = ServiceClearHookWrapper;
info.hookCookie = (void *)hook;
return HookMgrAddEx(GetBootStageHookMgr(), &info);
}
static int JobParseHookWrapper(const HOOK_INFO *hookInfo, void *executionContext)
{
JOB_PARSE_CTX *jobParseContext = (JOB_PARSE_CTX *)executionContext;
@ -122,27 +104,6 @@ int InitAddJobParseHook(JobParseHook hook)
return HookMgrAddEx(GetBootStageHookMgr(), &info);
}
static int CmdClear(int id, const char *name, int argc, const char **argv)
{
SERVICE_INFO_CTX ctx = {0};
ctx.reserved = argc >= 1 ? argv[0] : NULL;
PLUGIN_LOGI("CmdClear %s cmd: %s", name, ctx.reserved);
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
while (node != NULL) {
if (node->data.service == NULL) {
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
continue;
}
ctx.serviceName = node->name;
HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)&ctx, NULL);
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
}
ctx.reserved = "clearInitBootevent";
HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)&ctx, NULL);
return 0;
}
static void SetLogLevelFunc(const char *value)
{
unsigned int level;
@ -176,7 +137,6 @@ static int InitCmd(int id, const char *name, int argc, const char **argv)
static int ParamSetInitCmdHook(const HOOK_INFO *hookInfo, void *cookie)
{
AddCmdExecutor("clear", CmdClear);
AddCmdExecutor("setloglevel", CmdSetLogLevel);
AddCmdExecutor("initcmd", InitCmd);
return 0;
@ -256,9 +216,3 @@ MODULE_CONSTRUCTOR(void)
// Depends on parameter service
InitAddPostPersistParamLoadHook(0, InitDebugHook);
}
MODULE_DESTRUCTOR(void)
{
const char *clearBootEventArgv[] = {"bootevent"};
PluginExecCmd("clear", ARRAY_LENGTH(clearBootEventArgv), clearBootEventArgv);
}

View File

@ -63,7 +63,6 @@ const ParamCmdInfo *GetServiceCtl(size_t *size)
static const ParamCmdInfo installParam[] = {
{"ohos.servicectrl.install", "install", "install" },
{"ohos.servicectrl.uninstall", "uninstall", "uninstall" },
{"ohos.servicectrl.clear", "clear", "clear" },
{"ohos.servicectrl.bootchart", "bootchart", "bootchart" },
{"ohos.servicectrl.init_trace", "init_trace", "init_trace" },
{"ohos.servicectrl.timer_start", "timer_start", "timer_start " },

View File

@ -52,12 +52,3 @@ ohos_prebuilt_etc("inittrace_cfg") {
part_name = "init"
subsystem_name = "startup"
}
ohos_source_set("libinittrace_static") {
sources = [ "init_trace_static.c" ]
include_dirs = comm_include
public_configs = [ ":inittrace_static_config" ]
public_configs += [ "../../../interfaces/innerkits/init_module_engine:init_module_engine_exported_config" ]
part_name = "init"
subsystem_name = "startup"
}

View File

@ -1,33 +0,0 @@
/*
* 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 <string.h>
#include "init_module_engine.h"
#include "bootevent.h"
#include "plugin_adapter.h"
static int InitTraceEarlyHook(const HOOK_INFO *info, void *cookie)
{
if (GetBootEventEnable()) {
PLUGIN_LOGI("init trace enabled.");
return 0;
}
return 0;
}
MODULE_CONSTRUCTOR(void)
{
// Depends on parameter service
InitAddPostPersistParamLoadHook(0, InitTraceEarlyHook);
}

View File

@ -26,6 +26,7 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include "init_log.h"
#include "securec.h"
@ -734,3 +735,19 @@ int StrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase)
}
return -1;
}
long long GetUptimeInMicroSeconds(const struct timespec *uptime)
{
struct timespec now;
if (uptime == NULL) {
clock_gettime(CLOCK_MONOTONIC, &now);
uptime = &now;
}
#define SECOND_TO_MICRO_SECOND (1000000)
#define MICRO_SECOND_TO_NANOSECOND (1000)
return (long long)((uptime->tv_sec * SECOND_TO_MICRO_SECOND) +
(uptime->tv_nsec / MICRO_SECOND_TO_NANOSECOND));
}

View File

@ -386,7 +386,6 @@ ohos_unittest("init_unittest") {
sources += [
"//base/startup/init/services/modules/trace/init_trace.c",
"//base/startup/init/services/modules/trace/init_trace_static.c",
"//base/startup/init/test/unittest/modules/trace_unittest.cpp",
]

View File

@ -319,7 +319,6 @@ HWTEST_F(ServiceUnitTest, TestServiceBootEventHook, TestSize.Level1)
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&serviceInfoContext), nullptr);
cJSON *fileRoot = cJSON_Parse(serviceStr);
ASSERT_NE(nullptr, fileRoot);
PluginExecCmd("clear", 0, nullptr);
ConfigContext context = { INIT_CONTEXT_MAIN };
ParseAllServices(fileRoot, &context);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), nullptr);

View File

@ -305,6 +305,5 @@ HWTEST_F(HookMgrUnitTest, HookMgrExecuteInit_unitest, TestSize.Level1)
{
HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
HookMgrExecute(GetBootStageHookMgr(), INIT_PRE_CFG_LOAD, nullptr, nullptr);
InitAddClearServiceHook([](SERVICE_INFO_CTX *serviceCtx) {return;});
}
} // namespace init_ut

View File

@ -596,12 +596,12 @@ static __attribute__((constructor(101))) void ParamTestStubInit(void)
#ifndef OHOS_LITE
TestBeforeInit();
#endif
SystemPrepare();
SystemPrepare(0);
#ifndef __LITEOS_A__
SystemInit();
#endif
PARAM_LOGI("SystemConfig \n");
SystemConfig();
SystemConfig(NULL);
PrepareInitUnitTestEnv();
}
@ -616,8 +616,6 @@ __attribute__((destructor)) static void ParamTestStubExit(void)
HookMgrExecute(GetBootStageHookMgr(), INIT_BOOT_COMPLETE, nullptr, nullptr);
CloseUeventConfig();
const char *clearBootEventArgv[] = {"bootevent"};
PluginExecCmd("clear", ARRAY_LENGTH(clearBootEventArgv), clearBootEventArgv);
CloseServiceSpace();
demoExit();
LE_CloseLoop(LE_GetDefaultLoop());