提交 b40fcca3 编写于 作者: M Mupceet 提交者: Gitee

Merge branch 'master' of gitee.com:openharmony/startup_init_lite into initmusl1

Signed-off-by: NMupceet <laiguizhong@huawei.com>
......@@ -29,7 +29,7 @@
"config_policy",
"hilog_native",
"thirdparty_bounds_checking_function",
"samgr_standard",
"samgr",
"hiviewdfx_hilog_native",
"selinux",
"hiviewdfx",
......
......@@ -33,7 +33,7 @@ if (!defined(ohos_lite)) {
]
include_dirs = [
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include/",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy/include/",
".",
"//base/startup/init/services/include/param",
"//base/startup/init/interfaces/innerkits/include",
......
......@@ -63,6 +63,7 @@ if (defined(ohos_lite)) {
public_configs = [ ":exported_header_files" ]
deps = [
"//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
"//base/startup/init/services/modules/init_hook:inithook",
"//third_party/bounds_checking_function:libsec_shared",
"//third_party/mbedtls:mbedtls_shared",
]
......@@ -252,7 +253,7 @@ if (defined(ohos_lite)) {
"c_utils:utils",
"hilog_native:libhilog_base",
"ipc:ipc_core",
"samgr_standard:samgr_proxy",
"samgr:samgr_proxy",
]
public_configs = [ ":exported_header_files" ]
part_name = "init"
......
......@@ -338,6 +338,16 @@ int GetBlockDeviceByMountPoint(const char *mountPoint, const Fstab *fstab, char
return 0;
}
int GetBlockDeviceByName(const char *deviceName, const Fstab *fstab, char* miscDev, size_t size)
{
for (FstabItem *item = fstab->head; item != NULL; item = item->next) {
if (strstr(item->deviceName, deviceName) != NULL) {
BEGET_CHECK_RETURN_VALUE(strcpy_s(miscDev, size, item->deviceName) != 0, 0);
}
}
return -1;
}
static const struct MountFlags mountFlags[] = {
{ "noatime", MS_NOATIME },
{ "noexec", MS_NOEXEC },
......@@ -487,21 +497,114 @@ unsigned long GetMountFlags(char *mountFlag, char *fsSpecificData, size_t fsSpec
return flags;
}
int GetBlockDevicePath(const char *partName, char *path, int size)
int GetBlockDevicePath(const char *partName, char *path, size_t size)
{
char *fstabFile = GetFstabFile(path, size);
if (fstabFile == NULL) {
return -1;
}
Fstab *fstab = ReadFstabFromFile(fstabFile, false);
Fstab *fstab = LoadFstabFromCommandLine();
if (fstab == NULL) {
return -1;
BEGET_LOGI("fstab not found from cmdline, try to get it from file");
char *fstabFile = GetFstabFile(path, size);
BEGET_CHECK_RETURN_VALUE(fstabFile != NULL, -1);
fstab = ReadFstabFromFile(fstabFile, false);
}
BEGET_CHECK_RETURN_VALUE(fstab != NULL, -1);
int ret = GetBlockDeviceByMountPoint(partName, fstab, path, size);
BEGET_INFO_CHECK(ret == 0, ret = GetBlockDeviceByName(partName, fstab, path, size),
"mount point not found, try to get it by device name");
ReleaseFstab(fstab);
return ret;
}
#define OHOS_REQUIRED_MOUNT_PREFIX "ohos.required_mount."
/*
* Fstab includes block device node, mount point, file system type, MNT_ Flags and options.
* We separate them by spaces in fstab.required file, but the separator is '@' in CmdLine.
* The prefix "ohos.required_mount." is the flag of required fstab information in CmdLine.
* Format as shown below:
* <block device>@<mount point>@<fstype>@<mount options>@<fstab options>
* e.g.
* ohos.required_mount.system=/dev/block/xxx/by-name/system@/usr@ext4@ro,barrier=1@wait,required
*/
static int ParseRequiredMountInfo(const char *item, Fstab *fstab)
{
char mountOptions[MAX_BUFFER_LEN] = {};
char partName[NAME_SIZE] = {};
// Sanity checks
BEGET_CHECK(!(item == NULL || *item == '\0' || fstab == NULL), return -1);
char *p = NULL;
const char *q = item;
if ((p = strstr(item, "=")) != NULL) {
q = item + strlen(OHOS_REQUIRED_MOUNT_PREFIX); // Get partition name
BEGET_CHECK(!(q == NULL || *q == '\0' || (p - q) <= 0), return -1);
BEGET_ERROR_CHECK(strncpy_s(partName, NAME_SIZE -1, q, p - q) == EOK,
return -1, "Failed to copy required partition name");
p++; // skip '='
BEGET_ERROR_CHECK(strncpy_s(mountOptions, MAX_BUFFER_LEN -1, p, strlen(p)) == EOK,
return -1, "Failed to copy required mount info: %s", item);
}
BEGET_LOGV("Mount option of partition %s is [%s]", partName, mountOptions);
if (ParseFstabPerLine(mountOptions, fstab, false, "@") < 0) {
BEGET_LOGE("Failed to parse mount options of partition \' %s \', options: %s", partName, mountOptions);
return -1;
}
return 0;
}
Fstab* LoadFstabFromCommandLine(void)
{
Fstab *fstab = NULL;
char *cmdline = ReadFileData(BOOT_CMD_LINE);
bool isDone = false;
BEGET_ERROR_CHECK(cmdline != NULL, return NULL, "Read from \'/proc/cmdline\' failed, err = %d", errno);
TrimTail(cmdline, '\n');
BEGET_ERROR_CHECK((fstab = (Fstab *)calloc(1, sizeof(Fstab))) != NULL, return NULL,
"Allocate memory for FS table failed, err = %d", errno);
char *start = cmdline;
char *end = start + strlen(cmdline);
while (start < end) {
char *token = strstr(start, " ");
if (token == NULL) {
break;
}
// Startswith " "
if (token == start) {
start++;
continue;
}
*token = '\0';
if (strncmp(start, OHOS_REQUIRED_MOUNT_PREFIX,
strlen(OHOS_REQUIRED_MOUNT_PREFIX)) != 0) {
start = token + 1;
continue;
}
isDone = true;
if (ParseRequiredMountInfo(start, fstab) < 0) {
BEGET_LOGE("Failed to parse \' %s \'", start);
isDone = false;
break;
}
start = token + 1;
}
// handle last one
if (start < end) {
if (strncmp(start, OHOS_REQUIRED_MOUNT_PREFIX,
strlen(OHOS_REQUIRED_MOUNT_PREFIX)) == 0 &&
ParseRequiredMountInfo(start, fstab) < 0) {
BEGET_LOGE("Failed to parse \' %s \'", start);
isDone = false;
}
}
if (!isDone) {
ReleaseFstab(fstab);
fstab = NULL;
}
free(cmdline);
return fstab;
}
#ifdef __cplusplus
#if __cplusplus
}
......
......@@ -21,9 +21,11 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <linux/limits.h>
#include "beget_ext.h"
#include "fs_manager/fs_manager.h"
#include "init_utils.h"
#include "param/init_param.h"
#include "securec.h"
#ifdef __cplusplus
......@@ -35,6 +37,8 @@ extern "C" {
#define FS_MANAGER_BUFFER_SIZE 512
#define BLOCK_SIZE_BUFFER (64)
#define RESIZE_BUFFER_SIZE 1024
const off_t MISC_PARTITION_ACTIVE_SLOT_OFFSET = 1400;
const off_t MISC_PARTITION_ACTIVE_SLOT_SIZE = 4;
bool IsSupportedFilesystem(const char *fsType)
{
......@@ -285,6 +289,68 @@ static int Mount(const char *source, const char *target, const char *fsType,
return rc;
}
static int GetSlotInfoFromParameter(const char *slotInfoName)
{
char name[PARAM_NAME_LEN_MAX] = {0};
BEGET_ERROR_CHECK(sprintf_s(name, sizeof(name), "ohos.boot.%s", slotInfoName) > 0,
return -1, "Failed to format slot parameter name");
char value[PARAM_VALUE_LEN_MAX] = {0};
uint32_t valueLen = PARAM_VALUE_LEN_MAX;
return SystemGetParameter(name, value, &valueLen) == 0 ? atoi(value) : -1;
}
static int GetSlotInfoFromCmdLine(const char *slotInfoName)
{
char value[MAX_BUFFER_LEN] = {0};
char *buffer = ReadFileData(BOOT_CMD_LINE);
BEGET_ERROR_CHECK(buffer != NULL, return -1, "Failed to read cmdline");
BEGET_ERROR_CHECK(GetProcCmdlineValue(slotInfoName, buffer, value, MAX_BUFFER_LEN) == 0,
free(buffer); buffer = NULL; return -1, "Failed to get %s value from cmdline", slotInfoName);
free(buffer);
buffer = NULL;
return atoi(value);
}
static int GetSlotInfoFromMisc(off_t offset, off_t size)
{
char miscDev[MAX_BUFFER_LEN] = {0};
BEGET_ERROR_CHECK(GetBlockDevicePath("/misc", miscDev, MAX_BUFFER_LEN) == 0,
return -1, "Failed to get misc device");
int fd = open(miscDev, O_RDWR | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
BEGET_ERROR_CHECK(fd >= 0, return -1, "Failed to open misc device, errno %d", errno);
BEGET_ERROR_CHECK(lseek(fd, offset, SEEK_SET) >= 0, close(fd); return -1,
"Failed to lseek misc device fd, errno %d", errno);
int slotInfo = 0;
BEGET_ERROR_CHECK(read(fd, &slotInfo, size) == size, close(fd); return -1,
"Failed to read current slot from misc, errno %d", errno);
close(fd);
return slotInfo;
}
int GetBootSlots(void)
{
int bootSlots = GetSlotInfoFromParameter("bootslots");
BEGET_CHECK_RETURN_VALUE(bootSlots <= 0, bootSlots);
BEGET_LOGI("No valid slot value found from parameter, try to get it from cmdline");
return GetSlotInfoFromCmdLine("bootslots");
}
int GetCurrentSlot(void)
{
// get current slot from parameter
int currentSlot = GetSlotInfoFromParameter("currentslot");
BEGET_CHECK_RETURN_VALUE(currentSlot <= 0, currentSlot);
BEGET_LOGI("No valid slot value found from parameter, try to get it from cmdline");
// get current slot from cmdline
currentSlot = GetSlotInfoFromCmdLine("currentslot");
BEGET_CHECK_RETURN_VALUE(currentSlot <= 0, currentSlot);
BEGET_LOGI("No valid slot value found from cmdline, try to get it from misc");
// get current slot from misc
return GetSlotInfoFromMisc(MISC_PARTITION_ACTIVE_SLOT_OFFSET, MISC_PARTITION_ACTIVE_SLOT_SIZE);
}
int MountOneItem(FstabItem *item)
{
if (item == NULL) {
......@@ -333,6 +399,21 @@ int MountOneItem(FstabItem *item)
return rc;
}
static void AdjustPartitionNameByPartitionSlot(FstabItem *item)
{
BEGET_CHECK_ONLY_RETURN(strstr(item->deviceName, "/system") != NULL ||
strstr(item->deviceName, "/vendor") != NULL);
char buffer[MAX_BUFFER_LEN] = {0};
int slot = GetCurrentSlot();
BEGET_ERROR_CHECK(slot > 0 && slot <= MAX_SLOT, slot = 1, "slot value %d is invalid, set default value", slot);
BEGET_INFO_CHECK(slot > 1, return, "default partition doesn't need to add suffix");
BEGET_ERROR_CHECK(sprintf_s(buffer, sizeof(buffer), "%s_%c", item->deviceName, 'a' + slot - 1) > 0,
return, "Failed to format partition name suffix, use default partition name");
free(item->deviceName);
item->deviceName = strdup(buffer);
BEGET_LOGI("partition name with slot suffix: %s", item->deviceName);
}
static int CheckRequiredAndMount(FstabItem *item, bool required)
{
int rc = 0;
......@@ -341,6 +422,9 @@ static int CheckRequiredAndMount(FstabItem *item, bool required)
}
if (required) { // Mount partition during first startup.
if (FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) {
int bootSlots = GetBootSlots();
BEGET_INFO_CHECK(bootSlots <= 1, AdjustPartitionNameByPartitionSlot(item),
"boot slots is %d, now adjust partition name according to current slot", bootSlots);
rc = MountOneItem(item);
}
} else { // Mount partition during second startup.
......
......@@ -121,6 +121,7 @@ static int hookItemCompare(ListNode *node, ListNode *newNode)
struct HOOKITEM_COMPARE_VAL {
int prio;
OhosHook hook;
void *hookCookie;
};
static int hookItemCompareValue(ListNode *node, void *data)
......@@ -130,7 +131,9 @@ static int hookItemCompareValue(ListNode *node, void *data)
hookItem = (const HOOK_ITEM *)node;
BEGET_CHECK(hookItem->info.prio == compareVal->prio, return (hookItem->info.prio - compareVal->prio));
BEGET_CHECK(hookItem->info.hook != compareVal->hook, return 0);
if (hookItem->info.hook == compareVal->hook && hookItem->info.hookCookie == compareVal->hookCookie) {
return 0;
}
return -1;
}
......@@ -143,6 +146,7 @@ static int addHookToStage(HOOK_STAGE *hookStage, int prio, OhosHook hook, void *
// Check if exists
compareVal.prio = prio;
compareVal.hook = hook;
compareVal.hookCookie = hookCookie;
hookItem = (HOOK_ITEM *)OH_ListFind(&(hookStage->hooks), (void *)(&compareVal), hookItemCompareValue);
BEGET_CHECK(hookItem == NULL, return 0);
......
......@@ -29,6 +29,8 @@ extern "C" {
#define FS_MANAGER_CHECK 0x00000001
#define FS_MANAGER_WAIT 0x00000002
#define FS_MANAGER_REQUIRED 0x00000004
#define NAME_SIZE 32
#define MAX_SLOT 2
#define VALID_FS_MANAGER_FLAGS (FS_MANAGER_CHECK | FS_MANAGER_WAIT | FS_MANAGER_REQUIRED)
#define FS_MANAGER_FLAGS_ENABLED(fsMgrFlags, flag) (((fsMgrFlags) & FS_MANAGER_##flag) != 0)
......@@ -56,6 +58,21 @@ typedef struct {
struct FstabItem *head;
} Fstab;
typedef enum SlotFlag {
UNBOOT = 0,
ACTIVE = 1,
} SlotFlag;
typedef struct SlotInfo {
int slotName;
char *slotSuffix;
SlotFlag slotFlag;
unsigned int retryCount;
unsigned int reserved;
} SlotInfo;
Fstab* LoadFstabFromCommandLine(void);
int GetSlotInfo(void);
void ReleaseFstab(Fstab *fstab);
Fstab *ReadFstabFromFile(const char *file, bool procMounts);
FstabItem *FindFstabItemForPath(Fstab fstab, const char *path);
......@@ -63,6 +80,7 @@ FstabItem* FindFstabItemForMountPoint(Fstab fstab, const char *mp);
int ParseFstabPerLine(char *str, Fstab *fstab, bool procMounts, const char *separator);
int GetBlockDeviceByMountPoint(const char *mountPoint, const Fstab *fstab, char *deviceName, int nameLen);
int GetBlockDeviceByName(const char *deviceName, const Fstab *fstab, char* miscDev, size_t size);
bool IsSupportedFilesystem(const char *fsType);
int DoFormat(const char *devPath, const char *fsType);
int MountOneItem(FstabItem *item);
......@@ -73,7 +91,7 @@ int UmountAllWithFstabFile(const char *file);
unsigned long GetMountFlags(char *mountFlag, char *fsSpecificFlags, size_t fsSpecificFlagSize,
const char *mountPoint);
int GetBlockDevicePath(const char *partName, char *path, int size);
int GetBlockDevicePath(const char *partName, char *path, size_t size);
// Get fscrypt policy if exist
int LoadFscryptPolicy(char *buf, size_t size);
......
......@@ -32,7 +32,13 @@ enum INIT_BOOTSTAGE {
INIT_PRE_CFG_LOAD = 30,
INIT_SERVICE_PARSE = 35,
INIT_POST_PERSIST_PARAM_LOAD = 40,
INIT_POST_CFG_LOAD = 50
INIT_POST_CFG_LOAD = 50,
INIT_REBOOT = 55,
INIT_SERVICE_CLEAR = 56,
INIT_SERVICE_DUMP = 57,
INIT_SERVICE_FORK_BEFORE = 58,
INIT_SERVICE_SET_PERMS = 59,
INIT_JOB_PARSE = 70,
};
HOOK_MGR *GetBootStageHookMgr();
......@@ -75,6 +81,22 @@ typedef struct tagSERVICE_PARSE_CTX {
const cJSON *serviceNode; /* Service JSON node */
} SERVICE_PARSE_CTX;
/**
* @brief job config parsing context information
*/
typedef struct tagJOB_PARSE_CTX {
const char *jobName; /* job name */
const cJSON *jobNode; /* job JSON node */
} JOB_PARSE_CTX;
/**
* @brief service info
*/
typedef struct tagSERVICE_INFO_CTX {
const char *serviceName; /* Service name */
const char *reserved; /* reserved info */
} SERVICE_INFO_CTX;
/**
* @brief service config parse hook function prototype
*
......@@ -83,6 +105,22 @@ typedef struct tagSERVICE_PARSE_CTX {
*/
typedef void (*ServiceParseHook)(SERVICE_PARSE_CTX *serviceParseCtx);
/**
* @brief job config parse hook function prototype
*
* @param JobParseHook job config parsing context information
* @return None
*/
typedef void (*JobParseHook)(JOB_PARSE_CTX *jobParseCtx);
/**
* @brief service hook function prototype
*
* @param ServiceHook service info
* @return None
*/
typedef void (*ServiceHook)(SERVICE_INFO_CTX *serviceCtx);
/**
* @brief Register a hook for service config parsing
*
......@@ -92,6 +130,50 @@ typedef void (*ServiceParseHook)(SERVICE_PARSE_CTX *serviceParseCtx);
*/
int InitAddServiceParseHook(ServiceParseHook hook);
/**
* @brief service config parsing context information
*/
typedef struct tagReboot {
char *reason;
} RebootHookCtx;
/**
* @brief service config parse hook function prototype
*
* @param serviceParseCtx service config parsing context information
* @return None
*/
typedef void (*InitRebootHook)(RebootHookCtx *ctx);
/**
* @brief Register a hook for reboot
*
* @param hook
*
* @return return 0 if succeed; other values if failed.
*/
int InitAddRebootHook(InitRebootHook hook);
/**
* @brief Register a hook for job config parsing
*
* @param hook job config parsing hook
* in the hook, we can parse extra fields in the config file.
* @return return 0 if succeed; other values if failed.
*/
int InitAddJobParseHook(JobParseHook hook);
/**
* @brief Register a hook for service
*
* @param hook service hook
* in the hook, we can get service.
* @param hookState init boot state
* @return return 0 if succeed; other values if failed.
*/
int InitAddServiceHook(ServiceHook hook, int hookState);
int InitAddClearServiceHook(ServiceHook hook);
#ifdef __cplusplus
#if __cplusplus
}
......
......@@ -42,6 +42,7 @@ int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd);
void RemoveCmdExecutor(const char *cmdName, int id);
int DoJobNow(const char *jobName);
#ifdef __cplusplus
#if __cplusplus
}
......
......@@ -13,5 +13,7 @@
{ "name": "InitAddPostCfgLoadHook" },
{ "name": "InitModuleMgrInstall" },
{ "name": "InitModuleMgrUnInstall" },
{ "name": "StartupLog" }
{ "name": "StartupLog" },
{ "name": "DoJobNow" },
{ "name": "GetServiceExtData" }
]
......@@ -120,6 +120,14 @@ if (defined(ohos_lite)) {
"sandbox",
"dump_service",
]
if (product_name == "rk3568") {
sources += [ "partitionslot.cpp" ]
external_deps +=
[ "drivers_peripheral_partitionslot:libpartition_slot_manager" ]
symlink_target_name += [ "partitionslot" ]
}
install_images = [ "system" ]
install_enable = true
part_name = "init"
......
......@@ -17,29 +17,46 @@
#include <string.h>
#include "begetctl.h"
#include "beget_ext.h"
#include "control_fd.h"
#include "securec.h"
#include "init_param.h"
#define DUMP_SERVICE_INFO_CMD_ARGS 2
#define DUMP_SERVICE_BOOTEVENT_CMD_ARGS 3
static int main_cmd(BShellHandle shell, int argc, char **argv)
{
if (argc != DUMP_SERVICE_INFO_CMD_ARGS) {
BShellCmdHelp(shell, argc, argv);
return 0;
}
if (strcmp(argv[0], "dump_service") == 0) {
if (argc == DUMP_SERVICE_INFO_CMD_ARGS) {
printf("dump service info \n");
CmdClientInit(INIT_CONTROL_FD_SOCKET_PATH, ACTION_DUMP, argv[1]);
} else if (argc == DUMP_SERVICE_BOOTEVENT_CMD_ARGS) {
printf("dump service bootevent info \n");
int serviceNameLen = strlen(argv[1]) + strlen(argv[2]) + 2; // 2 is \0 and #
char *serviceBootevent = (char *)calloc(1, serviceNameLen);
BEGET_ERROR_CHECK(sprintf_s(serviceBootevent, serviceNameLen, "%s#%s", argv[1], argv[2]) >= 0,
return 0, "dumpservice arg create failed");
CmdClientInit(INIT_CONTROL_FD_SOCKET_PATH, ACTION_DUMP, serviceBootevent);
free(serviceBootevent);
} else {
BShellCmdHelp(shell, argc, argv);
}
return 0;
}
static int ClearBootEvent(BShellHandle shell, int argc, char **argv)
{
return SystemSetParameter("ohos.servicectrl.clear", "bootevent");
}
MODULE_CONSTRUCTOR(void)
{
const CmdInfo infos[] = {
{"dump_service", main_cmd, "dump one service info by serviceName", "dump_service serviceName", NULL},
{"dump_service", main_cmd, "dump one service bootevent", "dump_service serviceName bootevent", NULL},
{"dump_service", main_cmd, "dump all services info", "dump_service all", NULL},
{"dump_service", main_cmd, "dump all services bootevent", "dump_service all bootevent", NULL},
{"service", ClearBootEvent, "Clear all services bootevent", "service clear bootevent",
"service clear bootevent"},
};
for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
BShellEnvRegitsterCmd(GetShellHandle(), &infos[i]);
......
......@@ -359,7 +359,6 @@ static int32_t BShellParamCmdDump(BShellHandle shell, int32_t argc, char *argv[]
{
BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
if (argc >= 2 && strcmp(argv[1], "verbose") == 0) { // 2 min arg
SystemSetParameter("ohos.servicectrl.display", "system");
SystemDumpParameters(1);
} else {
SystemDumpParameters(0);
......
/*
* 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.
*/
#include <iostream>
#include "begetctl.h"
#include "partitionslot_manager.h"
using namespace OHOS::HDI::Partitionslot::V1_0;
const int32_t PARTITION_ARGC = 2;
static int GetSlot(BShellHandle handle, int32_t argc, char *argv[])
{
std::cout << "Command: partitionslot getslot" << std::endl;
int bootSlots = 0;
int currentSlot = PartitionSlotManager::GetInstance()->GetCurrentSlot(bootSlots);
std::cout << "The number of slots: " << bootSlots << "," << "current slot: " << currentSlot << std::endl;
return 0;
}
static int GetSuffix(BShellHandle handle, int32_t argc, char *argv[])
{
if (argc != PARTITION_ARGC) {
BShellCmdHelp(handle, argc, argv);
return 0;
}
std::cout << "Command: partitionslot getsuffix" << std::endl;
int slot = atoi(argv[1]);
std::string suffix = "";
PartitionSlotManager::GetInstance()->GetSlotSuffix(slot, suffix);
std::cout << "The slot " << slot << " matches with suffix: " << suffix << std::endl;
return 0;
}
static int SetActiveSlot(BShellHandle handle, int32_t argc, char *argv[])
{
if (argc != PARTITION_ARGC) {
BShellCmdHelp(handle, argc, argv);
return 0;
}
std::cout << "Command: partitionslot setactive" << std::endl;
int slot = atoi(argv[1]);
PartitionSlotManager::GetInstance()->SetActiveSlot(slot);
std::cout << "Set active slot: " << slot << std::endl;
return 0;
}
static int SetUnbootSlot(BShellHandle handle, int32_t argc, char *argv[])
{
if (argc != PARTITION_ARGC) {
BShellCmdHelp(handle, argc, argv);
return 0;
}
std::cout << "Command: partitionslot setunboot" << std::endl;
int slot = atoi(argv[1]);
PartitionSlotManager::GetInstance()->SetSlotUnbootable(slot);
std::cout << "Set unboot slot: " << slot << std::endl;
return 0;
}
MODULE_CONSTRUCTOR(void)
{
CmdInfo infos[] = {
{
(char *)"partitionslot", GetSlot, (char *)"get the number of slots and current slot",
(char *)"partitionslot getslot", (char *)"partitionslot getslot"
},
{
(char *)"partitionslot", GetSuffix, (char *)"get suffix that matches with the slot",
(char *)"partitionslot getsuffix [slot]", (char *)"partitionslot getsuffix"
},
{
(char *)"partitionslot", SetActiveSlot, (char *)"set active slot",
(char *)"partitionslot setactive [slot]", (char *)"partitionslot setactive"
},
{
(char *)"partitionslot", SetUnbootSlot, (char *)"set unboot slot",
(char *)"partitionslot setunboot [slot]", (char *)"partitionslot setunboot"
}
};
for (size_t i = sizeof(infos) / sizeof(infos[0]); i > 0; i--) {
BShellEnvRegitsterCmd(GetShellHandle(), &infos[i - 1]);
}
}
......@@ -76,6 +76,7 @@ daudio:x:3055:
dhardware:x:3056:
installs:x:3060:
vendor_mpp_driver:x:3061:
device_manager:x:3062:
deviceauth:x:3333:
huks_server:x:3510:
dms:x:5522:
......
......@@ -30,7 +30,7 @@ const.build.product=default
const.product.hardwareversion=default
const.product.bootloader.version=bootloader
const.product.cpu.abilist=default
const.product.software.version=OpenHarmony 3.2.6.1
const.product.software.version=OpenHarmony 3.2.6.2
const.product.incremental.version=default
const.product.firstapiversion=1
const.product.build.type=default
......
......@@ -73,6 +73,7 @@ daudio:x:3055:3055:::/bin/false
dhardware:x:3056:3056:::/bin/false
installs:x:3060:3060:::/bin/false
vendor_mpp_driver:x:3061:3061:::/bin/false
device_manager:x:3062:3062:::/bin/false
deviceauth:x:3333:3333:::/bin/false
huks_server:x:3510:3510:::/bin/false
dms:x:5522:5522:::/bin/false
......
......@@ -155,8 +155,11 @@ typedef struct Service_ {
TimerHandle timer;
ServiceJobs serviceJobs;
cpu_set_t cpuSet;
struct ListNode extDataNode;
} Service;
Service *GetServiceByPid(pid_t pid);
Service *GetServiceByName(const char *servName);
int ServiceStart(Service *service);
int ServiceStop(Service *service);
void ServiceReap(Service *service);
......
......@@ -49,8 +49,6 @@ typedef struct {
int serviceCount;
} ServiceSpace;
Service *GetServiceByPid(pid_t pid);
Service *GetServiceByName(const char *servName);
cJSON *GetArrayItem(const cJSON *fileRoot, int *arrSize, const char *arrName);
int ParseOneService(const cJSON *curItem, Service *service);
......@@ -63,8 +61,8 @@ void ReleaseService(Service *service);
void StartAllServices(int startMode);
void LoadAccessTokenId(void);
Service *AddService(const char *name);
void DumpAllServices(void);
void DumpOneService(const Service *service);
void DumpServiceHookExecute(const char *name, const char *info);
void ProcessControlFd(uint16_t type, const char *serviceCmd, const void *context);
#ifdef __cplusplus
#if __cplusplus
}
......
......@@ -43,6 +43,11 @@
#include "securec.h"
#include "service_control.h"
#ifndef OHOS_LITE
#include "hookmgr.h"
#include "bootstage.h"
#endif
#ifdef WITH_SELINUX
#include "init_selinux_param.h"
#include <selinux/selinux.h>
......@@ -82,6 +87,45 @@ static int SetSystemSeccompPolicy(const Service *service)
}
#endif
#ifndef OHOS_LITE
/**
* service Hooking
*/
static int ServiceHookWrapper(const HOOK_INFO *hookInfo, void *executionContext)
{
SERVICE_INFO_CTX *serviceContext = (SERVICE_INFO_CTX *)executionContext;
ServiceHook realHook = (ServiceHook)hookInfo->hookCookie;
realHook(serviceContext);
return 0;
};
int InitAddServiceHook(ServiceHook hook, int hookState)
{
HOOK_INFO info;
info.stage = hookState;
info.prio = 0;
info.hook = ServiceHookWrapper;
info.hookCookie = (void *)hook;
return HookMgrAddEx(GetBootStageHookMgr(), &info);
}
/**
* service hooking execute
*/
static void ServiceHookExecute(const char *serviceName, const char *info, int stage)
{
SERVICE_INFO_CTX context;
context.serviceName = serviceName;
context.reserved = info;
(void)HookMgrExecute(GetBootStageHookMgr(), stage, (void *)(&context), NULL);
}
#endif
static int SetPerms(const Service *service)
{
INIT_CHECK_RETURN_VALUE(KeepCapability() == 0, SERVICE_FAILURE);
......@@ -134,6 +178,12 @@ static int SetPerms(const Service *service)
INIT_ERROR_CHECK(SetAmbientCapability(service->servPerm.caps[i]) == 0, return SERVICE_FAILURE,
"SetAmbientCapability failed for service: %s", service->name);
}
#ifndef OHOS_LITE
/*
* service set Perms hooks
*/
ServiceHookExecute(service->name, NULL, INIT_SERVICE_SET_PERMS);
#endif
return SERVICE_SUCCESS;
}
......@@ -344,6 +394,12 @@ int ServiceStart(Service *service)
INIT_LOGE("start service %s invalid, please check %s.", service->name, service->pathArgs.argv[0]);
return SERVICE_FAILURE;
}
#ifndef OHOS_LITE
/*
* before service fork hooks
*/
ServiceHookExecute(service->name, NULL, INIT_SERVICE_FORK_BEFORE);
#endif
int pid = fork();
if (pid == 0) {
// fail must exit sub process
......@@ -388,6 +444,7 @@ int ServiceStop(Service *service)
NotifyServiceChange(service, SERVICE_STOPPING);
INIT_LOGI("stop service %s, pid %d.", service->name, service->pid);
service->pid = -1;
NotifyServiceChange(service, SERVICE_STOPPED);
return SERVICE_SUCCESS;
}
......
......@@ -51,104 +51,6 @@ static const int CRITICAL_DEFAULT_CRASH_TIME = 20;
static const int CRITICAL_DEFAULT_CRASH_COUNT = 4;
static const int CRITICAL_CONFIG_ARRAY_LEN = 3;
static void DumpServiceArgs(const char *info, const ServiceArgs *args)
{
printf("\tservice %s count %d \n", info, args->count);
for (int j = 0; j < args->count; j++) {
if (args->argv[j] != NULL) {
printf("\t\tinfo [%d] %s \n", j, args->argv[j]);
}
}
}
static void DumpServiceJobs(const Service *service)
{
printf("\tservice job info \n");
if (service->serviceJobs.jobsName[JOB_ON_BOOT] != NULL) {
printf("\t\tservice boot job %s \n", service->serviceJobs.jobsName[JOB_ON_BOOT]);
}
if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
printf("\t\tservice start job %s \n", service->serviceJobs.jobsName[JOB_ON_START]);
}
if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
printf("\t\tservice stop job %s \n", service->serviceJobs.jobsName[JOB_ON_STOP]);
}
if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
printf("\t\tservice restart job %s \n", service->serviceJobs.jobsName[JOB_ON_RESTART]);
}
}
static void DumpServiceSocket(const Service *service)
{
printf("\tservice socket info \n");
ServiceSocket *sockopt = service->socketCfg;
while (sockopt != NULL) {
printf("\t\tsocket name: %s \n", sockopt->name);
printf("\t\tsocket type: %u \n", sockopt->type);
printf("\t\tsocket uid: %u \n", sockopt->uid);
printf("\t\tsocket gid: %u \n", sockopt->gid);
sockopt = sockopt->next;
}
}
void DumpOneService(const Service *service)
{
const InitArgInfo startModeMap[] = {
{"condition", START_MODE_CONDITION},
{"boot", START_MODE_BOOT},
{"normal", START_MODE_NORMAL}
};
const static char *serviceStatusMap[] = {
"created", "starting", "running", "ready",
"stopping", "stopped", "suspended", "freezed", "disabled", "critical"
};
printf("\tservice name: [%s] \n", service->name);
#ifdef WITH_SELINUX
if (service->secon != NULL) {
printf("\tservice secon: [%s] \n", service->secon);
}
#endif
printf("\tservice pid: [%d] \n", service->pid);
printf("\tservice crashCnt: [%d] \n", service->crashCnt);
printf("\tservice attribute: [%u] \n", service->attribute);
printf("\tservice importance: [%d] \n", service->importance);
printf("\tservice startMode: [%s] \n", startModeMap[service->startMode].name);
printf("\tservice status: [%s] \n", serviceStatusMap[service->status]);
printf("\tservice perms uID [%u] \n", service->servPerm.uID);
DumpServiceArgs("path arg", &service->pathArgs);
DumpServiceArgs("writepid file", &service->writePidArgs);
DumpServiceJobs(service);
DumpServiceSocket(service);
printf("\tservice perms groupId %d \n", service->servPerm.gIDCnt);
for (int i = 0; i < service->servPerm.gIDCnt; i++) {
printf("\t\tservice perms groupId %u \n", service->servPerm.gIDArray[i]);
}
printf("\tservice perms capability %u \n", service->servPerm.capsCnt);
for (int i = 0; i < (int)service->servPerm.capsCnt; i++) {
printf("\t\tservice perms capability %u \n", service->servPerm.caps[i]);
}
}
void DumpAllServices(void)
{
printf("Ready to dump all services: \n");
printf("total service number: %d \n", g_serviceSpace.serviceCount);
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
while (node != NULL) {
if (node->data.service == NULL) {
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
continue;
}
Service *service = node->data.service;
DumpOneService(service);
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
}
printf("Dump all services finished \n");
}
static void FreeServiceArg(ServiceArgs *arg)
{
if (arg == NULL) {
......@@ -197,6 +99,7 @@ Service *AddService(const char *name)
service->name = node->name;
service->status = SERVICE_IDLE;
CPU_ZERO(&service->cpuSet);
OH_ListInit(&service->extDataNode);
g_serviceSpace.serviceCount++;
INIT_LOGV("AddService %s", node->name);
return service;
......@@ -246,6 +149,12 @@ void ReleaseService(Service *service)
FreeServiceSocket(service->socketCfg);
FreeServiceFile(service->fileCfg);
#ifndef OHOS_LITE
// clear ext data
SERVICE_INFO_CTX ctx = {0};
ctx.serviceName = service->name;
HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)&ctx, NULL);
#endif
g_serviceSpace.serviceCount--;
InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_SERVICES, service->name);
if (groupNode != NULL) {
......
......@@ -60,6 +60,7 @@ executable("init") {
"//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
"//base/startup/init/services/log:init_log",
"//base/startup/init/services/loopevent:loopevent",
"//base/startup/init/services/modules/init_hook:inithook",
"//base/startup/init/services/param/base:parameterbase",
"//base/startup/init/services/utils:libinit_utils",
"//build/lite/config/component/cJSON:cjson_static",
......
......@@ -274,24 +274,10 @@ static void BootStateChange(const char *content)
}
if (strcmp("post-init", content) == 0) {
StartAllServices(START_MODE_NORMAL);
// Destroy all hooks
HookMgrDestroy(bootStageHookMgr);
bootStageHookMgr = NULL;
return;
}
}
#if defined(OHOS_SERVICE_DUMP)
static int SystemDump(int id, const char *name, int argc, const char **argv)
{
INIT_ERROR_CHECK(argv != NULL && argc >= 1, return 0, "Invalid install parameter");
INIT_LOGI("Dump system info %s", argv[0]);
SystemDumpParameters(1);
SystemDumpTriggers(1);
return 0;
}
#endif
static void IsEnableSandbox(void)
{
const char *name = "const.sandbox";
......@@ -390,11 +376,6 @@ void SystemConfig(void)
INIT_LOGI("Parse init config file done.");
HookMgrExecute(GetBootStageHookMgr(), INIT_POST_CFG_LOAD, (void *)&timingStat, (void *)&options);
// dump config
#if defined(OHOS_SERVICE_DUMP)
AddCmdExecutor("display", SystemDump);
(void)AddCompleteJob("param:ohos.servicectrl.display", "ohos.servicectrl.display=*", "display system");
#endif
IsEnableSandbox();
// execute init
PostTrigger(EVENT_TRIGGER_BOOT, "pre-init", strlen("pre-init"));
......
......@@ -24,6 +24,134 @@
#include "init_modulemgr.h"
#include "init_utils.h"
#include "init_log.h"
#include "init_group_manager.h"
#include "hookmgr.h"
#include "bootstage.h"
static void DumpServiceArgs(const char *info, const ServiceArgs *args)
{
printf("\tservice %s count %d \n", info, args->count);
for (int j = 0; j < args->count; j++) {
if (args->argv[j] != NULL) {
printf("\t\tinfo [%d] %s \n", j, args->argv[j]);
}
}
}
static void DumpServiceJobs(const Service *service)
{
printf("\tservice job info \n");
if (service->serviceJobs.jobsName[JOB_ON_BOOT] != NULL) {
printf("\t\tservice boot job %s \n", service->serviceJobs.jobsName[JOB_ON_BOOT]);
}
if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
printf("\t\tservice start job %s \n", service->serviceJobs.jobsName[JOB_ON_START]);
}
if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
printf("\t\tservice stop job %s \n", service->serviceJobs.jobsName[JOB_ON_STOP]);
}
if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
printf("\t\tservice restart job %s \n", service->serviceJobs.jobsName[JOB_ON_RESTART]);
}
}
static void DumpServiceSocket(const Service *service)
{
printf("\tservice socket info \n");
ServiceSocket *sockopt = service->socketCfg;
while (sockopt != NULL) {
printf("\t\tsocket name: %s \n", sockopt->name);
printf("\t\tsocket type: %u \n", sockopt->type);
printf("\t\tsocket uid: %u \n", sockopt->uid);
printf("\t\tsocket gid: %u \n", sockopt->gid);
sockopt = sockopt->next;
}
}
void DumpServiceHookExecute(const char *name, const char *info)
{
SERVICE_INFO_CTX context;
context.serviceName = name;
context.reserved = info;
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&context), NULL);
}
static void DumpOneService(const Service *service)
{
const InitArgInfo startModeMap[] = {
{"condition", START_MODE_CONDITION},
{"boot", START_MODE_BOOT},
{"normal", START_MODE_NORMAL}
};
const static char *serviceStatusMap[] = {
"created", "starting", "running", "ready",
"stopping", "stopped", "suspended", "freezed", "disabled", "critical"
};
printf("\tservice name: [%s] \n", service->name);
printf("\tservice pid: [%d] \n", service->pid);
printf("\tservice crashCnt: [%d] \n", service->crashCnt);
printf("\tservice attribute: [%u] \n", service->attribute);
printf("\tservice importance: [%d] \n", service->importance);
printf("\tservice startMode: [%s] \n", startModeMap[service->startMode].name);
printf("\tservice status: [%s] \n", serviceStatusMap[service->status]);
printf("\tservice perms uID [%u] \n", service->servPerm.uID);
DumpServiceArgs("path arg", &service->pathArgs);
DumpServiceArgs("writepid file", &service->writePidArgs);
DumpServiceJobs(service);
DumpServiceSocket(service);
printf("\tservice perms groupId %d \n", service->servPerm.gIDCnt);
for (int i = 0; i < service->servPerm.gIDCnt; i++) {
printf("\t\tservice perms groupId %u \n", service->servPerm.gIDArray[i]);
}
printf("\tservice perms capability %u \n", service->servPerm.capsCnt);
for (int i = 0; i < (int)service->servPerm.capsCnt; i++) {
printf("\t\tservice perms capability %u \n", service->servPerm.caps[i]);
}
DumpServiceHookExecute(service->name, NULL);
}
static void PrintBootEventHead(const char *cmd)
{
if (strcmp(cmd, "bootevent") == 0) {
printf("\t%-20.20s\t%-50s\t%-20.20s\t%-20.20s\n",
"service-name", "bootevent-name", "fork", "ready");
}
return;
}
static void DumpAllExtData(const char *cmd)
{
PrintBootEventHead(cmd);
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
while (node != NULL) {
if (node->data.service == NULL) {
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
continue;
}
DumpServiceHookExecute(node->name, cmd);
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
}
}
static void DumpAllServices(void)
{
printf("Ready to dump all services: \n");
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
while (node != NULL) {
if (node->data.service == NULL) {
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
continue;
}
Service *service = node->data.service;
DumpOneService(service);
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
}
printf("Dump all services finished \n");
}
static void ProcessSandboxControlFd(uint16_t type, const char *serviceCmd)
{
......@@ -45,12 +173,28 @@ static void ProcessDumpServiceControlFd(uint16_t type, const char *serviceCmd)
if ((type != ACTION_DUMP) || (serviceCmd == NULL)) {
return;
}
Service *service = GetServiceByName(serviceCmd);
char *cmd = strrchr(serviceCmd, '#');
if (cmd != NULL) {
cmd[0] = '\0';
cmd++;
}
if (service == NULL) {
DumpAllServices();
} else {
DumpOneService(service);
if (strcmp(serviceCmd, "all") == 0) {
if (cmd != NULL) {
DumpAllExtData(cmd);
} else {
DumpAllServices();
}
return;
}
Service *service = GetServiceByName(serviceCmd);
if (service != NULL) {
if (cmd != NULL) {
PrintBootEventHead(cmd);
DumpServiceHookExecute(serviceCmd, cmd);
} else {
DumpOneService(service);
}
}
return;
}
......
......@@ -32,98 +32,6 @@ int MountRequriedPartitions(const Fstab *fstab)
return rc;
}
#define OHOS_REQUIRED_MOUNT_PREFIX "ohos.required_mount."
/*
* Fstab includes block device node, mount point, file system type, MNT_ Flags and options.
* We separate them by spaces in fstab.required file, but the separator is '@' in CmdLine.
* The prefix "ohos.required_mount." is the flag of required fstab information in CmdLine.
* Format as shown below:
* <block device>@<mount point>@<fstype>@<mount options>@<fstab options>
* e.g.
* ohos.required_mount.system=/dev/block/xxx/by-name/system@/usr@ext4@ro,barrier=1@wait,required
*/
static int ParseRequiredMountInfo(const char *item, Fstab *fstab)
{
char mountOptions[MAX_BUFFER_LEN] = {};
char partName[PARTITION_NAME_SIZE] = {};
// Sanity checks
INIT_CHECK(!(item == NULL || *item == '\0' || fstab == NULL), return -1);
char *p = NULL;
const char *q = item;
if ((p = strstr(item, "=")) != NULL) {
q = item + strlen(OHOS_REQUIRED_MOUNT_PREFIX); // Get partition name
INIT_CHECK(!(q == NULL || *q == '\0' || (p - q) <= 0), return -1);
INIT_ERROR_CHECK(strncpy_s(partName, PARTITION_NAME_SIZE -1, q, p - q) == EOK,
return -1, "Failed to copy required partition name");
p++; // skip '='
INIT_ERROR_CHECK(strncpy_s(mountOptions, MAX_BUFFER_LEN -1, p, strlen(p)) == EOK,
return -1, "Failed to copy required mount info: %s", item);
}
INIT_LOGV("Mount option of partition %s is [%s]", partName, mountOptions);
if (ParseFstabPerLine(mountOptions, fstab, false, "@") < 0) {
INIT_LOGE("Failed to parse mount options of partition \' %s \', options: %s", partName, mountOptions);
return -1;
}
return 0;
}
static Fstab* LoadFstabFromCommandLine(void)
{
Fstab *fstab = NULL;
char *cmdline = ReadFileData(BOOT_CMD_LINE);
bool isDone = false;
INIT_ERROR_CHECK(cmdline != NULL, return NULL, "Read from \'/proc/cmdline\' failed, err = %d", errno);
TrimTail(cmdline, '\n');
INIT_ERROR_CHECK((fstab = (Fstab *)calloc(1, sizeof(Fstab))) != NULL, return NULL,
"Allocate memory for FS table failed, err = %d", errno);
char *start = cmdline;
char *end = start + strlen(cmdline);
while (start < end) {
char *token = strstr(start, " ");
if (token == NULL) {
break;
}
// Startswith " "
if (token == start) {
start++;
continue;
}
*token = '\0';
if (strncmp(start, OHOS_REQUIRED_MOUNT_PREFIX,
strlen(OHOS_REQUIRED_MOUNT_PREFIX)) != 0) {
start = token + 1;
continue;
}
isDone = true;
if (ParseRequiredMountInfo(start, fstab) < 0) {
INIT_LOGE("Failed to parse \' %s \'", start);
isDone = false;
break;
}
start = token + 1;
}
// handle last one
if (start < end) {
if (strncmp(start, OHOS_REQUIRED_MOUNT_PREFIX,
strlen(OHOS_REQUIRED_MOUNT_PREFIX)) == 0 &&
ParseRequiredMountInfo(start, fstab) < 0) {
INIT_LOGE("Failed to parse \' %s \'", start);
isDone = false;
}
}
if (!isDone) {
ReleaseFstab(fstab);
fstab = NULL;
}
free(cmdline);
return fstab;
}
Fstab* LoadRequiredFstab(void)
{
Fstab *fstab = NULL;
......
......@@ -23,7 +23,6 @@
extern "C" {
#endif
#endif
#define PARTITION_NAME_SIZE 32
Fstab* LoadRequiredFstab(void);
int MountRequriedPartitions(const Fstab *fstab);
#ifdef __cplusplus
......
......@@ -36,12 +36,14 @@
#endif
#define MAX_VALUE_LENGTH 500
#define MAX_COMMAND_SIZE 20
#define MAX_UPDATE_SIZE 100
#define MAX_COMMAND_SIZE 32
#define MAX_UPDATE_SIZE 1280
#define MAX_RESERVED_SIZE 736
struct RBMiscUpdateMessage {
char command[MAX_COMMAND_SIZE];
char update[MAX_UPDATE_SIZE];
char reserved[MAX_RESERVED_SIZE];
};
static int RBMiscWriteUpdaterMessage(const char *path, const struct RBMiscUpdateMessage *boot)
......
# Copyright (c) 2020-2021 Huawei Device Co., Ltd.
# Copyright (c) 2020-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
......@@ -11,56 +11,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.
if (!defined(ohos_lite)) {
import("//base/startup/init/begetd.gni")
import("//build/ohos.gni")
ohos_shared_library("bootchart") {
sources = [ "bootchart/bootchart.c" ]
include_dirs = [
".",
"//base/startup/init/services/include/param",
]
deps = [
"//base/startup/init/interfaces/innerkits:libbegetutil",
"//third_party/bounds_checking_function:libsec_shared",
"//third_party/cJSON:cjson_static",
]
external_deps = [ "init:libinit_module_engine" ]
part_name = "init"
if (target_cpu == "arm64") {
module_install_dir = "lib64/init"
} else {
module_install_dir = "lib/init"
}
}
config("libbootchart_static_config") {
include_dirs = [ "." ]
}
ohos_source_set("libbootchart_static") {
sources = [ "bootchart/bootchart_static.c" ]
public_configs = [ ":libbootchart_static_config" ]
public_configs += [ "//base/startup/init/interfaces/innerkits/init_module_engine:init_module_engine_exported_config" ]
}
}
group("static_modules") {
if (!defined(ohos_lite)) {
deps = [
":libbootchart_static",
"bootchart:libbootchart_static",
"bootevent:libbootevent_static",
"init_hook:inithook",
]
}
}
group("modulesgroup") {
if (!defined(ohos_lite)) {
deps = [ ":bootchart" ]
deps = [ "bootchart:bootchart" ]
}
}
# 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.
import("//base/startup/init/begetd.gni")
import("//build/ohos.gni")
ohos_shared_library("bootchart") {
sources = [ "bootchart.c" ]
include_dirs = [
"//base/startup/init/services/modules",
"//base/startup/init/services/modules/bootchart",
"//base/startup/init/services/include/param",
]
deps = [
"//base/startup/init/interfaces/innerkits:libbegetutil",
"//third_party/bounds_checking_function:libsec_shared",
"//third_party/cJSON:cjson_static",
]
external_deps = [ "init:libinit_module_engine" ]
part_name = "init"
if (target_cpu == "arm64") {
module_install_dir = "lib64/init"
} else {
module_install_dir = "lib/init"
}
}
config("libbootchart_static_config") {
include_dirs = [
"//base/startup/init/services/modules",
"//base/startup/init/services/modules/bootchart",
]
}
ohos_source_set("libbootchart_static") {
sources = [ "bootchart_static.c" ]
public_configs = [ ":libbootchart_static_config" ]
public_configs += [ "//base/startup/init/interfaces/innerkits/init_module_engine:init_module_engine_exported_config" ]
}
......@@ -16,14 +16,26 @@ import("//build/ohos.gni")
config("bootevent_static_config") {
include_dirs = [
"//base/startup/init/services/param/linux",
"//base/startup/init/services/init/include",
"//base/startup/init/services/loopevent/include",
"//base/startup/init/services/modules/init_hook",
"//base/startup/init/services/param/include",
"//base/startup/init/services/include/param",
"//third_party/bounds_checking_function/include/",
]
}
ohos_source_set("libbootevent_static") {
sources = [ "bootevent.c" ]
include_dirs = [ ".." ]
public_configs = [ ":bootevent_static_config" ]
public_configs += [ "//base/startup/init/interfaces/innerkits/init_module_engine:init_module_engine_exported_config" ]
if (build_selinux) {
include_dirs += [
"//third_party/selinux/libselinux/include/",
"//base/security/selinux/interfaces/policycoreutils/include/",
"//base/startup/init/services/include/param",
]
defines = [ "WITH_SELINUX" ]
}
}
......@@ -17,121 +17,107 @@
#include "init_module_engine.h"
#include "trigger_manager.h"
#include "init_log.h"
#include "plugin_adapter.h"
#include "init_hook.h"
#include "init_service.h"
#include "bootstage.h"
#include "securec.h"
#define BOOT_EVENT_PARA_PREFIX "bootevent."
#define BOOT_EVENT_PARA_PREFIX_LEN 10
#define BOOT_EVENT_TIMESTAMP_MAX_LEN 50
static int bootEventNum = 0;
enum {
BOOTEVENT_FORK,
BOOTEVENT_READY,
BOOTEVENT_MAX
};
typedef struct tagBOOT_EVENT_PARAM_ITEM {
ListNode node;
const char *paramName;
struct timespec timestamp[BOOTEVENT_MAX];
} BOOT_EVENT_PARAM_ITEM;
static ListNode *bootEventList = NULL;
static ListNode bootEventList = {&bootEventList, &bootEventList};
static ListNode *getBootEventParaList(bool autoCreate)
static int BootEventParaListCompareProc(ListNode *node, void *data)
{
if (!autoCreate) {
return bootEventList;
}
if (bootEventList != NULL) {
return bootEventList;
}
// Create list node
bootEventList = (ListNode *)malloc(sizeof(ListNode));
if (bootEventList == NULL) {
return NULL;
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)node;
if (strcmp(item->paramName + BOOT_EVENT_PARA_PREFIX_LEN, (const char *)data) == 0) {
return 0;
}
OH_ListInit(bootEventList);
return bootEventList;
return -1;
}
static void BootEventParaAdd(const char *paramName)
static int AddServiceBootEvent(const char *serviceName, const char *paramName)
{
ListNode *list;
BOOT_EVENT_PARAM_ITEM *item;
if (paramName == NULL) {
return;
}
// Only bootevent. parameters can be added
ServiceExtData *extData = NULL;
ListNode *found = NULL;
if (strncmp(paramName, BOOT_EVENT_PARA_PREFIX, BOOT_EVENT_PARA_PREFIX_LEN) != 0) {
return;
return -1;
}
INIT_LOGI("Add bootevent [%s] ...", paramName);
list = getBootEventParaList(true);
if (list == NULL) {
return;
found = OH_ListFind(&bootEventList, (void *)paramName, BootEventParaListCompareProc);
if (found != NULL) {
return -1;
}
// Create item
item = (BOOT_EVENT_PARAM_ITEM *)malloc(sizeof(BOOT_EVENT_PARAM_ITEM));
if (item == NULL) {
return;
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) {
break;
}
}
item->paramName = strdup(paramName);
if (item->paramName == NULL) {
free((void *)item);
return;
if (extData == NULL) {
return -1;
}
// Add to list
OH_ListAddTail(list, (ListNode *)item);
}
static int BootEventParaListCompareProc(ListNode *node, void *data)
{
BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)node;
if (strcmp(item->paramName, (const char *)data) == 0) {
return 0;
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;
}
return -1;
}
static void BootEventParaItemDestroy(BOOT_EVENT_PARAM_ITEM *item)
{
if (item->paramName != NULL) {
free((void *)item->paramName);
item->paramName = strdup(paramName);
if (item->paramName == NULL) {
INIT_LOGI("strdup failed");
return -1;
}
free((void *)item);
OH_ListAddTail(&bootEventList, (ListNode *)&item->node);
return 0;
}
#define BOOT_EVENT_BOOT_COMPLETED "bootevent.boot.completed"
static void BootEventParaFireByName(const char *paramName)
{
ListNode *found;
if (bootEventList == NULL) {
ListNode *found = NULL;
char *bootEventValue = strrchr(paramName, '.');
if (bootEventValue == NULL) {
return;
}
bootEventValue[0] = '\0';
found = OH_ListFind(getBootEventParaList(false), (void *)paramName, BootEventParaListCompareProc);
if (found != NULL) {
// Remove from list
OH_ListRemove(found);
BootEventParaItemDestroy((BOOT_EVENT_PARAM_ITEM *)found);
found = OH_ListFind(&bootEventList, (void *)paramName, BootEventParaListCompareProc);
if (found == NULL) {
return;
}
if (((BOOT_EVENT_PARAM_ITEM *)found)->timestamp[BOOTEVENT_READY].tv_sec != 0) {
return;
}
INIT_CHECK_ONLY_RETURN(clock_gettime(CLOCK_MONOTONIC,
&(((BOOT_EVENT_PARAM_ITEM *)found)->timestamp[BOOTEVENT_READY])) == 0);
bootEventNum--;
// Check if all boot event params are fired
if (OH_ListGetCnt(getBootEventParaList(false)) > 0) {
if (bootEventNum > 0) {
return;
}
// Delete hooks for boot event
free((void *)bootEventList);
bootEventList = NULL;
// All parameters are fired, set boot completed now ...
INIT_LOGI("All bootevents are fired, boot complete now ...");
SystemWriteParam(BOOT_EVENT_BOOT_COMPLETED, "true");
return;
}
#define BOOT_EVENT_FIELD_NAME "bootevents"
static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx)
{
int cnt;
......@@ -141,10 +127,14 @@ static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx)
if (bootEvents == NULL) {
return;
}
// Single bootevent in config file
if (!cJSON_IsArray(bootEvents)) {
BootEventParaAdd(cJSON_GetStringValue(bootEvents));
if (AddServiceBootEvent(serviceParseCtx->serviceName,
cJSON_GetStringValue(bootEvents)) != 0) {
INIT_LOGI("Add service bootevent failed %s", serviceParseCtx->serviceName);
return;
}
bootEventNum++;
return;
}
......@@ -152,24 +142,89 @@ static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx)
cnt = cJSON_GetArraySize(bootEvents);
for (int i = 0; i < cnt; i++) {
cJSON *item = cJSON_GetArrayItem(bootEvents, i);
BootEventParaAdd(cJSON_GetStringValue(item));
if (AddServiceBootEvent(serviceParseCtx->serviceName,
cJSON_GetStringValue(item)) != 0) {
INIT_LOGI("Add service bootevent failed %s", serviceParseCtx->serviceName);
return;
}
bootEventNum++;
}
}
static int DoBootEventCmd(int id, const char *name, int argc, const char **argv)
{
PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
// argv[0] samgr.ready.true
BootEventParaFireByName(argv[0]);
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);
}
return 0;
}
static void ParamSetBootEventHook(PARAM_SET_CTX *paramSetCtx)
static void DumpServiceBootEvent(SERVICE_INFO_CTX *serviceCtx)
{
// Check if the parameter is started with "bootevent."
if (strncmp(paramSetCtx->name, BOOT_EVENT_PARA_PREFIX, BOOT_EVENT_PARA_PREFIX_LEN) != 0) {
if (serviceCtx->reserved != NULL && strcmp(serviceCtx->reserved, "bootevent") != 0) {
return;
}
for (int i = HOOK_ID_BOOTEVENT; i < HOOK_ID_BOOTEVENT_MAX; i++) {
ServiceExtData *serviceExtData = GetServiceExtData(serviceCtx->serviceName, i);
if (serviceExtData == NULL) {
return;
}
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);
printf("\t%-20.20s\t%-50s\t%-20.20s\t%-20.20s\n", serviceCtx->serviceName, item->paramName,
booteventForkTimeStamp, booteventReadyTimeStamp);
}
return;
}
// Delete the bootevent param for list
BootEventParaFireByName(paramSetCtx->name);
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;
}
OH_ListRemove(&((BOOT_EVENT_PARAM_ITEM *)extData->data)->node);
DelServiceExtData(serviceCtx->serviceName, i);
}
}
return;
}
static void SetServiceBootEventFork(SERVICE_INFO_CTX *serviceCtx)
{
for (int i = HOOK_ID_BOOTEVENT; i < HOOK_ID_BOOTEVENT_MAX; i++) {
ServiceExtData *extData = GetServiceExtData(serviceCtx->serviceName, i);
if (extData == NULL || ((BOOT_EVENT_PARAM_ITEM *)extData->data)->timestamp[BOOTEVENT_FORK].tv_sec != 0) {
return;
}
INIT_CHECK_ONLY_RETURN(clock_gettime(CLOCK_MONOTONIC,
&(((BOOT_EVENT_PARAM_ITEM *)extData->data)->timestamp[BOOTEVENT_FORK])) == 0);
}
return;
}
MODULE_CONSTRUCTOR(void)
{
EnableInitLog(INIT_DEBUG);
InitAddServiceHook(SetServiceBootEventFork, INIT_SERVICE_FORK_BEFORE);
InitAddServiceHook(ClearServiceBootEvent, INIT_SERVICE_CLEAR);
InitAddServiceHook(DumpServiceBootEvent, INIT_SERVICE_DUMP);
InitAddServiceParseHook(ServiceParseBootEventHook);
ParamSetHookAdd(ParamSetBootEventHook);
InitAddGlobalInitHook(0, ParamSetBootEventHook);
}
# 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.
import("//build/ohos.gni")
config("inithook_config") {
include_dirs = [ "//base/startup/init/services/modules/init_hook" ]
}
comm_include = [
"//base/startup/init/services/include",
"//base/startup/init/services/include/param",
"//base/startup/init/services/modules",
"//base/startup/init/services/modules/init_hook",
"//base/startup/init/services/init/include",
"//base/startup/init/services/loopevent/include",
"//base/startup/init/services/log",
"//base/startup/init/interfaces/innerkits/include",
"//third_party/cJSON",
"//third_party/bounds_checking_function/include",
]
if (defined(ohos_lite)) {
static_library("inithook") {
defines = [ "_GNU_SOURCE" ]
include_dirs = comm_include
sources = [ "param_hook.c" ]
public_configs = [ ":inithook_config" ]
}
} else {
ohos_source_set("inithook") {
defines = [ "_GNU_SOURCE" ]
include_dirs = comm_include
sources = [
"init_hook.c",
"param_hook.c",
]
if (build_selinux) {
include_dirs += [
"//third_party/selinux/libselinux/include/",
"//base/security/selinux/interfaces/policycoreutils/include/",
]
defines += [ "WITH_SELINUX" ]
}
public_configs = [ ":inithook_config" ]
public_configs += [ "//base/startup/init/interfaces/innerkits/init_module_engine:init_module_engine_exported_config" ]
}
}
/*
* 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.
*/
#include "init_hook.h"
#include "init_service.h"
#include "init_utils.h"
#include "plugin_adapter.h"
#include "securec.h"
#include "init_module_engine.h"
#include "init_group_manager.h"
#include "hookmgr.h"
#include "bootstage.h"
static int ServiceExtDataCompareProc(ListNode *node, void *data)
{
ServiceExtData *item = ListEntry(node, ServiceExtData, node);
if (item->dataId == *(uint32_t *)data) {
return 0;
}
return -1;
}
static ServiceExtData *GetServiceExtData_(Service *service, uint32_t id)
{
ListNode *node = OH_ListFind(&service->extDataNode, (void *)&id, ServiceExtDataCompareProc);
return (ServiceExtData *)node;
}
ServiceExtData *AddServiceExtData(const char *serviceName, uint32_t id, void *data, uint32_t dataLen)
{
Service *service = GetServiceByName(serviceName);
PLUGIN_CHECK(service != NULL, return NULL, "Can not find service for %s", serviceName);
ServiceExtData *extData = GetServiceExtData_(service, id);
if (extData != NULL) {
return NULL;
}
extData = calloc(1, sizeof(ServiceExtData) + dataLen);
PLUGIN_CHECK(extData != NULL, return NULL, "Can not alloc extData for %d", id);
OH_ListInit(&extData->node);
extData->dataId = id;
if (data != NULL) {
int ret = memcpy_s(extData->data, dataLen, data, dataLen);
if (ret == 0) {
OH_ListAddTail(&service->extDataNode, &extData->node);
return extData;
}
} else {
OH_ListAddTail(&service->extDataNode, &extData->node);
return extData;
}
free(extData);
return NULL;
}
void DelServiceExtData(const char *serviceName, uint32_t id)
{
Service *service = GetServiceByName(serviceName);
PLUGIN_CHECK(service != NULL, return, "Can not find service for %s", serviceName);
ServiceExtData *extData = GetServiceExtData_(service, id);
if (extData == NULL) {
return;
}
OH_ListRemove(&extData->node);
free(extData);
}
ServiceExtData *GetServiceExtData(const char *serviceName, uint32_t id)
{
Service *service = GetServiceByName(serviceName);
PLUGIN_CHECK (service != NULL, return NULL, "Can not find service for %s", serviceName);
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 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);
}
return 0;
}
static int ParamSetBootEventHook(const HOOK_INFO *hookInfo, void *cookie)
{
AddCmdExecutor("clear", CmdClear_);
return 0;
}
MODULE_CONSTRUCTOR(void)
{
InitAddGlobalInitHook(0, ParamSetBootEventHook);
}
/*
* 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_PARAM_HOOK_
#define STARTUP_INIT_PARAM_HOOK_
#include <stdio.h>
#include <stdint.h>
#include "list.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define SERVICE_CTL_CMD_INDEX 2
typedef struct {
const char *name;
const char *replace;
const char *cmd;
} ParamCmdInfo;
const ParamCmdInfo *GetServiceStartCtrl(size_t *size);
const ParamCmdInfo *GetServiceCtl(size_t *size);
const ParamCmdInfo *GetStartupPowerCtl(size_t *size);
const ParamCmdInfo *GetOtherSpecial(size_t *size);
typedef struct {
struct ListNode node;
uint32_t dataId;
uint8_t data[0];
} ServiceExtData;
ServiceExtData *AddServiceExtData(const char *serviceName, uint32_t id, void *data, uint32_t dataLen);
void DelServiceExtData(const char *serviceName, uint32_t id);
ServiceExtData *GetServiceExtData(const char *serviceName, uint32_t id);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif
\ No newline at end of file
/*
* 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.
*/
#include "init_hook.h"
#include "init_service.h"
#include "init_utils.h"
#include "plugin_adapter.h"
#include "securec.h"
const ParamCmdInfo *GetServiceStartCtrl(size_t *size)
{
static const ParamCmdInfo ctrlParam[] = {
{"ohos.ctl.start", "start", "start "},
{"ohos.ctl.stop", "stop", "stop "},
};
*size = ARRAY_LENGTH(ctrlParam);
return ctrlParam;
}
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" }
};
*size = ARRAY_LENGTH(installParam);
return installParam;
}
const ParamCmdInfo *GetStartupPowerCtl(size_t *size)
{
static const ParamCmdInfo powerCtrlArg[] = {
{"reboot,shutdown", "reboot.shutdown", "reboot "},
{"reboot,updater", "reboot.updater", "reboot "},
{"reboot,flashd", "reboot.flashd", "reboot "},
{"reboot,loader", "reboot.loader", "reboot "},
{"reboot,charge", "reboot.charge", "reboot "},
{"reboot", "reboot", "reboot "},
};
*size = ARRAY_LENGTH(powerCtrlArg);
return powerCtrlArg;
}
const ParamCmdInfo *GetOtherSpecial(size_t *size)
{
static const ParamCmdInfo other[] = {
{"bootevent.", "bootevent.", "bootevent"},
};
*size = ARRAY_LENGTH(other);
return other;
}
......@@ -21,6 +21,12 @@
#include "init_log.h"
#define PROCESS_EXIT_CODE 0x7f // 0x7f: user specified
#ifndef UNUSED
#define UNUSED(x) (void)(x)
#endif
#ifndef PLUGIN_DOMAIN
#define PLUGIN_DOMAIN (BASE_DOMAIN + 6)
#endif
......@@ -39,4 +45,12 @@
if (!(ret)) { \
exper; \
}
#define HOOKID(name) HOOK_ID_##name
enum HOOK_ID_ {
HOOKID(BOOTCHART),
HOOKID(SELINUX),
HOOKID(BOOTEVENT),
HOOKID(BOOTEVENT_MAX) = HOOK_ID_BOOTEVENT + 10,
};
#endif
......@@ -48,6 +48,7 @@ mode_str = {
'ONLY_CHECK_ARGS': 1
}
def is_hex_digit(s):
try:
int(s, 16)
......
......@@ -43,8 +43,7 @@ static int InitWorkSpace_(WorkSpace *workSpace, uint32_t spaceSize, int readOnly
int ret = GetRealFileName(workSpace, buffer, sizeof(buffer));
PARAM_CHECK(ret == 0, return -1, "Failed to get file name %s", workSpace->fileName);
void *areaAddr = GetSharedMem(buffer, &workSpace->memHandle, spaceSize, readOnly);
PARAM_CHECK(areaAddr != NULL, return PARAM_CODE_ERROR_MAP_FILE,
"Failed to map memory error %d spaceSize %d", errno, spaceSize);
PARAM_ONLY_CHECK(areaAddr != NULL, return PARAM_CODE_ERROR_MAP_FILE);
if (!readOnly) {
workSpace->area = (ParamTrieHeader *)areaAddr;
ATOMIC_INIT(&workSpace->area->commitId, 0);
......@@ -108,7 +107,7 @@ INIT_LOCAL_API int InitWorkSpace(WorkSpace *workSpace, int onlyRead, uint32_t sp
workSpace->allocTrieNode = AllocateParamTrieNode;
workSpace->area = NULL;
int ret = InitWorkSpace_(workSpace, spaceSize, onlyRead);
PARAM_CHECK(ret == 0, return ret, "Failed to init workspace %s", workSpace->fileName);
PARAM_ONLY_CHECK(ret == 0, return ret);
PARAMSPACE_AREA_INIT_LOCK(workSpace);
PARAM_SET_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT);
PARAM_LOGV("InitWorkSpace %s for %s", workSpace->fileName, (onlyRead == 0) ? "init" : "other");
......
......@@ -35,8 +35,12 @@ extern "C" {
#endif
#define WORKSPACE_NAME_DAC "param_sec_dac"
#define WORKSPACE_NAME_NORMAL "param_storage"
#define WORKSPACE_NAME_DEF_SELINUX "u:object_r:default_param:s0"
#ifndef PARAM_SUPPORT_SELINUX
#define WORKSPACE_NAME_NORMAL "param_storage"
#else
#define WORKSPACE_NAME_NORMAL WORKSPACE_NAME_DEF_SELINUX
#endif
#define PARAM_NEED_CHECK_IN_SERVICE 0x2
#define PARAM_CTRL_SERVICE 0x1
......@@ -76,6 +80,13 @@ typedef struct {
PersistParamOps persistParamOps;
} ParamPersistWorkSpace;
typedef struct {
char realKey[PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX + 1];
char cmdName[32];
uint32_t valueOffset;
uint8_t ctrlParam;
} ServiceCtrlInfo;
typedef void (*TraversalParamPtr)(ParamHandle handle, void *context);
typedef struct {
TraversalParamPtr traversalParamPtr;
......@@ -117,6 +128,9 @@ INIT_LOCAL_API int GenerateKeyHasCode(const char *buff, size_t len);
INIT_INNER_API ParamWorkSpace *GetParamWorkSpace(void);
INIT_INNER_API int GetParamSecurityAuditData(const char *name, int type, ParamAuditData *auditData);
INIT_INNER_API int SysCheckParamExist(const char *name);
INIT_LOCAL_API int GetServiceCtrlInfo(const char *name, const char *value, ServiceCtrlInfo **ctrlInfo);
#ifdef STARTUP_INIT_TEST
ParamService *GetParamService();
#endif
......
......@@ -44,6 +44,7 @@ extern "C" {
#endif
#endif
#define PARAM_WORKSPACE_MIN (1024)
#if (defined __LITEOS_A__ || defined __LITEOS_M__)
#define DAC_DEFAULT_MODE 0777
#ifdef STARTUP_INIT_TEST
......
......@@ -33,6 +33,7 @@ param_include_dirs = [
"//base/startup/init/services/include",
"//base/startup/init/services/init/include",
"//base/startup/init/services/log",
"//base/startup/init/services/modules/init_hook",
"//base/startup/init/interfaces/innerkits/init_module_engine/include",
"//base/startup/init/services/loopevent/include",
"//third_party/bounds_checking_function/include",
......
......@@ -33,7 +33,7 @@ int ConnectServer(int fd, const char *servername)
addr.sun_family = AF_UNIX;
ret = sprintf_s(addr.sun_path, sizeof(addr.sun_path) - 1, "%s", servername);
PARAM_CHECK(ret > EOK, return -1, "Failed to sprintf_s server address");
int len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path);
size_t len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path);
ret = connect(fd, (struct sockaddr *)&addr, len);
PARAM_CHECK(ret != -1, return -1, "Failed to connect server %s %d", servername, errno);
PARAM_LOGV("ConnectServer %s success", servername);
......
......@@ -56,7 +56,7 @@ INIT_LOCAL_API int ParamRWMutexUnlock(ParamRWMutex *lock)
INIT_LOCAL_API int ParamRWMutexDelete(ParamRWMutex *lock)
{
PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
uint32_t ret = pthread_rwlock_destroy(&lock->rwlock);
int ret = pthread_rwlock_destroy(&lock->rwlock);
PARAM_CHECK(ret == 0, return -1, "Failed to mutex lock ret %d", ret);
return 0;
}
......
......@@ -146,9 +146,10 @@ static int StartRequest(int clientFd, ParamMessage *request, int timeout)
int SystemSetParameter(const char *name, const char *value)
{
PARAM_CHECK(name != NULL && value != NULL, return -1, "Invalid name or value");
int ctrlService = 0;
int ret = CheckParameterSet(name, value, GetParamSecurityLabel(), &ctrlService);
PARAM_CHECK(ret == 0, return ret, "Forbid to set parameter %s", name);
int ret = CheckParamName(name, 0);
PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name);
ret = CheckParamValue(NULL, name, value, GetParamValueType(name));
PARAM_CHECK(ret == 0, return ret, "Illegal param value %s", value);
size_t msgSize = sizeof(ParamMsgContent);
msgSize = (msgSize < RECV_BUFFER_MAX) ? RECV_BUFFER_MAX : msgSize;
......
......@@ -29,10 +29,6 @@
#include "param_message.h"
#include "trigger_manager.h"
#include "securec.h"
#ifndef OHOS_LITE
#include "hookmgr.h"
#include "init_running_hooks.h"
#endif
#ifdef PARAM_SUPPORT_SELINUX
#include "selinux_parameter.h"
#include <policycoreutils.h>
......@@ -144,45 +140,6 @@ static int SendWatcherNotifyMessage(const TriggerExtInfo *extData, const char *c
return 0;
}
#ifndef OHOS_LITE
/**
* Parameter Set Hooking
*/
static int ParamSetHookWrapper(const HOOK_INFO *hookInfo, void *executionContext)
{
PARAM_SET_CTX *paramSetContext = (PARAM_SET_CTX *)executionContext;
ParamSetHook realHook = (ParamSetHook)hookInfo->hookCookie;
realHook(paramSetContext);
return 0;
};
int ParamSetHookAdd(ParamSetHook hook)
{
HOOK_INFO info;
info.stage = INIT_PARAM_SET_HOOK_STAGE;
info.prio = 0;
info.hook = ParamSetHookWrapper;
info.hookCookie = (void *)hook;
return HookMgrAddEx(NULL, &info);
}
static int ParamSetHookExecute(const char *name, const char *value)
{
PARAM_SET_CTX context;
context.name = name;
context.value = value;
context.skipParamSet = 0;
(void)HookMgrExecute(NULL, INIT_PARAM_SET_HOOK_STAGE, (void *)(&context), NULL);
return context.skipParamSet;
}
#endif
static int SystemSetParam(const char *name, const char *value, const ParamSecurityLabel *srcLabel)
{
PARAM_LOGV("SystemWriteParam name %s value: %s", name, value);
......@@ -190,20 +147,7 @@ static int SystemSetParam(const char *name, const char *value, const ParamSecuri
int ret = CheckParameterSet(name, value, srcLabel, &ctrlService);
PARAM_CHECK(ret == 0, return ret, "Forbid to set parameter %s", name);
#ifndef OHOS_LITE
/*
* Execute param set hooks before setting parameter values
*/
if (ParamSetHookExecute(name, value)) {
// Hook has processed the parameter set request
PARAM_LOGI("param [%s] set in the hook.", name);
return 0;
}
#endif
if (ctrlService & PARAM_CTRL_SERVICE) { // ctrl param
PostParamTrigger(EVENT_TRIGGER_PARAM, name, value);
} else {
if ((ctrlService & PARAM_CTRL_SERVICE) != PARAM_CTRL_SERVICE) { // ctrl param
uint32_t dataIndex = 0;
ret = WriteParam(name, value, &dataIndex, 0);
PARAM_CHECK(ret == 0, return ret, "Failed to set param %d name %s %s", ret, name, value);
......
......@@ -14,6 +14,7 @@ import("//base/startup/init/begetd.gni")
param_include_dirs = [
"//base/startup/init/interfaces/innerkits/include/syspara",
"//base/startup/init/services/modules/init_hook",
"//base/startup/init/services/param/include",
"//base/startup/init/services/param/adapter",
"//base/startup/init/services/param/base",
......
......@@ -18,6 +18,8 @@
#include <ctype.h>
#include <limits.h>
#include "init_cmds.h"
#include "init_hook.h"
#include "param_trie.h"
#include "param_utils.h"
#include "securec.h"
......@@ -239,63 +241,67 @@ INIT_INNER_API int GetParamSecurityAuditData(const char *name, int type, ParamAu
return 0;
}
static char *BuildKey(const char *format, ...)
static int CreateCtrlInfo(ServiceCtrlInfo **ctrlInfo, const char *cmd, uint32_t offset,
uint8_t ctrlParam, const char *format, ...)
{
const size_t buffSize = 1024; // 1024 for format key
char *buffer = malloc(buffSize);
PARAM_CHECK(buffer != NULL, return NULL, "Failed to malloc for format");
*ctrlInfo = calloc(1, sizeof(ServiceCtrlInfo));
PARAM_CHECK(ctrlInfo != NULL, return -1, "Failed to alloc memory %s", cmd);
va_list vargs;
va_start(vargs, format);
int len = vsnprintf_s(buffer, buffSize, buffSize - 1, format, vargs);
int len = vsnprintf_s((*ctrlInfo)->realKey,
sizeof((*ctrlInfo)->realKey), sizeof((*ctrlInfo)->realKey) - 1, format, vargs);
va_end(vargs);
if (len > 0 && (size_t)len < buffSize) {
buffer[len] = '\0';
for (int i = 0; i < len; i++) {
if (buffer[i] == '|') {
buffer[i] = '\0';
}
}
return buffer;
int ret = strcpy_s((*ctrlInfo)->cmdName, sizeof((*ctrlInfo)->cmdName), cmd);
(*ctrlInfo)->valueOffset = offset;
if (ret != 0 || len <= 0) {
free(*ctrlInfo);
return -1;
}
return NULL;
(*ctrlInfo)->ctrlParam = ctrlParam;
return 0;
}
PARAM_STATIC char *GetServiceCtrlName(const char *name, const char *value)
INIT_LOCAL_API int GetServiceCtrlInfo(const char *name, const char *value, ServiceCtrlInfo **ctrlInfo)
{
static char *ctrlParam[] = {
"ohos.ctl.start",
"ohos.ctl.stop"
};
static char *installParam[] = {
"ohos.servicectrl."
};
static char *powerCtrlArg[][2] = {
{"reboot,shutdown", "reboot.shutdown"},
{"reboot,updater", "reboot.updater"},
{"reboot,flashd", "reboot.flashd"},
{"reboot", "reboot"},
};
char *key = NULL;
PARAM_CHECK(ctrlInfo != NULL, return -1, "Invalid ctrlInfo %s", name);
*ctrlInfo = NULL;
size_t size = 0;
if (strcmp("ohos.startup.powerctrl", name) == 0) {
for (size_t i = 0; i < ARRAY_LENGTH(powerCtrlArg); i++) {
if (strncmp(value, powerCtrlArg[i][0], strlen(powerCtrlArg[i][0])) == 0) {
return BuildKey("%s%s", OHOS_SERVICE_CTRL_PREFIX, powerCtrlArg[i][1]);
const ParamCmdInfo *powerCtrlArg = GetStartupPowerCtl(&size);
for (size_t i = 0; i < size; i++) {
if (strncmp(value, powerCtrlArg[i].name, strlen(powerCtrlArg[i].name)) == 0) {
uint32_t valueOffset = strlen(OHOS_SERVICE_CTRL_PREFIX) + strlen(powerCtrlArg[i].replace) + 1;
return CreateCtrlInfo(ctrlInfo, powerCtrlArg[i].cmd, valueOffset, 1,
"%s%s.%s", OHOS_SERVICE_CTRL_PREFIX, powerCtrlArg[i].replace, value);
}
}
return key;
return 0;
}
for (size_t i = 0; i < ARRAY_LENGTH(ctrlParam); i++) {
if (strcmp(name, ctrlParam[i]) == 0) {
return BuildKey("%s%s", OHOS_SERVICE_CTRL_PREFIX, value);
if (strncmp("ohos.ctl.", name, strlen("ohos.ctl.")) == 0) {
const ParamCmdInfo *ctrlParam = GetServiceStartCtrl(&size);
for (size_t i = 0; i < size; i++) {
if (strcmp(name, ctrlParam[i].name) == 0) {
uint32_t valueOffset = strlen(OHOS_SERVICE_CTRL_PREFIX) + strlen(ctrlParam[i].replace) + 1;
return CreateCtrlInfo(ctrlInfo, ctrlParam[i].cmd, valueOffset, 1,
"%s%s.%s", OHOS_SERVICE_CTRL_PREFIX, ctrlParam[i].replace, value);
}
}
}
for (size_t i = 0; i < ARRAY_LENGTH(installParam); i++) {
if (strncmp(name, installParam[i], strlen(installParam[i])) == 0) {
return BuildKey("%s.%s", name, value);
if (strncmp("ohos.servicectrl.", name, strlen("ohos.servicectrl.")) == 0) {
const ParamCmdInfo *installParam = GetServiceCtl(&size);
for (size_t i = 0; i < size; i++) {
if (strncmp(name, installParam[i].name, strlen(installParam[i].name)) == 0) {
return CreateCtrlInfo(ctrlInfo, installParam[i].cmd, strlen(name) + 1, 1, "%s.%s", name, value);
}
}
}
const ParamCmdInfo *other = GetOtherSpecial(&size);
for (size_t i = 0; i < size; i++) {
if (strncmp(name, other[i].name, strlen(other[i].name)) == 0) {
return CreateCtrlInfo(ctrlInfo, other[i].cmd, strlen(other[i].name), 0, "%s.%s", name, value);
}
}
return key;
return 0;
}
INIT_LOCAL_API int CheckParameterSet(const char *name,
......@@ -312,24 +318,25 @@ INIT_LOCAL_API int CheckParameterSet(const char *name,
PARAM_CHECK(ret == 0, return ret, "Illegal param value %s", value);
*ctrlService = 0;
#ifndef __LITEOS_M__
if (getpid() != 1) { // none init
#ifdef PARAM_SUPPORT_SELINUX
*ctrlService |= PARAM_NEED_CHECK_IN_SERVICE;
return 0;
#else
if ((srcLabel->flags[0] & LABEL_CHECK_IN_ALL_PROCESS) != LABEL_CHECK_IN_ALL_PROCESS) {
*ctrlService |= PARAM_NEED_CHECK_IN_SERVICE;
ServiceCtrlInfo *serviceInfo = NULL;
GetServiceCtrlInfo(name, value, &serviceInfo);
ret = CheckParamPermission(srcLabel, (serviceInfo == NULL) ? name : serviceInfo->realKey, DAC_WRITE);
if (ret == 0) {
if (serviceInfo == NULL) {
return 0;
}
if (serviceInfo->ctrlParam != 0) { // ctrl param
*ctrlService |= PARAM_CTRL_SERVICE;
}
#if !(defined __LITEOS_A__ || defined __LITEOS_M__)
// do hook cmd
PARAM_LOGI("CheckParameterSet realKey %s cmd: '%s' value: %s",
serviceInfo->realKey, serviceInfo->cmdName, (char *)serviceInfo->realKey + serviceInfo->valueOffset);
DoCmdByName(serviceInfo->cmdName, (char *)serviceInfo->realKey + serviceInfo->valueOffset);
#endif
}
#endif
char *key = GetServiceCtrlName(name, value);
ret = CheckParamPermission(srcLabel, (key == NULL) ? name : key, DAC_WRITE);
if (key != NULL) { // ctrl param
free(key);
*ctrlService |= PARAM_CTRL_SERVICE;
if (serviceInfo != NULL) {
free(serviceInfo);
}
return ret;
}
......
......@@ -120,6 +120,8 @@ INIT_LOCAL_API int LoadParamFromCmdLine(void)
},
{OHOS_BOOT"reboot_reason", CommonDealFun
},
{OHOS_BOOT"bootslots", CommonDealFun
},
{OHOS_BOOT"sn", SnDealFun
}
};
......
......@@ -14,7 +14,6 @@
*/
#include <ctype.h>
#include "init_cmds.h"
#include "init_param.h"
#include "init_service_manager.h"
#include "init_utils.h"
......@@ -24,6 +23,8 @@
#include "trigger_checker.h"
#include "trigger_manager.h"
#include "securec.h"
#include "hookmgr.h"
#include "bootstage.h"
#define MAX_TRIGGER_COUNT_RUN_ONCE 20
static TriggerWorkSpace g_triggerWorkSpace = {};
......@@ -140,65 +141,11 @@ PARAM_STATIC void ProcessBeforeEvent(const ParamTaskPtr stream,
}
}
static const char *GetCmdInfo(const char *content, uint32_t contentSize)
{
static char buffer[PARAM_NAME_LEN_MAX] = {0};
uint32_t index = 0;
while (index < contentSize && index < PARAM_NAME_LEN_MAX) {
if (*(content + index) == '=' || *(content + index) == ',') {
break;
}
buffer[index] = *(content + index);
index++;
}
if (index >= (PARAM_NAME_LEN_MAX - 1)) {
return NULL;
}
buffer[index] = ' ';
buffer[index + 1] = '\0';
int cmdIndex = 0;
return GetMatchCmd(buffer, &cmdIndex);
}
static void DoServiceCtrlTrigger(const char *cmdStart, uint32_t len, int onlyValue)
{
char *cmdParam = (char *)cmdStart;
const char *matchCmd = GetCmdInfo(cmdStart, len);
if (matchCmd != NULL) {
size_t cmdLen = strlen(matchCmd);
if (onlyValue != 0 && cmdParam != NULL && strlen(cmdParam) > cmdLen) {
cmdParam += cmdLen + 1;
}
PARAM_LOGV("DoServiceCtrlTrigger matchCmd %s cmdParam %s", matchCmd, cmdParam);
#ifndef STARTUP_INIT_TEST
DoCmdByName(matchCmd, cmdParam);
#endif
} else {
PARAM_LOGE("DoServiceCtrlTrigger cmd %s not found", cmdStart);
}
}
static void SendTriggerEvent(int type, const char *content, uint32_t contentLen)
{
PARAM_CHECK(content != NULL, return, "Invalid param");
PARAM_LOGV("SendTriggerEvent type %d content %s", type, content);
if (type == EVENT_TRIGGER_PARAM) {
int ctrlSize = strlen(SYS_POWER_CTRL);
int prefixSize = strlen(OHOS_SERVICE_CTRL_PREFIX);
if (strncmp(content, SYS_POWER_CTRL, ctrlSize) == 0) {
DoServiceCtrlTrigger(content + ctrlSize, contentLen - ctrlSize, 0);
} else if (strncmp(content, OHOS_SERVICE_CTRL_PREFIX, prefixSize) == 0) {
DoServiceCtrlTrigger(content + prefixSize, contentLen - prefixSize, 1);
} else if (strncmp(content, OHOS_CTRL_START, strlen(OHOS_CTRL_START)) == 0) {
StartServiceByName(content + strlen(OHOS_CTRL_START));
} else if (strncmp(content, OHOS_CTRL_STOP, strlen(OHOS_CTRL_STOP)) == 0) {
StopServiceByName(content + strlen(OHOS_CTRL_STOP));
} else {
ParamEventSend(g_triggerWorkSpace.eventHandle, (uint64_t)type, content, contentLen);
}
} else {
ParamEventSend(g_triggerWorkSpace.eventHandle, (uint64_t)type, content, contentLen);
}
ParamEventSend(g_triggerWorkSpace.eventHandle, (uint64_t)type, content, contentLen);
}
void PostParamTrigger(int type, const char *name, const char *value)
......@@ -254,6 +201,40 @@ static int GetCommandInfo(const char *cmdLine, int *cmdKeyIndex, char **content)
return 0;
}
/**
* job Config File Parse Hooking
*/
static int JobParseHookWrapper(const HOOK_INFO *hookInfo, void *executionContext)
{
JOB_PARSE_CTX *jobParseContext = (JOB_PARSE_CTX *)executionContext;
JobParseHook realHook = (JobParseHook)hookInfo->hookCookie;
realHook(jobParseContext);
return 0;
};
int InitAddJobParseHook(JobParseHook hook)
{
HOOK_INFO info;
info.stage = INIT_JOB_PARSE;
info.prio = 0;
info.hook = JobParseHookWrapper;
info.hookCookie = (void *)hook;
return HookMgrAddEx(GetBootStageHookMgr(), &info);
}
static void ParseJobHookExecute(const char *name, const cJSON *jobNode)
{
JOB_PARSE_CTX context;
context.jobName = name;
context.jobNode = jobNode;
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_JOB_PARSE, (void *)(&context), NULL);
}
static int ParseTrigger_(const TriggerWorkSpace *workSpace,
const cJSON *triggerItem, int (*checkJobValid)(const char *jobName))
{
......@@ -310,6 +291,10 @@ int ParseTriggerConfig(const cJSON *fileRoot, int (*checkJobValid)(const char *j
for (int i = 0; i < size && i < TRIGGER_MAX_CMD; ++i) {
cJSON *item = cJSON_GetArrayItem(triggers, i);
ParseTrigger_(&g_triggerWorkSpace, item, checkJobValid);
/*
* execute job parsing hooks
*/
ParseJobHookExecute(cJSON_GetStringValue(cJSON_GetObjectItem(item, "name")), item);
}
return 0;
}
......
......@@ -27,7 +27,7 @@ ohos_shared_library("param_watcher") {
]
include_dirs = [
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include/",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy/include/",
"//base/startup/init/services/param/include",
"//base/startup/init/services/include/param",
"//base/startup/init/services/param/linux",
......
......@@ -74,7 +74,7 @@ ohos_executable("ondemandTest") {
"c_utils:utils",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
"samgr:samgr_proxy",
]
install_images = [ "system" ]
......
......@@ -475,7 +475,7 @@ ohos_fuzztest("SystemWatchParameterFuzzTest") {
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
"samgr:samgr_proxy",
]
cflags = [
......
......@@ -64,6 +64,7 @@ ohos_unittest("init_unittest") {
"//base/startup/init/services/init/standard/init.c",
"//base/startup/init/services/init/standard/init_cmdexecutor.c",
"//base/startup/init/services/init/standard/init_cmds.c",
"//base/startup/init/services/init/standard/init_control_fd_service.c",
"//base/startup/init/services/init/standard/init_jobs.c",
"//base/startup/init/services/init/standard/init_mount.c",
"//base/startup/init/services/init/standard/init_reboot.c",
......@@ -81,6 +82,9 @@ ohos_unittest("init_unittest") {
"//base/startup/init/services/loopevent/task/le_watchtask.c",
"//base/startup/init/services/loopevent/timer/le_timer.c",
"//base/startup/init/services/loopevent/utils/le_utils.c",
"//base/startup/init/services/modules/bootevent/bootevent.c",
"//base/startup/init/services/modules/init_hook/init_hook.c",
"//base/startup/init/services/modules/init_hook/param_hook.c",
"//base/startup/init/services/param/adapter/param_dac.c",
"//base/startup/init/services/param/adapter/param_persistadp.c",
"//base/startup/init/services/param/base/param_base.c",
......@@ -157,6 +161,7 @@ ohos_unittest("init_unittest") {
sources += [
"//base/startup/init/interfaces/innerkits/hookmgr/hookmgr.c",
"//base/startup/init/interfaces/innerkits/init_module_engine/init_modulemgr.c",
"//base/startup/init/interfaces/innerkits/modulemgr/modulemgr.c",
"innerkits/hookmgr_unittest.cpp",
"innerkits/modulemgr_unittest.cpp",
......@@ -186,6 +191,10 @@ ohos_unittest("init_unittest") {
"//base/startup/init/services/loopevent/task",
"//base/startup/init/services/loopevent/timer",
"//base/startup/init/services/loopevent/utils",
"//base/startup/init/services/modules",
"//base/startup/init/services/modules/init_hook",
"//base/startup/init/services/modules/selinux",
"//base/startup/init/services/loopevent/utils",
"//base/startup/init/services/param/adapter",
"//base/startup/init/services/param/base",
"//base/startup/init/services/param/linux",
......@@ -195,11 +204,11 @@ ohos_unittest("init_unittest") {
"//base/startup/init/services/param/watcher/proxy",
"//base/startup/init/test/unittest",
"//base/startup/init/test/unittest/param",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
"//foundation/distributedschedule/safwk/services/safwk/include",
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk",
"//foundation/distributedschedule/samgr/adapter/interfaces/innerkits/include",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy/include",
"//foundation/systemabilitymgr/safwk/services/safwk/include",
"//foundation/systemabilitymgr/safwk/interfaces/innerkits/safwk",
"//foundation/systemabilitymgr/samgr/adapter/interfaces/innerkits/include",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy/include",
"//base/startup/init/ueventd/include",
"//utils/system/safwk/native/include",
"//third_party/bounds_checking_function/include",
......@@ -251,7 +260,7 @@ ohos_unittest("init_unittest") {
external_deps += [
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
"samgr:samgr_proxy",
]
}
......
......@@ -23,6 +23,7 @@
#include "le_timer.h"
#include "param_stub.h"
#include "securec.h"
#include "control_fd.h"
using namespace testing::ext;
using namespace std;
......@@ -299,7 +300,8 @@ HWTEST_F(InitGroupManagerUnitTest, TestAddService2, TestSize.Level1)
ASSERT_NE(nullptr, fileRoot);
ParseAllServices(fileRoot);
cJSON_Delete(fileRoot);
DumpAllServices();
char cmdStr[] = "all#bootevent";
ProcessControlFd(ACTION_DUMP, cmdStr, NULL);
Service *service = GetServiceByName("test-service6");
ASSERT_NE(service, nullptr);
workspace->groupMode = GROUP_BOOT;
......
......@@ -26,6 +26,9 @@
#include "securec.h"
#include "init_group_manager.h"
#include "trigger_manager.h"
#include "bootstage.h"
#include "init_hook.h"
#include "plugin_adapter.h"
using namespace testing::ext;
using namespace std;
......@@ -262,6 +265,36 @@ HWTEST_F(ServiceUnitTest, TestServiceManagerGetService, TestSize.Level1)
ret = ParseOneService(serviceItem, service);
EXPECT_NE(ret, 0);
}
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;
}
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;
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_FORK_BEFORE, (void *)(&serviceInfoContext), NULL);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_DUMP, (void *)(&serviceInfoContext), NULL);
(void)HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)(&serviceInfoContext), NULL);
}
HWTEST_F(ServiceUnitTest, TestServiceExec, TestSize.Level1)
{
......
......@@ -36,6 +36,7 @@ if (defined(ohos_lite)) {
]
}
param_common_sources = [
"//base/startup/init/services/modules/init_hook/param_hook.c",
"//base/startup/init/services/param/manager/param_manager.c",
"//base/startup/init/services/param/manager/param_persist.c",
"//base/startup/init/services/param/manager/param_server.c",
......@@ -94,10 +95,14 @@ if (defined(ohos_lite)) {
"//base/startup/init/services/param/watcher/agent",
"//base/startup/init/services/param/watcher/include",
"//base/startup/init/services/param/watcher/proxy",
"//base/startup/init/services/modules",
"//base/startup/init/services/modules/init_hook",
"//base/startup/init/services/modules/selinux",
"//base/startup/init/test/unittest",
"//base/startup/init/test/unittest/param",
"//base/startup/init/interfaces/innerkits/include",
"//base/startup/init/interfaces/innerkits/include/syspara",
"//base/startup/init/interfaces/innerkits/init_module_engine/include",
"//base/startup/init/interfaces/innerkits/syspara",
"//third_party/cJSON",
"//third_party/bounds_checking_function/include",
......
......@@ -27,7 +27,11 @@ using namespace std;
extern "C" {
int WorkSpaceNodeCompare(const HashNode *node1, const HashNode *node2);
char *GetServiceCtrlName(const char *name, const char *value);
}
static void OnClose(ParamTaskPtr client)
{
UNUSED(client);
}
static int CheckServerParamValue(const char *name, const char *expectValue)
......@@ -412,10 +416,24 @@ HWTEST_F(ParamUnitTest, TestLinuxRWLock, TestSize.Level0)
free(workspace1);
free(workspace2);
}
HWTEST_F(ParamUnitTest, TestGetServiceCtlName, TestSize.Level0)
{
EXPECT_STREQ(GetServiceCtrlName("ohos.startup.powerctrl", "reboot,updater"), "ohos.servicectrl.reboot.updater");
EXPECT_STREQ(GetServiceCtrlName("ohos.ctl.stop", "test"), "ohos.servicectrl.test");
EXPECT_STREQ(GetServiceCtrlName("ohos.servicectrl.stop", "test"), "ohos.servicectrl.stop.test");
ServiceCtrlInfo *serviceInfo = NULL;
GetServiceCtrlInfo("ohos.startup.powerctrl", "reboot,updater", &serviceInfo);
if (serviceInfo != NULL) {
EXPECT_STREQ(serviceInfo->realKey, "ohos.servicectrl.reboot.updater.reboot,updater");
free(serviceInfo);
}
GetServiceCtrlInfo("ohos.ctl.stop", "test", &serviceInfo);
if (serviceInfo != NULL) {
EXPECT_STREQ(serviceInfo->realKey, "ohos.servicectrl.stop.test");
free(serviceInfo);
}
GetServiceCtrlInfo("ohos.servicectrl.stop", "test", &serviceInfo);
if (serviceInfo != NULL) {
EXPECT_STREQ(serviceInfo->realKey, "ohos.servicectrl.stop.test");
free(serviceInfo);
}
}
}
......@@ -528,49 +528,34 @@ HWTEST_F(ParamServiceUnitTest, TestServiceCtrl, TestSize.Level0)
{
ParamServiceUnitTest test;
int ret = test.TestServiceCtrl("server1", 0770);
#ifdef PARAM_SUPPORT_SELINUX
EXPECT_EQ(ret, 0);
#else
EXPECT_NE(ret, 0);
#endif
EXPECT_NE(ret, 0);
// selinux forbid
ret = test.TestServiceCtrl("server2", 0772);
EXPECT_EQ(ret, 0);
EXPECT_NE(ret, 0);
}
HWTEST_F(ParamServiceUnitTest, TestPowerCtrl, TestSize.Level0)
{
ParamServiceUnitTest test;
int ret = test.TestPowerCtrl("reboot,shutdown", 0770);
#ifdef PARAM_SUPPORT_SELINUX
EXPECT_EQ(ret, 0);
#else
EXPECT_NE(ret, 0);
#endif
EXPECT_NE(ret, 0);
ret = test.TestPowerCtrl("reboot,shutdown", 0772);
EXPECT_EQ(ret, 0);
// selinux forbid
EXPECT_NE(ret, 0);
ret = test.TestPowerCtrl("reboot,updater", 0770);
#ifdef PARAM_SUPPORT_SELINUX
EXPECT_EQ(ret, 0);
#else
EXPECT_NE(ret, 0);
#endif
EXPECT_NE(ret, 0);
ret = test.TestPowerCtrl("reboot,updater", 0772);
EXPECT_EQ(ret, 0);
// selinux forbid
EXPECT_NE(ret, 0);
ret = test.TestPowerCtrl("reboot,flash", 0770);
#ifdef PARAM_SUPPORT_SELINUX
EXPECT_EQ(ret, 0);
#else
EXPECT_NE(ret, 0);
#endif
EXPECT_NE(ret, 0);
ret = test.TestPowerCtrl("reboot,flash", 0772);
EXPECT_EQ(ret, 0);
// selinux forbid
EXPECT_NE(ret, 0);
ret = test.TestPowerCtrl("reboot", 0770);
#ifdef PARAM_SUPPORT_SELINUX
EXPECT_EQ(ret, 0);
#else
EXPECT_NE(ret, 0);
#endif
EXPECT_NE(ret, 0);
ret = test.TestPowerCtrl("reboot", 0772);
EXPECT_EQ(ret, 0);
// selinux forbid
EXPECT_NE(ret, 0);
}
} // namespace init_ut
......@@ -182,7 +182,8 @@ static void HandleRequiredBlockDeviceNodes(const struct Uevent *uevent, char **d
INIT_LOGI("%s match with required partition %s success, now handle it", uevent->syspath, deviceName);
HandleBlockDeviceEvent(uevent);
return;
} else if (strstr(devices[i], uevent->partitionName) != NULL) {
} else if (strstr(devices[i], uevent->partitionName) != NULL ||
strstr(uevent->partitionName, "vendor") != NULL || strstr(uevent->partitionName, "system") != NULL) {
INIT_LOGI("Handle required partitionName %s", uevent->partitionName);
HandleBlockDeviceEvent(uevent);
return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册