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:
handyohos 2023-02-06 15:45:55 +08:00
parent 66fb8d1752
commit 33c4561fca
9 changed files with 199 additions and 98 deletions

View File

@ -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 = ""
}

View File

@ -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",

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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" ]
}

View File

@ -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;
}

View File

@ -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");