mirror of
https://gitee.com/openharmony/startup_init
synced 2024-12-18 00:16:53 +00:00
Feature: support hooking device info api and extending ohos.boot. parameters from cmdline
1) add hook to device info api 2) extending ohos.boot. parameters by cmdline Signed-off-by: handyohos <zhangxiaotian@huawei.com> Change-Id: I06931b7685315a9422754444c42dc85e89e681f5 #I6D6V1
This commit is contained in:
parent
66fb8d1752
commit
33c4561fca
@ -31,8 +31,6 @@ declare_args() {
|
||||
# config memory size for liteos-m
|
||||
config_ohos_startup_init_lite_memory_size = 5120
|
||||
|
||||
# boot_kernel_extended_cmdline for extend cmdline
|
||||
|
||||
startup_init_feature_decode_group_file = false
|
||||
|
||||
startup_init_test_performance = true
|
||||
@ -45,4 +43,7 @@ declare_args() {
|
||||
startup_init_with_param_base = true
|
||||
startup_init_feature_decode_group_file = true
|
||||
}
|
||||
|
||||
# begetutil extension module
|
||||
startup_begetutil_extra_modules = ""
|
||||
}
|
||||
|
@ -200,6 +200,10 @@ if (defined(ohos_lite)) {
|
||||
"//third_party/mbedtls:mbedtls_shared",
|
||||
]
|
||||
deps += [ "//base/startup/init/services/param/base:param_base" ]
|
||||
if (startup_begetutil_extra_modules != "") {
|
||||
deps += [ startup_begetutil_extra_modules ]
|
||||
}
|
||||
|
||||
external_deps = [
|
||||
"c_utils:utils",
|
||||
"hilog_native:libhilog_base",
|
||||
|
@ -92,6 +92,8 @@ INIT_LOCAL_API int GetParameter_(const char *key, const char *def, char *value,
|
||||
return GetSystemError(ret);
|
||||
}
|
||||
|
||||
static PropertyValueProcessor propertyGetProcessor = NULL;
|
||||
|
||||
INIT_LOCAL_API const char *GetProperty(const char *key, const char **paramHolder)
|
||||
{
|
||||
BEGET_CHECK(paramHolder != NULL, return NULL);
|
||||
@ -108,11 +110,21 @@ INIT_LOCAL_API const char *GetProperty(const char *key, const char **paramHolder
|
||||
free(res);
|
||||
return NULL;
|
||||
}
|
||||
if (propertyGetProcessor != NULL) {
|
||||
res = propertyGetProcessor(key, res);
|
||||
}
|
||||
*paramHolder = res;
|
||||
}
|
||||
return *paramHolder;
|
||||
}
|
||||
|
||||
INIT_LOCAL_API PropertyValueProcessor SetPropertyGetProcessor(PropertyValueProcessor processor)
|
||||
{
|
||||
PropertyValueProcessor prev = propertyGetProcessor;
|
||||
propertyGetProcessor = processor;
|
||||
return prev;
|
||||
}
|
||||
|
||||
INIT_LOCAL_API const char *GetProductModel_(void)
|
||||
{
|
||||
static const char *productModel = NULL;
|
||||
|
@ -30,7 +30,10 @@ extern "C" {
|
||||
#define DEV_BUF_LENGTH 3
|
||||
#define DEV_BUF_MAX_LENGTH 1024
|
||||
|
||||
typedef char * (*PropertyValueProcessor)(const char *key, char *value);
|
||||
|
||||
INIT_LOCAL_API const char *GetProperty(const char *key, const char **paramHolder);
|
||||
INIT_LOCAL_API PropertyValueProcessor SetPropertyGetProcessor(PropertyValueProcessor processor);
|
||||
INIT_LOCAL_API int GetParameter_(const char *key, const char *def, char *value, uint32_t len);
|
||||
|
||||
INIT_LOCAL_API const char *GetProductModel_(void);
|
||||
|
@ -60,6 +60,14 @@ char *ReadFileToBuf(const char *configFile);
|
||||
int GetProcCmdlineValue(const char *name, const char *buffer, char *value, int length);
|
||||
char *ReadFileData(const char *fileName);
|
||||
|
||||
typedef struct tagNAME_VALUE_PAIR{
|
||||
const char *name;
|
||||
const char *name_end;
|
||||
const char *value;
|
||||
const char *value_end;
|
||||
} NAME_VALUE_PAIR;
|
||||
int IterateNameValuePairs(const char *src, void (*iterator)(const NAME_VALUE_PAIR *nv, void *context), void *context);
|
||||
|
||||
int SplitString(char *srcPtr, const char *del, char **dstPtr, int maxNum);
|
||||
void WaitForFile(const char *source, unsigned int maxSecond);
|
||||
size_t WriteAll(int fd, const char *buffer, size_t size);
|
||||
|
@ -37,16 +37,6 @@ typedef enum {
|
||||
#define PARAM_BUFFER_MAX (0x01 << 16)
|
||||
#endif
|
||||
|
||||
struct CmdLineEntry {
|
||||
char *key;
|
||||
int set;
|
||||
};
|
||||
|
||||
typedef struct cmdLineInfo {
|
||||
const char *name;
|
||||
int (*processor)(const char *name, const char *value, int);
|
||||
} cmdLineInfo;
|
||||
|
||||
#define FILENAME_LEN_MAX 255
|
||||
#define MS_UNIT 1000
|
||||
#ifndef UNUSED
|
||||
@ -64,7 +54,6 @@ typedef struct cmdLineInfo {
|
||||
#define OHOS_CTRL_START "ohos.ctl.start="
|
||||
#define OHOS_CTRL_STOP "ohos.ctl.stop="
|
||||
#define OHOS_SERVICE_CTRL_PREFIX "ohos.servicectrl."
|
||||
#define OHOS_BOOT "ohos.boot."
|
||||
|
||||
#ifdef STARTUP_INIT_TEST
|
||||
#define PARAM_STATIC
|
||||
|
@ -74,9 +74,6 @@ if (defined(ohos_lite)) {
|
||||
include_dirs = param_include_dirs
|
||||
public_configs = [ ":exported_header_files" ]
|
||||
|
||||
if (defined(boot_kernel_extended_cmdline)) {
|
||||
defines += [ "BOOT_EXTENDED_CMDLINE=\"${boot_kernel_extended_cmdline}\"" ]
|
||||
}
|
||||
defines += [
|
||||
"_GNU_SOURCE",
|
||||
"__LINUX__",
|
||||
@ -112,10 +109,6 @@ if (defined(ohos_lite)) {
|
||||
"PARAM_SUPPORT_REAL_CHECK",
|
||||
]
|
||||
|
||||
if (defined(boot_kernel_extended_cmdline)) {
|
||||
defines += [ "BOOT_EXTENDED_CMDLINE=\"${boot_kernel_extended_cmdline}\"" ]
|
||||
}
|
||||
|
||||
if (param_base_log) {
|
||||
defines += [ "PARAM_BASE_LOG" ]
|
||||
}
|
||||
|
@ -18,43 +18,38 @@
|
||||
#include "param_manager.h"
|
||||
#include "param_trie.h"
|
||||
|
||||
static int LoadSecurityLabel(const char *fileName)
|
||||
{
|
||||
ParamWorkSpace *paramSpace = GetParamWorkSpace();
|
||||
PARAM_CHECK(paramSpace != NULL, return -1, "Invalid paramSpace");
|
||||
PARAM_WORKSPACE_CHECK(paramSpace, return -1, "Invalid space");
|
||||
PARAM_CHECK(fileName != NULL, return -1, "Invalid filename for load");
|
||||
#if !(defined __LITEOS_A__ || defined __LITEOS_M__)
|
||||
// load security label
|
||||
ParamSecurityOps *ops = GetParamSecurityOps(PARAM_SECURITY_DAC);
|
||||
if (ops != NULL && ops->securityGetLabel != NULL) {
|
||||
ops->securityGetLabel(fileName);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Loading system parameter from /proc/cmdline by the following rules:
|
||||
* 1) reserved cmdline with or without ohos.boot. prefix listed in CmdlineIterator
|
||||
will be processed by the specified processor
|
||||
* 2) cmdline not listed in CmdlineIterator but prefixed with ohos.boot will be add by default
|
||||
*
|
||||
* Special cases for sn:
|
||||
* a) if sn value in cmdline is started with "/", it means a file to be read as parameter value
|
||||
* b) if sn or ohos.boot.sn are not specified, try to generate sn by GenerateSnByDefault
|
||||
*/
|
||||
#define OHOS_CMDLINE_PARA_PREFIX "ohos.boot."
|
||||
#define OHOS_CMDLINE_PARA_PREFIX_LEN 10
|
||||
|
||||
static int GetParamValueFromBuffer(const char *name, const char *buffer, char *value, int length)
|
||||
{
|
||||
size_t bootLen = strlen(OHOS_BOOT);
|
||||
const char *tmpName = name + bootLen;
|
||||
int ret = GetProcCmdlineValue(tmpName, buffer, value, length);
|
||||
return ret;
|
||||
}
|
||||
typedef struct cmdLineInfo {
|
||||
const char *name;
|
||||
int (*processor)(const char *name, const char *value);
|
||||
} cmdLineInfo;
|
||||
|
||||
static int CommonDealFun(const char *name, const char *value, int res)
|
||||
typedef struct cmdLineIteratorCtx {
|
||||
char *cmdline;
|
||||
bool gotSn;
|
||||
} cmdLineIteratorCtx;
|
||||
|
||||
static int CommonDealFun(const char *name, const char *value)
|
||||
{
|
||||
int ret = 0;
|
||||
if (res == 0) {
|
||||
PARAM_LOGV("Add param from cmdline %s %s", name, value);
|
||||
ret = CheckParamName(name, 0);
|
||||
PARAM_CHECK(ret == 0, return ret, "Invalid param name %s", name);
|
||||
PARAM_LOGV("Param name %s, value %s", name, value);
|
||||
ret = WriteParam(name, value, NULL, 0);
|
||||
PARAM_CHECK(ret == 0, return ret, "Failed to write param %s %s", name, value);
|
||||
} else {
|
||||
PARAM_LOGW("Get %s parameter value is null.", name);
|
||||
}
|
||||
PARAM_LOGV("Add param from cmdline %s %s", name, value);
|
||||
ret = CheckParamName(name, 0);
|
||||
PARAM_CHECK(ret == 0, return ret, "Invalid param name %s", name);
|
||||
PARAM_LOGV("Param name %s, value %s", name, value);
|
||||
ret = WriteParam(name, value, NULL, 0);
|
||||
PARAM_CHECK(ret == 0, return ret, "Failed to write param %s %s", name, value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -82,71 +77,125 @@ static int ReadSnFromFile(const char *name, const char *file)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int SnDealFun(const char *name, const char *value, int res)
|
||||
#define OHOS_SN_PARAM_NAME OHOS_CMDLINE_PARA_PREFIX"sn"
|
||||
|
||||
static int SnDealFun(const char *name, const char *value)
|
||||
{
|
||||
const char *snFileList [] = {
|
||||
"/sys/block/mmcblk0/device/cid",
|
||||
"/proc/bootdevice/cid"
|
||||
};
|
||||
int ret = CheckParamName(name, 0);
|
||||
PARAM_CHECK(ret == 0, return ret, "Invalid name %s", name);
|
||||
if (value != NULL && res == 0 && value[0] != '/') {
|
||||
if (value != NULL && value[0] != '/') {
|
||||
PARAM_LOGV("**** name %s, value %s", name, value);
|
||||
ret = WriteParam(name, value, NULL, 0);
|
||||
ret = WriteParam(OHOS_SN_PARAM_NAME, value, NULL, 0);
|
||||
PARAM_CHECK(ret == 0, return ret, "Failed to write param %s %s", name, value);
|
||||
return ret;
|
||||
}
|
||||
if (value != NULL && value[0] == '/') {
|
||||
ret = ReadSnFromFile(name, value);
|
||||
ret = ReadSnFromFile(OHOS_SN_PARAM_NAME, value);
|
||||
if (ret == 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(snFileList); i++) {
|
||||
ret = ReadSnFromFile(name, snFileList[i]);
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void CmdlineIterator(const NAME_VALUE_PAIR *nv, void *context)
|
||||
{
|
||||
const char *name;
|
||||
char fullName[PARAM_NAME_LEN_MAX];
|
||||
cmdLineIteratorCtx *ctx = (cmdLineIteratorCtx *)context;
|
||||
char *data = (char *)ctx->cmdline;
|
||||
static const cmdLineInfo cmdLines[] = {
|
||||
{ "hardware", CommonDealFun },
|
||||
{ "bootgroup", CommonDealFun },
|
||||
{ "reboot_reason", CommonDealFun },
|
||||
{ "bootslots", CommonDealFun },
|
||||
{ "sn", SnDealFun },
|
||||
{ "serialno", SnDealFun }
|
||||
};
|
||||
|
||||
data[nv->name_end - data] = '\0';
|
||||
data[nv->value_end - data] = '\0';
|
||||
PARAM_LOGE("proc cmdline: name [%s], value [%s]", nv->name, nv->value);
|
||||
|
||||
// Get name without prefix
|
||||
name = nv->name;
|
||||
if (strncmp(name, OHOS_CMDLINE_PARA_PREFIX, OHOS_CMDLINE_PARA_PREFIX_LEN) == 0) {
|
||||
name = name + OHOS_CMDLINE_PARA_PREFIX_LEN;
|
||||
}
|
||||
|
||||
// Matching reserved cmdlines
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(cmdLines); i++) {
|
||||
if (strcmp(name, cmdLines[i].name) == 0) {
|
||||
snprintf_s(fullName, sizeof(fullName), sizeof(fullName) - 1, OHOS_CMDLINE_PARA_PREFIX "%s", cmdLines[i].name);
|
||||
PARAM_LOGE("proc cmdline %s matched.", fullName);
|
||||
int ret = cmdLines[i].processor(fullName, nv->value);
|
||||
if ((ret == 0) && (SnDealFun == cmdLines[i].processor)) {
|
||||
ctx->gotSn = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (name == nv->name) {
|
||||
return;
|
||||
}
|
||||
|
||||
// cmdline with prefix but not matched, add to param by default
|
||||
PARAM_LOGE("add proc cmdline param %s by default.", nv->name);
|
||||
CommonDealFun(nv->name, nv->value);
|
||||
}
|
||||
|
||||
static void GenerateSnByDefault() {
|
||||
const char *snFileList [] = {
|
||||
"/sys/block/mmcblk0/device/cid",
|
||||
"/proc/bootdevice/cid"
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(snFileList); i++) {
|
||||
int ret = ReadSnFromFile(OHOS_CMDLINE_PARA_PREFIX "sn", snFileList[i]);
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INIT_LOCAL_API int LoadParamFromCmdLine(void)
|
||||
{
|
||||
static const cmdLineInfo cmdLines[] = {
|
||||
{OHOS_BOOT"hardware", CommonDealFun
|
||||
},
|
||||
{OHOS_BOOT"bootgroup", CommonDealFun
|
||||
},
|
||||
{OHOS_BOOT"reboot_reason", CommonDealFun
|
||||
},
|
||||
{OHOS_BOOT"bootslots", CommonDealFun
|
||||
},
|
||||
{OHOS_BOOT"sn", SnDealFun
|
||||
}
|
||||
};
|
||||
char *data = ReadFileData(BOOT_CMD_LINE);
|
||||
PARAM_CHECK(data != NULL, return -1, "Failed to read file %s", BOOT_CMD_LINE);
|
||||
char *value = calloc(1, PARAM_CONST_VALUE_LEN_MAX + 1);
|
||||
PARAM_CHECK(value != NULL, free(data);
|
||||
return -1, "Failed to read file %s", BOOT_CMD_LINE);
|
||||
cmdLineIteratorCtx ctx;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(cmdLines); i++) {
|
||||
int ret = 0;
|
||||
#ifdef BOOT_EXTENDED_CMDLINE
|
||||
ret = GetParamValueFromBuffer(cmdLines[i].name, BOOT_EXTENDED_CMDLINE, value, PARAM_CONST_VALUE_LEN_MAX);
|
||||
if (ret != 0) {
|
||||
ret = GetParamValueFromBuffer(cmdLines[i].name, data, value, PARAM_CONST_VALUE_LEN_MAX);
|
||||
}
|
||||
#else
|
||||
ret = GetParamValueFromBuffer(cmdLines[i].name, data, value, PARAM_CONST_VALUE_LEN_MAX);
|
||||
#endif
|
||||
ctx.gotSn = false;
|
||||
ctx.cmdline = ReadFileData(BOOT_CMD_LINE);
|
||||
PARAM_CHECK(ctx.cmdline != NULL, return -1, "Failed to read file %s", BOOT_CMD_LINE);
|
||||
|
||||
cmdLines[i].processor(cmdLines[i].name, value, ret);
|
||||
IterateNameValuePairs(ctx.cmdline, CmdlineIterator, (void *)(&ctx));
|
||||
|
||||
// sn is critical, it must be specified
|
||||
if (!ctx.gotSn) {
|
||||
PARAM_LOGE("Generate default sn now ...");
|
||||
GenerateSnByDefault();
|
||||
}
|
||||
PARAM_LOGV("Parse cmdline finish %s", BOOT_CMD_LINE);
|
||||
free(data);
|
||||
free(value);
|
||||
|
||||
free(ctx.cmdline);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load parameters from files
|
||||
*/
|
||||
|
||||
static int LoadSecurityLabel(const char *fileName)
|
||||
{
|
||||
ParamWorkSpace *paramSpace = GetParamWorkSpace();
|
||||
PARAM_CHECK(paramSpace != NULL, return -1, "Invalid paramSpace");
|
||||
PARAM_WORKSPACE_CHECK(paramSpace, return -1, "Invalid space");
|
||||
PARAM_CHECK(fileName != NULL, return -1, "Invalid filename for load");
|
||||
#if !(defined __LITEOS_A__ || defined __LITEOS_M__)
|
||||
// load security label
|
||||
ParamSecurityOps *ops = GetParamSecurityOps(PARAM_SECURITY_DAC);
|
||||
if (ops != NULL && ops->securityGetLabel != NULL) {
|
||||
ops->securityGetLabel(fileName);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -202,6 +202,48 @@ char *ReadFileData(const char *fileName)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int IterateNameValuePairs(const char *src, void (*iterator)(const NAME_VALUE_PAIR *nv, void *context), void *context)
|
||||
{
|
||||
int cnt = 0;
|
||||
const char *seperator;
|
||||
NAME_VALUE_PAIR nv;
|
||||
if ((src == NULL) || (iterator == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
// Find space seperator
|
||||
nv.name = src;
|
||||
seperator = strchr(src, ' ');
|
||||
if (seperator == NULL) {
|
||||
// Last nv
|
||||
nv.value_end = src + strlen(src);
|
||||
src = NULL;
|
||||
} else {
|
||||
nv.value_end = seperator;
|
||||
src = seperator + 1;
|
||||
}
|
||||
|
||||
// Find equal seperator
|
||||
seperator = strchr(nv.name, '=');
|
||||
if (seperator == NULL) {
|
||||
// Invalid name value pair
|
||||
continue;
|
||||
}
|
||||
if (seperator > nv.value_end) {
|
||||
// name without value, just ignore
|
||||
continue;
|
||||
}
|
||||
nv.name_end = seperator;
|
||||
nv.value = seperator + 1;
|
||||
|
||||
iterator(&nv, context);
|
||||
cnt += 1;
|
||||
} while (src != NULL);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int GetProcCmdlineValue(const char *name, const char *buffer, char *value, int length)
|
||||
{
|
||||
INIT_ERROR_CHECK(name != NULL && buffer != NULL && value != NULL, return -1, "Failed get parameters");
|
||||
|
Loading…
Reference in New Issue
Block a user