提交 3eed80cd 编写于 作者: C cheng_jinsong

add save bootevent command and unittest

Signed-off-by: Ncheng_jinsong <chengjinsong2@huawei.com>
Change-Id: I545b11b54564ed2cba2e3df80b518a5b8cdce8d0
上级 f9ff0c09
......@@ -17,9 +17,10 @@
"chmod 0771 /data",
"mkdir /data/service 0711 root root",
"mkdir /data/service/el0 0711 root root",
"mkdir /data/service/el0/startup 0755 root root",
"mkdir /data/service/el0/startup/init 0755 root root",
"mount configfs none /config nodev noexec nosuid",
"load_persist_params ",
"mkdir /data/bootchart 0755 root root",
"bootchart start",
"chown access_token access_token /dev/access_token_id",
"chmod 0666 /dev/access_token_id"
......
......@@ -29,6 +29,7 @@
#include "securec.h"
#define NANO_PRE_JIFFY 10000000
#define BOOTCHART_OUTPUT_PATH "/data/service/el0/startup/init/"
static BootchartCtrl *g_bootchartCtrl = NULL;
......@@ -80,10 +81,10 @@ static void BootchartLogHeader(void)
uint32_t len = sizeof(release);
(void)SystemReadParam("const.ohos.releasetype", release, &len);
char *cmdLine = ReadFileToBuffer("/proc/cmdline", g_bootchartCtrl->buffer, g_bootchartCtrl->bufferSize);
PLUGIN_CHECK(cmdLine != NULL, return, "Failed to open file /data/bootchart/header");
PLUGIN_CHECK(cmdLine != NULL, return, "Failed to open file "BOOTCHART_OUTPUT_PATH"header");
FILE *file = fopen("/data/bootchart/header", "we");
PLUGIN_CHECK(file != NULL, return, "Failed to open file /data/bootchart/header");
FILE *file = fopen(BOOTCHART_OUTPUT_PATH"header", "we");
PLUGIN_CHECK(file != NULL, return, "Failed to open file "BOOTCHART_OUTPUT_PATH"header");
(void)fprintf(file, "version = openharmony init\n");
(void)fprintf(file, "title = Boot chart for openharmony (%s)\n", date);
......@@ -162,9 +163,9 @@ static void bootchartLogProcess(FILE *log)
static void *BootchartThreadMain(void *data)
{
PLUGIN_LOGI("bootcharting start");
FILE *statFile = fopen("/data/bootchart/proc_stat.log", "w");
FILE *procFile = fopen("/data/bootchart/proc_ps.log", "w");
FILE *diskFile = fopen("/data/bootchart/proc_diskstats.log", "w");
FILE *statFile = fopen(BOOTCHART_OUTPUT_PATH"proc_stat.log", "w");
FILE *procFile = fopen(BOOTCHART_OUTPUT_PATH"proc_ps.log", "w");
FILE *diskFile = fopen(BOOTCHART_OUTPUT_PATH"proc_diskstats.log", "w");
do {
if (statFile == NULL || procFile == NULL || diskFile == NULL) {
PLUGIN_LOGE("Failed to open file");
......@@ -219,7 +220,6 @@ static void BootchartDestory(void)
static int DoBootchartStart(void)
{
mkdir("/data/bootchart", S_IRWXU | S_IRWXG | S_IRWXO);
if (g_bootchartCtrl != NULL) {
PLUGIN_LOGI("bootcharting has been start");
return 0;
......
......@@ -22,10 +22,16 @@
#include "init_service.h"
#include "bootstage.h"
#include "securec.h"
#include "init_utils.h"
#define BOOT_EVENT_PARA_PREFIX "bootevent."
#define BOOT_EVENT_PARA_PREFIX_LEN 10
#define BOOT_EVENT_TIMESTAMP_MAX_LEN 50
#define BOOT_EVENT_FILEPATH_MAX_LEN 60
#define SECTOMSEC 1000000
#define SECTONSEC 1000000000
#define MSECTONSEC 1000
#define BOOTEVENT_OUTPUT_PATH "/data/service/el0/startup/init/"
static int g_bootEventNum = 0;
enum {
......@@ -172,11 +178,71 @@ static int DoBootEventCmd(int id, const char *name, int argc, const char **argv)
return 0;
}
static int AddItemToJson(cJSON *root, const char *name, double startime, int tid, double durTime)
{
cJSON *obj = cJSON_CreateObject(); // release obj at traverse done
INIT_CHECK_RETURN_VALUE(obj != NULL, -1);
cJSON_AddStringToObject(obj, "name", name);
cJSON_AddNumberToObject(obj, "ts", startime);
cJSON_AddStringToObject(obj, "ph", "X");
cJSON_AddNumberToObject(obj, "pid", 0);
cJSON_AddNumberToObject(obj, "tid", tid);
cJSON_AddNumberToObject(obj, "dur", durTime);
cJSON_AddItemToArray(root, obj);
return 0;
}
static int BooteventTraversal(ListNode *node, void *root)
{
static int tid = 1; // 1 bootevent start num
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)node;
double forkTime = item->timestamp[BOOTEVENT_FORK].tv_sec * SECTOMSEC +
(double)item->timestamp[BOOTEVENT_FORK].tv_nsec / MSECTONSEC;
double readyTime = item->timestamp[BOOTEVENT_READY].tv_sec * SECTOMSEC +
(double)item->timestamp[BOOTEVENT_READY].tv_nsec / MSECTONSEC;
double durTime = readyTime - forkTime;
if (tid == 1) {
// set time datum is 0
INIT_CHECK_RETURN_VALUE(AddItemToJson((cJSON *)root, item->paramName, 0,
1, 0) == 0, -1);
}
INIT_CHECK_RETURN_VALUE(AddItemToJson((cJSON *)root, item->paramName, forkTime,
tid++, durTime > 0 ? durTime : 0) == 0, -1);
return 0;
}
static int SaveServiceBootEvent(int id, const char *name, int argc, const char **argv)
{
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(booteventFileName, BOOT_EVENT_FILEPATH_MAX_LEN,
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");
INIT_CHECK_RETURN_VALUE(tmpFile != NULL, -1);
cJSON *root = cJSON_CreateArray();
INIT_CHECK_RETURN_VALUE(root != NULL, -1);
OH_ListTraversal(&bootEventList, (void *)root, BooteventTraversal, 0);
char *buff = cJSON_Print(root);
INIT_CHECK_RETURN_VALUE(buff != NULL, -1);
INIT_CHECK_RETURN_VALUE(fprintf(tmpFile, "%s\n", buff) >= 0, -1);
free(buff);
cJSON_Delete(root);
(void)fflush(tmpFile);
(void)fclose(tmpFile);
return 0;
}
static int32_t g_executorId = -1;
static int ParamSetBootEventHook(const HOOK_INFO *hookInfo, void *cookie)
{
if (g_executorId == -1) {
g_executorId = AddCmdExecutor("bootevent", DoBootEventCmd);
AddCmdExecutor("save.bootevent", SaveServiceBootEvent);
}
return 0;
}
......@@ -194,10 +260,12 @@ static void DumpServiceBootEvent(SERVICE_INFO_CTX *serviceCtx)
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)serviceExtData->data;
char booteventForkTimeStamp[BOOT_EVENT_TIMESTAMP_MAX_LEN] = "";
char booteventReadyTimeStamp[BOOT_EVENT_TIMESTAMP_MAX_LEN] = "";
INIT_CHECK_ONLY_RETURN(sprintf_s(booteventForkTimeStamp, BOOT_EVENT_TIMESTAMP_MAX_LEN, "%ld.%ld",
(long)item->timestamp[BOOTEVENT_FORK].tv_sec, (long)item->timestamp[BOOTEVENT_FORK].tv_nsec) >= 0);
INIT_CHECK_ONLY_RETURN(sprintf_s(booteventReadyTimeStamp, BOOT_EVENT_TIMESTAMP_MAX_LEN, "%ld.%ld",
(long)item->timestamp[BOOTEVENT_READY].tv_sec, (long)item->timestamp[BOOTEVENT_READY].tv_nsec) >= 0);
INIT_CHECK_ONLY_RETURN(sprintf_s(booteventForkTimeStamp, BOOT_EVENT_TIMESTAMP_MAX_LEN, "%f",
item->timestamp[BOOTEVENT_FORK].tv_sec +
(double)item->timestamp[BOOTEVENT_FORK].tv_nsec / SECTONSEC) >= 0);
INIT_CHECK_ONLY_RETURN(sprintf_s(booteventReadyTimeStamp, BOOT_EVENT_TIMESTAMP_MAX_LEN, "%f",
(long)item->timestamp[BOOTEVENT_READY].tv_sec +
(double)item->timestamp[BOOTEVENT_READY].tv_nsec / SECTONSEC) >= 0);
printf("\t%-20.20s\t%-50s\t%-20.20s\t%-20.20s\n", serviceCtx->serviceName, item->paramName,
booteventForkTimeStamp, booteventReadyTimeStamp);
}
......
......@@ -5,7 +5,8 @@
"uid" : "paramwatcher",
"start-mode" : "boot",
"gid" : ["paramwatcher", "shell"],
"secon" : "u:r:param_watcher:s0"
"secon" : "u:r:param_watcher:s0",
"bootevents" : "bootevent.param_watcher.started"
}
]
}
......@@ -316,6 +316,7 @@ void WatcherManager::OnStart()
if (!res) {
WATCHER_LOGE("WatcherManager Publish failed");
}
SystemSetParameter("bootevent.param_watcher.started", "true");
if (deathRecipient_ == nullptr) {
deathRecipient_ = new DeathRecipient(this);
}
......
......@@ -261,35 +261,56 @@ HWTEST_F(ServiceUnitTest, TestServiceManagerGetService, TestSize.Level1)
ret = ParseOneService(serviceItem, service);
EXPECT_NE(ret, 0);
}
/**
* @tc.name: TestServiceBootEventHook
* @tc.desc: test bootevent module exec correct
* @tc.type: FUNC
* @tc.require: issueI5NTX4
* @tc.author:
*/
HWTEST_F(ServiceUnitTest, TestServiceBootEventHook, TestSize.Level1)
{
Service *service = nullptr;
const char *jsonStr = "{\"services\":{\"name\":\"test_service8\",\"path\":[\"/data/init_ut/test_service\"],"
"\"importance\":-20,\"uid\":\"system\",\"writepid\":[\"/dev/test_service\"],\"console\":1,"
"\"bootevents\" : [\"bootevent1\", \"bootevent2\"],"
"\"gid\":[\"system\"], \"critical\":[1,2]}}";
cJSON* jobItem = cJSON_Parse(jsonStr);
ASSERT_NE(nullptr, jobItem);
cJSON *serviceItem = cJSON_GetObjectItem(jobItem, "services");
ASSERT_NE(nullptr, serviceItem);
service = AddService("test_service2");
ASSERT_NE(nullptr, service);
int ret = ParseOneService(serviceItem, service);
if (ret < 0) {
return;
}
const char *serviceStr = "{"
"\"services\": [{"
"\"name\" : \"test-service\","
"\"path\" : [\"/dev/test_service\"],"
"\"start-mode\" : \"condition\","
"\"writepid\":[\"/dev/test_service\"],"
"\"bootevents\" : \"bootevent2\""
"},{"
"\"name\" : \"test-service\","
"\"path\" : [\"/dev/test_service\"],"
"\"start-mode\" : \"condition\","
"\"writepid\":[\"/dev/test_service\"],"
"\"bootevents\" : \"bootevent.bootevent2\""
"},{"
"\"name\" : \"test-service2\","
"\"path\" : [\"/dev/test_service\"],"
"\"console\":1,"
"\"start-mode\" : \"boot\","
"\"writepid\":[\"/dev/test_service\"],"
"\"bootevents\" : [\"bootevent.bootevent1\", \"bootevent.bootevent2\"]"
"}]"
"}";
SERVICE_PARSE_CTX context;
context.serviceName = "test_service2";
context.serviceNode = serviceItem;
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_PARSE, (void *)(&context), NULL);
ASSERT_NE(GetServiceExtData("test_service2", HOOK_ID_BOOTEVENT), nullptr);
SERVICE_INFO_CTX serviceInfoContext;
serviceInfoContext.serviceName = "test_service2";
serviceInfoContext.reserved = nullptr;
serviceInfoContext.serviceName = "test-service2";
serviceInfoContext.reserved = "bootevent";
HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, nullptr, nullptr);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&serviceInfoContext), NULL);
cJSON *fileRoot = cJSON_Parse(serviceStr);
ASSERT_NE(nullptr, fileRoot);
ParseAllServices(fileRoot);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), NULL);
SystemWriteParam("bootevent.bootevent1", "true");
SystemWriteParam("bootevent.bootevent1", "true");
SystemWriteParam("bootevent.bootevent2", "true");
SystemSetParameter("ohos.servicectrl.save.bootevent", "save.bootevent");
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&serviceInfoContext), NULL);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)(&serviceInfoContext), NULL);
cJSON_Delete(fileRoot);
}
HWTEST_F(ServiceUnitTest, TestServiceExec, TestSize.Level1)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册