1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci 16d9f0492fSopenharmony_ci#include "sys_event.h" 17d9f0492fSopenharmony_ci 18d9f0492fSopenharmony_ci#include <inttypes.h> 19d9f0492fSopenharmony_ci#include <time.h> 20d9f0492fSopenharmony_ci#include <sys/time.h> 21d9f0492fSopenharmony_ci 22d9f0492fSopenharmony_ci#include "bootevent.h" 23d9f0492fSopenharmony_ci#include "init_module_engine.h" 24d9f0492fSopenharmony_ci#include "init_param.h" 25d9f0492fSopenharmony_ci#include "plugin_adapter.h" 26d9f0492fSopenharmony_ci#include "securec.h" 27d9f0492fSopenharmony_ci#include "init_utils.h" 28d9f0492fSopenharmony_ci 29d9f0492fSopenharmony_citypedef struct { 30d9f0492fSopenharmony_ci char *buffer; 31d9f0492fSopenharmony_ci uint32_t bufferLen; 32d9f0492fSopenharmony_ci uint32_t currLen; 33d9f0492fSopenharmony_ci} EventArgs; 34d9f0492fSopenharmony_ci 35d9f0492fSopenharmony_cistatic int GetServiceName(const char *paramName, char *buffer, size_t buffSize) 36d9f0492fSopenharmony_ci{ 37d9f0492fSopenharmony_ci size_t len = strlen(paramName); 38d9f0492fSopenharmony_ci size_t i = 0; 39d9f0492fSopenharmony_ci for (size_t index = strlen("bootevent."); index < len; index++) { 40d9f0492fSopenharmony_ci PLUGIN_CHECK(i <= buffSize, return -1); 41d9f0492fSopenharmony_ci if (*(paramName + index) == '.') { 42d9f0492fSopenharmony_ci break; 43d9f0492fSopenharmony_ci } 44d9f0492fSopenharmony_ci buffer[i++] = *(paramName + index); 45d9f0492fSopenharmony_ci } 46d9f0492fSopenharmony_ci return (int)i; 47d9f0492fSopenharmony_ci} 48d9f0492fSopenharmony_ci 49d9f0492fSopenharmony_cistatic int TraversalEvent(ListNode *node, void *root) 50d9f0492fSopenharmony_ci{ 51d9f0492fSopenharmony_ci BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)node; 52d9f0492fSopenharmony_ci if (item->flags != BOOTEVENT_TYPE_SERVICE) { 53d9f0492fSopenharmony_ci return 0; 54d9f0492fSopenharmony_ci } 55d9f0492fSopenharmony_ci EventArgs *args = (EventArgs *)root; 56d9f0492fSopenharmony_ci int len = GetServiceName(item->paramName, args->buffer + args->currLen, args->bufferLen - args->currLen); 57d9f0492fSopenharmony_ci PLUGIN_CHECK(len > 0 && (((uint32_t)len + args->currLen) < args->bufferLen), return -1, 58d9f0492fSopenharmony_ci "Failed to format service name %s", item->paramName); 59d9f0492fSopenharmony_ci args->currLen += (uint32_t)len; 60d9f0492fSopenharmony_ci 61d9f0492fSopenharmony_ci len = sprintf_s(args->buffer + args->currLen, args->bufferLen - args->currLen, ",%u:%u,%u:%u;", 62d9f0492fSopenharmony_ci (uint32_t)item->timestamp[BOOTEVENT_FORK].tv_sec, 63d9f0492fSopenharmony_ci (uint32_t)(item->timestamp[BOOTEVENT_FORK].tv_nsec / USTONSEC), 64d9f0492fSopenharmony_ci (uint32_t)item->timestamp[BOOTEVENT_READY].tv_sec, 65d9f0492fSopenharmony_ci (uint32_t)(item->timestamp[BOOTEVENT_READY].tv_nsec / USTONSEC)); 66d9f0492fSopenharmony_ci PLUGIN_CHECK(len > 0 && (((uint32_t)len + args->currLen) < args->bufferLen), return -1, 67d9f0492fSopenharmony_ci "Failed to format service time %s", item->paramName); 68d9f0492fSopenharmony_ci args->currLen += (uint32_t)len; 69d9f0492fSopenharmony_ci return 0; 70d9f0492fSopenharmony_ci} 71d9f0492fSopenharmony_ci 72d9f0492fSopenharmony_cistatic void InsertBootTimeParam(char *buffer, const char *name) 73d9f0492fSopenharmony_ci{ 74d9f0492fSopenharmony_ci char bufKernel[MAX_BUFFER_LEN] = {0}; 75d9f0492fSopenharmony_ci char buf[MAX_BUFFER_LEN] = {0}; 76d9f0492fSopenharmony_ci char bootName[MAX_BUFFER_LEN] = {0}; 77d9f0492fSopenharmony_ci uint32_t bufLen = MAX_BUFFER_LEN; 78d9f0492fSopenharmony_ci uint32_t kernelLen = MAX_BUFFER_LEN; 79d9f0492fSopenharmony_ci int len = sprintf_s(bootName, MAX_BUFFER_LEN, "ohos.boot.time.%s", name); 80d9f0492fSopenharmony_ci PLUGIN_CHECK(len > 0 && ((uint32_t)len < MAX_BUFFER_LEN), return, "Failed to format boot name "); 81d9f0492fSopenharmony_ci int ret = SystemReadParam(bootName, buf, &bufLen); 82d9f0492fSopenharmony_ci PLUGIN_CHECK(ret == 0, return, "Failed to read boot time "); 83d9f0492fSopenharmony_ci char time[MAX_BUFFER_LEN] = {0}; 84d9f0492fSopenharmony_ci if (strcmp(name, "kernel") == 0) { 85d9f0492fSopenharmony_ci len = sprintf_s(time, MAX_BUFFER_LEN, ";kernel,0,%s", buf); 86d9f0492fSopenharmony_ci } else { 87d9f0492fSopenharmony_ci int result = SystemReadParam("ohos.boot.time.kernel", bufKernel, &kernelLen); 88d9f0492fSopenharmony_ci if (result == 0) { 89d9f0492fSopenharmony_ci len = sprintf_s(time, MAX_BUFFER_LEN, ";init,%s,%s", bufKernel, buf); 90d9f0492fSopenharmony_ci } 91d9f0492fSopenharmony_ci } 92d9f0492fSopenharmony_ci PLUGIN_CHECK(len > 0 && ((uint32_t)len < MAX_BUFFER_LEN), return, "Failed to format boot time "); 93d9f0492fSopenharmony_ci ret = strcat_s(buffer, MAX_BUFFER_FOR_EVENT + PARAM_VALUE_LEN_MAX + MAX_BUFFER_LEN + 1, time); 94d9f0492fSopenharmony_ci PLUGIN_CHECK(ret == 0, return, "Failed to format boot time "); 95d9f0492fSopenharmony_ci} 96d9f0492fSopenharmony_ci 97d9f0492fSopenharmony_ciPLUGIN_STATIC void ReportBootEventComplete(ListNode *events) 98d9f0492fSopenharmony_ci{ 99d9f0492fSopenharmony_ci PLUGIN_CHECK(events != NULL, return, "Invalid events"); 100d9f0492fSopenharmony_ci struct timespec curr = {0}; 101d9f0492fSopenharmony_ci int ret = clock_gettime(CLOCK_MONOTONIC, &curr); 102d9f0492fSopenharmony_ci PLUGIN_CHECK(ret == 0, return); 103d9f0492fSopenharmony_ci 104d9f0492fSopenharmony_ci char *buffer = (char *)calloc(MAX_BUFFER_FOR_EVENT + PARAM_VALUE_LEN_MAX, 1); 105d9f0492fSopenharmony_ci PLUGIN_CHECK(buffer != NULL, return, "Failed to get memory for sys event "); 106d9f0492fSopenharmony_ci EventArgs args = { buffer, MAX_BUFFER_FOR_EVENT, 0 }; 107d9f0492fSopenharmony_ci OH_ListTraversal(events, (void *)&args, TraversalEvent, 0); 108d9f0492fSopenharmony_ci if ((args.currLen > 1) && (args.currLen < MAX_BUFFER_FOR_EVENT)) { 109d9f0492fSopenharmony_ci buffer[args.currLen - 1] = '\0'; 110d9f0492fSopenharmony_ci } 111d9f0492fSopenharmony_ci InsertBootTimeParam(buffer, "kernel"); 112d9f0492fSopenharmony_ci InsertBootTimeParam(buffer, "init"); 113d9f0492fSopenharmony_ci 114d9f0492fSopenharmony_ci StartupTimeEvent startupTime = {}; 115d9f0492fSopenharmony_ci startupTime.event.type = STARTUP_TIME; 116d9f0492fSopenharmony_ci startupTime.totalTime = curr.tv_sec; 117d9f0492fSopenharmony_ci startupTime.totalTime = startupTime.totalTime * MSECTONSEC; 118d9f0492fSopenharmony_ci startupTime.totalTime += curr.tv_nsec / USTONSEC; 119d9f0492fSopenharmony_ci startupTime.detailTime = buffer; 120d9f0492fSopenharmony_ci char *reason = buffer + MAX_BUFFER_FOR_EVENT; 121d9f0492fSopenharmony_ci uint32_t size = PARAM_VALUE_LEN_MAX; 122d9f0492fSopenharmony_ci ret = SystemReadParam("ohos.boot.bootreason", reason, &size); 123d9f0492fSopenharmony_ci if (ret == 0) { 124d9f0492fSopenharmony_ci startupTime.reason = reason; 125d9f0492fSopenharmony_ci startupTime.firstStart = 1; 126d9f0492fSopenharmony_ci } else { 127d9f0492fSopenharmony_ci startupTime.reason = ""; 128d9f0492fSopenharmony_ci startupTime.firstStart = 0; 129d9f0492fSopenharmony_ci } 130d9f0492fSopenharmony_ci PLUGIN_LOGI("SysEventInit %u.%u detailTime len %u '%s'", 131d9f0492fSopenharmony_ci (uint32_t)curr.tv_sec, (uint32_t)(curr.tv_nsec / USTONSEC), args.currLen, startupTime.detailTime); 132d9f0492fSopenharmony_ci ReportSysEvent(&startupTime.event); 133d9f0492fSopenharmony_ci free(buffer); 134d9f0492fSopenharmony_ci} 135d9f0492fSopenharmony_ci 136d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST // do not install 137d9f0492fSopenharmony_ciMODULE_CONSTRUCTOR(void) 138d9f0492fSopenharmony_ci{ 139d9f0492fSopenharmony_ci ReportBootEventComplete(GetBootEventList()); 140d9f0492fSopenharmony_ci} 141d9f0492fSopenharmony_ci#endif 142