1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci#include <ctype.h> 16d9f0492fSopenharmony_ci#include <errno.h> 17d9f0492fSopenharmony_ci#include <limits.h> 18d9f0492fSopenharmony_ci 19d9f0492fSopenharmony_ci#include "param_manager.h" 20d9f0492fSopenharmony_ci#include "param_trie.h" 21d9f0492fSopenharmony_ci#ifdef SUPPORT_PARAM_LOAD_HOOK 22d9f0492fSopenharmony_ci#include "init_module_engine.h" 23d9f0492fSopenharmony_ci#endif 24d9f0492fSopenharmony_ci#include "securec.h" 25d9f0492fSopenharmony_ci#include "init_cmds.h" 26d9f0492fSopenharmony_ci#include "init_param.h" 27d9f0492fSopenharmony_ci 28d9f0492fSopenharmony_ci/** 29d9f0492fSopenharmony_ci * Loading system parameter from /proc/cmdline by the following rules: 30d9f0492fSopenharmony_ci * 1) reserved cmdline with or without ohos.boot. prefix listed in CmdlineIterator 31d9f0492fSopenharmony_ci will be processed by the specified processor 32d9f0492fSopenharmony_ci * 2) cmdline not listed in CmdlineIterator but prefixed with ohos.boot will be add by default 33d9f0492fSopenharmony_ci * 34d9f0492fSopenharmony_ci * Special cases for sn: 35d9f0492fSopenharmony_ci * a) if sn value in cmdline is started with "/", it means a file to be read as parameter value 36d9f0492fSopenharmony_ci * b) if sn or ohos.boot.sn are not specified, try to generate sn by GenerateSnByDefault 37d9f0492fSopenharmony_ci */ 38d9f0492fSopenharmony_ci#define OHOS_CMDLINE_PARA_PREFIX "ohos.boot." 39d9f0492fSopenharmony_ci#define OHOS_CMDLINE_CONST_PARA_PREFIX "const.product." 40d9f0492fSopenharmony_ci#define OHOS_CMDLINE_PARA_PREFIX_LEN 10 41d9f0492fSopenharmony_ci#define IMPORT_PREFIX_LEN 7 42d9f0492fSopenharmony_ci 43d9f0492fSopenharmony_citypedef struct CmdLineInfo { 44d9f0492fSopenharmony_ci const char *name; 45d9f0492fSopenharmony_ci int (*processor)(const char *name, const char *value); 46d9f0492fSopenharmony_ci} CmdLineInfo; 47d9f0492fSopenharmony_ci 48d9f0492fSopenharmony_citypedef struct CmdLineInfoContainer { 49d9f0492fSopenharmony_ci const CmdLineInfo *cmdLineInfo; 50d9f0492fSopenharmony_ci size_t cmdLineInfoSize; 51d9f0492fSopenharmony_ci} CmdLineInfoContainer; 52d9f0492fSopenharmony_ci 53d9f0492fSopenharmony_citypedef struct CmdLineIteratorCtx { 54d9f0492fSopenharmony_ci char *cmdline; 55d9f0492fSopenharmony_ci bool gotSn; 56d9f0492fSopenharmony_ci bool *matches; 57d9f0492fSopenharmony_ci} CmdLineIteratorCtx; 58d9f0492fSopenharmony_ci 59d9f0492fSopenharmony_cistatic int CommonDealFun(const char *name, const char *value) 60d9f0492fSopenharmony_ci{ 61d9f0492fSopenharmony_ci int ret = 0; 62d9f0492fSopenharmony_ci PARAM_LOGV("Add param from cmdline %s %s", name, value); 63d9f0492fSopenharmony_ci ret = CheckParamName(name, 0); 64d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return ret, "Invalid param name %s", name); 65d9f0492fSopenharmony_ci PARAM_LOGV("Param name %s, value %s", name, value); 66d9f0492fSopenharmony_ci ret = WriteParam(name, value, NULL, 0); 67d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return ret, "Failed to write param %s %s", name, value); 68d9f0492fSopenharmony_ci return ret; 69d9f0492fSopenharmony_ci} 70d9f0492fSopenharmony_ci 71d9f0492fSopenharmony_cistatic int ReadSnFromFile(const char *name, const char *file) 72d9f0492fSopenharmony_ci{ 73d9f0492fSopenharmony_ci char *data = ReadFileData(file); 74d9f0492fSopenharmony_ci PARAM_CHECK(data != NULL, return -1, "Read sn from %s file failed!", file); 75d9f0492fSopenharmony_ci 76d9f0492fSopenharmony_ci int index = 0; 77d9f0492fSopenharmony_ci for (size_t i = 0; i < strlen(data); i++) { 78d9f0492fSopenharmony_ci // cancel \r\n 79d9f0492fSopenharmony_ci if (*(data + i) == '\r' || *(data + i) == '\n') { 80d9f0492fSopenharmony_ci break; 81d9f0492fSopenharmony_ci } 82d9f0492fSopenharmony_ci if (*(data + i) != ':') { 83d9f0492fSopenharmony_ci *(data + index) = *(data + i); 84d9f0492fSopenharmony_ci index++; 85d9f0492fSopenharmony_ci } 86d9f0492fSopenharmony_ci } 87d9f0492fSopenharmony_ci data[index] = '\0'; 88d9f0492fSopenharmony_ci PARAM_LOGV("**** name %s, value %s", name, data); 89d9f0492fSopenharmony_ci int ret = WriteParam(name, data, NULL, 0); 90d9f0492fSopenharmony_ci free(data); 91d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return ret, "Failed to write param %s", name); 92d9f0492fSopenharmony_ci return ret; 93d9f0492fSopenharmony_ci} 94d9f0492fSopenharmony_ci 95d9f0492fSopenharmony_ci#define OHOS_SN_PARAM_NAME OHOS_CMDLINE_PARA_PREFIX"sn" 96d9f0492fSopenharmony_ci 97d9f0492fSopenharmony_cistatic int SnDealFun(const char *name, const char *value) 98d9f0492fSopenharmony_ci{ 99d9f0492fSopenharmony_ci int ret = CheckParamName(name, 0); 100d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return ret, "Invalid name %s", name); 101d9f0492fSopenharmony_ci if (value != NULL && value[0] != '/') { 102d9f0492fSopenharmony_ci PARAM_LOGV("**** name %s, value %s", name, value); 103d9f0492fSopenharmony_ci ret = WriteParam(OHOS_SN_PARAM_NAME, value, NULL, 0); 104d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return ret, "Failed to write param %s %s", name, value); 105d9f0492fSopenharmony_ci return ret; 106d9f0492fSopenharmony_ci } 107d9f0492fSopenharmony_ci if (value != NULL && value[0] == '/') { 108d9f0492fSopenharmony_ci ret = ReadSnFromFile(OHOS_SN_PARAM_NAME, value); 109d9f0492fSopenharmony_ci if (ret == 0) { 110d9f0492fSopenharmony_ci return ret; 111d9f0492fSopenharmony_ci } 112d9f0492fSopenharmony_ci } 113d9f0492fSopenharmony_ci return ret; 114d9f0492fSopenharmony_ci} 115d9f0492fSopenharmony_ci 116d9f0492fSopenharmony_cistatic int Common2ConstDealFun(const char *name, const char *value) 117d9f0492fSopenharmony_ci{ 118d9f0492fSopenharmony_ci const char *tmpName; 119d9f0492fSopenharmony_ci tmpName = name; 120d9f0492fSopenharmony_ci if (strncmp(tmpName, OHOS_CMDLINE_PARA_PREFIX, OHOS_CMDLINE_PARA_PREFIX_LEN) == 0) { 121d9f0492fSopenharmony_ci tmpName = tmpName + OHOS_CMDLINE_PARA_PREFIX_LEN; 122d9f0492fSopenharmony_ci } 123d9f0492fSopenharmony_ci char fullName[PARAM_NAME_LEN_MAX]; 124d9f0492fSopenharmony_ci int ret = snprintf_s(fullName, sizeof(fullName), sizeof(fullName) - 1, 125d9f0492fSopenharmony_ci OHOS_CMDLINE_CONST_PARA_PREFIX"%s", tmpName); 126d9f0492fSopenharmony_ci PARAM_CHECK(ret > 0, return ret, "snprinf_s failed"); 127d9f0492fSopenharmony_ci ret = CheckParamName(fullName, 0); 128d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return ret, "Invalid name %s", name); 129d9f0492fSopenharmony_ci PARAM_LOGV("Param name %s, value %s", fullName, value); 130d9f0492fSopenharmony_ci ret = WriteParam(fullName, value, NULL, 0); 131d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return ret, "Failed to write param %s %s", fullName, value); 132d9f0492fSopenharmony_ci return ret; 133d9f0492fSopenharmony_ci} 134d9f0492fSopenharmony_ci 135d9f0492fSopenharmony_cistatic int MatchReserverCmdline(const NAME_VALUE_PAIR* nv, CmdLineIteratorCtx *ctx, const char *name, 136d9f0492fSopenharmony_ci CmdLineInfoContainer *container) 137d9f0492fSopenharmony_ci{ 138d9f0492fSopenharmony_ci const char* tmpName = name; 139d9f0492fSopenharmony_ci char fullName[PARAM_NAME_LEN_MAX]; 140d9f0492fSopenharmony_ci int ret = 0; 141d9f0492fSopenharmony_ci const char* matched; 142d9f0492fSopenharmony_ci 143d9f0492fSopenharmony_ci // Matching reserved cmdlines 144d9f0492fSopenharmony_ci for (size_t i = 0; i < container->cmdLineInfoSize; i++) { 145d9f0492fSopenharmony_ci // Check exact match 146d9f0492fSopenharmony_ci if (strcmp(tmpName, (container->cmdLineInfo + i)->name) != 0) { 147d9f0492fSopenharmony_ci // Check if contains ".xxx" for compatibility 148d9f0492fSopenharmony_ci ret = snprintf_s(fullName, sizeof(fullName), sizeof(fullName) - 1, ".%s", 149d9f0492fSopenharmony_ci (container->cmdLineInfo + i)->name); 150d9f0492fSopenharmony_ci matched = strstr(tmpName, fullName); 151d9f0492fSopenharmony_ci if (matched == NULL) { 152d9f0492fSopenharmony_ci continue; 153d9f0492fSopenharmony_ci } 154d9f0492fSopenharmony_ci // Check if it is ended with pattern 155d9f0492fSopenharmony_ci if (matched[ret] != '\0') { 156d9f0492fSopenharmony_ci continue; 157d9f0492fSopenharmony_ci } 158d9f0492fSopenharmony_ci } 159d9f0492fSopenharmony_ci ret = snprintf_s(fullName, sizeof(fullName), sizeof(fullName) - 1, 160d9f0492fSopenharmony_ci OHOS_CMDLINE_PARA_PREFIX "%s", (container->cmdLineInfo + i)->name); 161d9f0492fSopenharmony_ci if (ret <= 0) { 162d9f0492fSopenharmony_ci continue; 163d9f0492fSopenharmony_ci } 164d9f0492fSopenharmony_ci if (ctx->matches[i]) { 165d9f0492fSopenharmony_ci return PARAM_CODE_SUCCESS; 166d9f0492fSopenharmony_ci } 167d9f0492fSopenharmony_ci bool isSnSet = ((container->cmdLineInfo + i)->processor == SnDealFun); 168d9f0492fSopenharmony_ci if (isSnSet && ctx->gotSn) { 169d9f0492fSopenharmony_ci return PARAM_CODE_SUCCESS; 170d9f0492fSopenharmony_ci } 171d9f0492fSopenharmony_ci PARAM_LOGV("proc cmdline %s matched.", fullName); 172d9f0492fSopenharmony_ci ret = (container->cmdLineInfo + i)->processor(fullName, nv->value); 173d9f0492fSopenharmony_ci if (ret == 0) { 174d9f0492fSopenharmony_ci ctx->matches[i] = true; 175d9f0492fSopenharmony_ci if (isSnSet) { 176d9f0492fSopenharmony_ci ctx->gotSn = true; 177d9f0492fSopenharmony_ci } 178d9f0492fSopenharmony_ci } 179d9f0492fSopenharmony_ci return PARAM_CODE_SUCCESS; 180d9f0492fSopenharmony_ci } 181d9f0492fSopenharmony_ci return PARAM_CODE_NOT_FOUND; 182d9f0492fSopenharmony_ci} 183d9f0492fSopenharmony_ci 184d9f0492fSopenharmony_cistatic const CmdLineInfo CMDLINES[] = { 185d9f0492fSopenharmony_ci { "hardware", CommonDealFun }, 186d9f0492fSopenharmony_ci { "bootgroup", CommonDealFun }, 187d9f0492fSopenharmony_ci { "reboot_reason", CommonDealFun }, 188d9f0492fSopenharmony_ci { "bootslots", CommonDealFun }, 189d9f0492fSopenharmony_ci { "sn", SnDealFun }, 190d9f0492fSopenharmony_ci { "root_package", CommonDealFun }, 191d9f0492fSopenharmony_ci { "serialno", SnDealFun }, 192d9f0492fSopenharmony_ci { "udid", Common2ConstDealFun }, 193d9f0492fSopenharmony_ci { "productid", Common2ConstDealFun } 194d9f0492fSopenharmony_ci}; 195d9f0492fSopenharmony_ci 196d9f0492fSopenharmony_cistatic void CmdlineIterator(const NAME_VALUE_PAIR *nv, void *context) 197d9f0492fSopenharmony_ci{ 198d9f0492fSopenharmony_ci CmdLineIteratorCtx *ctx = (CmdLineIteratorCtx *)context; 199d9f0492fSopenharmony_ci char *data = (char *)ctx->cmdline; 200d9f0492fSopenharmony_ci 201d9f0492fSopenharmony_ci data[nv->nameEnd - data] = '\0'; 202d9f0492fSopenharmony_ci data[nv->valueEnd - data] = '\0'; 203d9f0492fSopenharmony_ci PARAM_LOGV("proc cmdline: name [%s], value [%s]", nv->name, nv->value); 204d9f0492fSopenharmony_ci 205d9f0492fSopenharmony_ci // Get name without prefix 206d9f0492fSopenharmony_ci const char *name = nv->name; 207d9f0492fSopenharmony_ci if (strncmp(name, OHOS_CMDLINE_PARA_PREFIX, OHOS_CMDLINE_PARA_PREFIX_LEN) == 0) { 208d9f0492fSopenharmony_ci name = name + OHOS_CMDLINE_PARA_PREFIX_LEN; 209d9f0492fSopenharmony_ci } 210d9f0492fSopenharmony_ci 211d9f0492fSopenharmony_ci CmdLineInfoContainer container = { 0 }; 212d9f0492fSopenharmony_ci container.cmdLineInfo = CMDLINES; 213d9f0492fSopenharmony_ci container.cmdLineInfoSize = ARRAY_LENGTH(CMDLINES); 214d9f0492fSopenharmony_ci if (MatchReserverCmdline(nv, ctx, name, &container) == 0) { 215d9f0492fSopenharmony_ci PARAM_LOGV("match reserver cmd line success, name: %s, value: %s", nv->name, nv->value); 216d9f0492fSopenharmony_ci return; 217d9f0492fSopenharmony_ci } 218d9f0492fSopenharmony_ci if (name == nv->name) { 219d9f0492fSopenharmony_ci return; 220d9f0492fSopenharmony_ci } 221d9f0492fSopenharmony_ci 222d9f0492fSopenharmony_ci // cmdline with prefix but not matched, add to param by default 223d9f0492fSopenharmony_ci PARAM_LOGI("add proc cmdline param %s by default.", nv->name); 224d9f0492fSopenharmony_ci CommonDealFun(nv->name, nv->value); 225d9f0492fSopenharmony_ci} 226d9f0492fSopenharmony_ci 227d9f0492fSopenharmony_cistatic void GenerateSnByDefault(void) 228d9f0492fSopenharmony_ci{ 229d9f0492fSopenharmony_ci const char *snFileList [] = { 230d9f0492fSopenharmony_ci "/sys/block/mmcblk0/device/cid", 231d9f0492fSopenharmony_ci "/proc/bootdevice/cid" 232d9f0492fSopenharmony_ci }; 233d9f0492fSopenharmony_ci 234d9f0492fSopenharmony_ci for (size_t i = 0; i < ARRAY_LENGTH(snFileList); i++) { 235d9f0492fSopenharmony_ci int ret = ReadSnFromFile(OHOS_CMDLINE_PARA_PREFIX "sn", snFileList[i]); 236d9f0492fSopenharmony_ci if (ret == 0) { 237d9f0492fSopenharmony_ci break; 238d9f0492fSopenharmony_ci } 239d9f0492fSopenharmony_ci } 240d9f0492fSopenharmony_ci} 241d9f0492fSopenharmony_ci 242d9f0492fSopenharmony_ciINIT_LOCAL_API int LoadParamFromCmdLine(void) 243d9f0492fSopenharmony_ci{ 244d9f0492fSopenharmony_ci CmdLineIteratorCtx ctx; 245d9f0492fSopenharmony_ci 246d9f0492fSopenharmony_ci ctx.gotSn = false; 247d9f0492fSopenharmony_ci ctx.cmdline = ReadFileData(BOOT_CMD_LINE); 248d9f0492fSopenharmony_ci PARAM_CHECK(ctx.cmdline != NULL, return -1, "Failed to read file %s", BOOT_CMD_LINE); 249d9f0492fSopenharmony_ci bool matches[ARRAY_LENGTH(CMDLINES)] = {false}; 250d9f0492fSopenharmony_ci ctx.matches = matches; 251d9f0492fSopenharmony_ci IterateNameValuePairs(ctx.cmdline, CmdlineIterator, (void *)(&ctx)); 252d9f0492fSopenharmony_ci 253d9f0492fSopenharmony_ci // sn is critical, it must be specified 254d9f0492fSopenharmony_ci if (!ctx.gotSn) { 255d9f0492fSopenharmony_ci PARAM_LOGE("Generate default sn now ..."); 256d9f0492fSopenharmony_ci GenerateSnByDefault(); 257d9f0492fSopenharmony_ci } 258d9f0492fSopenharmony_ci 259d9f0492fSopenharmony_ci free(ctx.cmdline); 260d9f0492fSopenharmony_ci return 0; 261d9f0492fSopenharmony_ci} 262d9f0492fSopenharmony_ci 263d9f0492fSopenharmony_ci/* 264d9f0492fSopenharmony_ci * Load parameters from files 265d9f0492fSopenharmony_ci */ 266d9f0492fSopenharmony_ci 267d9f0492fSopenharmony_cistatic int LoadSecurityLabel(const char *fileName) 268d9f0492fSopenharmony_ci{ 269d9f0492fSopenharmony_ci ParamWorkSpace *paramSpace = GetParamWorkSpace(); 270d9f0492fSopenharmony_ci PARAM_CHECK(paramSpace != NULL, return -1, "Invalid paramSpace"); 271d9f0492fSopenharmony_ci PARAM_WORKSPACE_CHECK(paramSpace, return -1, "Invalid space"); 272d9f0492fSopenharmony_ci PARAM_CHECK(fileName != NULL, return -1, "Invalid filename for load"); 273d9f0492fSopenharmony_ci#if !(defined __LITEOS_A__ || defined __LITEOS_M__) 274d9f0492fSopenharmony_ci // load security label 275d9f0492fSopenharmony_ci ParamSecurityOps *ops = GetParamSecurityOps(PARAM_SECURITY_DAC); 276d9f0492fSopenharmony_ci if (ops != NULL && ops->securityGetLabel != NULL) { 277d9f0492fSopenharmony_ci if (ops->securityGetLabel(fileName) == PARAM_CODE_REACHED_MAX) { 278d9f0492fSopenharmony_ci PARAM_LOGE("[startup_failed]Load Security Lable failed! system reboot! %d", SYS_PARAM_INIT_FAILED); 279d9f0492fSopenharmony_ci ExecReboot("panic"); 280d9f0492fSopenharmony_ci }; 281d9f0492fSopenharmony_ci } 282d9f0492fSopenharmony_ci#endif 283d9f0492fSopenharmony_ci return 0; 284d9f0492fSopenharmony_ci} 285d9f0492fSopenharmony_ci 286d9f0492fSopenharmony_cistatic int LoadOneParam_(const uint32_t *context, const char *name, const char *value) 287d9f0492fSopenharmony_ci{ 288d9f0492fSopenharmony_ci uint32_t mode = *(uint32_t *)context; 289d9f0492fSopenharmony_ci int ret = CheckParamName(name, 0); 290d9f0492fSopenharmony_ci if (ret != 0) { 291d9f0492fSopenharmony_ci return 0; 292d9f0492fSopenharmony_ci } 293d9f0492fSopenharmony_ci 294d9f0492fSopenharmony_ci#ifdef SUPPORT_PARAM_LOAD_HOOK 295d9f0492fSopenharmony_ci PARAM_LOAD_FILTER_CTX filter; 296d9f0492fSopenharmony_ci 297d9f0492fSopenharmony_ci // Filter by hook 298d9f0492fSopenharmony_ci filter.name = name; 299d9f0492fSopenharmony_ci filter.value = value; 300d9f0492fSopenharmony_ci filter.ignored = 0; 301d9f0492fSopenharmony_ci HookMgrExecute(GetBootStageHookMgr(), INIT_PARAM_LOAD_FILTER, (void *)&filter, NULL); 302d9f0492fSopenharmony_ci 303d9f0492fSopenharmony_ci if (filter.ignored) { 304d9f0492fSopenharmony_ci PARAM_LOGV("Default parameter [%s] [%s] ignored", name, value); 305d9f0492fSopenharmony_ci return 0; 306d9f0492fSopenharmony_ci } 307d9f0492fSopenharmony_ci#endif 308d9f0492fSopenharmony_ci 309d9f0492fSopenharmony_ci PARAM_LOGV("Add default parameter [%s] [%s]", name, value); 310d9f0492fSopenharmony_ci return WriteParam(name, value, NULL, mode & LOAD_PARAM_ONLY_ADD); 311d9f0492fSopenharmony_ci} 312d9f0492fSopenharmony_ci 313d9f0492fSopenharmony_cistatic int LoadFileFromImport(char *target, uint32_t mode) 314d9f0492fSopenharmony_ci{ 315d9f0492fSopenharmony_ci if (strstr(target, ".para.dac")) { 316d9f0492fSopenharmony_ci LoadSecurityLabel(target); 317d9f0492fSopenharmony_ci } else { 318d9f0492fSopenharmony_ci LoadDefaultParams(target, mode); 319d9f0492fSopenharmony_ci } 320d9f0492fSopenharmony_ci return 0; 321d9f0492fSopenharmony_ci} 322d9f0492fSopenharmony_ci 323d9f0492fSopenharmony_ci// Content format of .import.para is "import /dir/param.para" 324d9f0492fSopenharmony_ci// Use ${} to pass parameter like "import /dir/${const.product.productid}.para" 325d9f0492fSopenharmony_cistatic int LoadParamFromImport_(char *buffer, const int buffSize, uint32_t mode) 326d9f0492fSopenharmony_ci{ 327d9f0492fSopenharmony_ci int spaceCount = 0; 328d9f0492fSopenharmony_ci while (*(buffer + IMPORT_PREFIX_LEN + spaceCount) == ' ') { 329d9f0492fSopenharmony_ci spaceCount++; 330d9f0492fSopenharmony_ci } 331d9f0492fSopenharmony_ci char *target = calloc(PATH_MAX, 1); 332d9f0492fSopenharmony_ci PARAM_CHECK(target != NULL, return -1, "Failed to alloc memory"); 333d9f0492fSopenharmony_ci if (strncpy_s(target, PATH_MAX, buffer + IMPORT_PREFIX_LEN + spaceCount, buffSize) != 0) { 334d9f0492fSopenharmony_ci PARAM_LOGE("Failed to get value of import."); 335d9f0492fSopenharmony_ci free(target); 336d9f0492fSopenharmony_ci return -1; 337d9f0492fSopenharmony_ci } 338d9f0492fSopenharmony_ci char *tmp = NULL; 339d9f0492fSopenharmony_ci if ((tmp = strstr(target, "\n"))) { 340d9f0492fSopenharmony_ci *tmp = '\0'; 341d9f0492fSopenharmony_ci } 342d9f0492fSopenharmony_ci char *tmpParamValue = calloc(PARAM_VALUE_LEN_MAX + 1, sizeof(char)); 343d9f0492fSopenharmony_ci if (tmpParamValue == NULL) { 344d9f0492fSopenharmony_ci PARAM_LOGE("Failed to alloc memory"); 345d9f0492fSopenharmony_ci free(target); 346d9f0492fSopenharmony_ci return -1; 347d9f0492fSopenharmony_ci } 348d9f0492fSopenharmony_ci int ret = GetParamValue(target, strlen(target), tmpParamValue, PARAM_VALUE_LEN_MAX); 349d9f0492fSopenharmony_ci if (ret == 0) { 350d9f0492fSopenharmony_ci LoadFileFromImport(tmpParamValue, mode); 351d9f0492fSopenharmony_ci } 352d9f0492fSopenharmony_ci PARAM_LOGI("Load params from import %s return %d.", tmpParamValue, ret); 353d9f0492fSopenharmony_ci free(tmpParamValue); 354d9f0492fSopenharmony_ci free(target); 355d9f0492fSopenharmony_ci return ret; 356d9f0492fSopenharmony_ci} 357d9f0492fSopenharmony_ci 358d9f0492fSopenharmony_cistatic int LoadParamFromImport(const char *fileName, void *context) 359d9f0492fSopenharmony_ci{ 360d9f0492fSopenharmony_ci char realPath[PATH_MAX] = ""; 361d9f0492fSopenharmony_ci realpath(fileName, realPath); 362d9f0492fSopenharmony_ci FILE *fp = fopen(realPath, "r"); 363d9f0492fSopenharmony_ci if (fp == NULL) { 364d9f0492fSopenharmony_ci PARAM_LOGE("Failed to open file '%s' error:%d ", fileName, errno); 365d9f0492fSopenharmony_ci return -1; 366d9f0492fSopenharmony_ci } 367d9f0492fSopenharmony_ci 368d9f0492fSopenharmony_ci const int buffSize = PATH_MAX; 369d9f0492fSopenharmony_ci char *buffer = calloc(buffSize, sizeof(char)); 370d9f0492fSopenharmony_ci PARAM_CHECK(buffer != NULL, (void)fclose(fp); 371d9f0492fSopenharmony_ci return -1, "Failed to alloc memory"); 372d9f0492fSopenharmony_ci 373d9f0492fSopenharmony_ci uint32_t mode = *(int *)context; 374d9f0492fSopenharmony_ci while (fgets(buffer, buffSize, fp) != NULL) { 375d9f0492fSopenharmony_ci buffer[buffSize - 1] = '\0'; 376d9f0492fSopenharmony_ci if (!strncmp(buffer, "import ", IMPORT_PREFIX_LEN)) { 377d9f0492fSopenharmony_ci (void)LoadParamFromImport_(buffer, buffSize, mode); 378d9f0492fSopenharmony_ci } 379d9f0492fSopenharmony_ci } 380d9f0492fSopenharmony_ci (void)fclose(fp); 381d9f0492fSopenharmony_ci free(buffer); 382d9f0492fSopenharmony_ci return 0; 383d9f0492fSopenharmony_ci} 384d9f0492fSopenharmony_ci 385d9f0492fSopenharmony_cistatic int LoadDefaultParam_(const char *fileName, uint32_t mode, 386d9f0492fSopenharmony_ci const char *exclude[], uint32_t count, int (*loadOneParam)(const uint32_t *, const char *, const char *)) 387d9f0492fSopenharmony_ci{ 388d9f0492fSopenharmony_ci uint32_t paramNum = 0; 389d9f0492fSopenharmony_ci char realPath[PATH_MAX] = ""; 390d9f0492fSopenharmony_ci realpath(fileName, realPath); 391d9f0492fSopenharmony_ci FILE *fp = fopen(realPath, "r"); 392d9f0492fSopenharmony_ci if (fp == NULL) { 393d9f0492fSopenharmony_ci PARAM_LOGW("Failed to open file '%s' error:%d ", fileName, errno); 394d9f0492fSopenharmony_ci return -1; 395d9f0492fSopenharmony_ci } 396d9f0492fSopenharmony_ci 397d9f0492fSopenharmony_ci const int buffSize = PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX + 10; // 10 max len 398d9f0492fSopenharmony_ci char *buffer = calloc(buffSize, sizeof(char)); 399d9f0492fSopenharmony_ci PARAM_CHECK(buffer != NULL, (void)fclose(fp); 400d9f0492fSopenharmony_ci return -1, "Failed to alloc memory"); 401d9f0492fSopenharmony_ci 402d9f0492fSopenharmony_ci while (fgets(buffer, buffSize, fp) != NULL) { 403d9f0492fSopenharmony_ci buffer[buffSize - 1] = '\0'; 404d9f0492fSopenharmony_ci int ret = SplitParamString(buffer, exclude, count, loadOneParam, &mode); 405d9f0492fSopenharmony_ci PARAM_ONLY_CHECK(ret != PARAM_DEFAULT_PARAM_MEMORY_NOT_ENOUGH, 406d9f0492fSopenharmony_ci (void)fclose(fp); free(buffer); return PARAM_DEFAULT_PARAM_MEMORY_NOT_ENOUGH); 407d9f0492fSopenharmony_ci if (mode == LOAD_PARAM_ONLY_ADD && ret == PARAM_CODE_READ_ONLY) { 408d9f0492fSopenharmony_ci PARAM_WARNING_CHECK(ret == 0, continue, "Set param '%s' error:%d with only add mode", buffer, ret); 409d9f0492fSopenharmony_ci } else { 410d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, continue, "Failed to set param '%s' error:%d ", buffer, ret); 411d9f0492fSopenharmony_ci } 412d9f0492fSopenharmony_ci paramNum++; 413d9f0492fSopenharmony_ci } 414d9f0492fSopenharmony_ci (void)fclose(fp); 415d9f0492fSopenharmony_ci free(buffer); 416d9f0492fSopenharmony_ci PARAM_LOGV("Load %u default parameters success from %s.", paramNum, fileName); 417d9f0492fSopenharmony_ci return 0; 418d9f0492fSopenharmony_ci} 419d9f0492fSopenharmony_ci 420d9f0492fSopenharmony_cistatic int ProcessParamFile(const char *fileName, void *context) 421d9f0492fSopenharmony_ci{ 422d9f0492fSopenharmony_ci static const char *exclude[] = {"ctl.", "selinux.restorecon_recursive"}; 423d9f0492fSopenharmony_ci uint32_t mode = *(int *)context; 424d9f0492fSopenharmony_ci int ret = LoadDefaultParam_(fileName, mode, exclude, ARRAY_LENGTH(exclude), LoadOneParam_); 425d9f0492fSopenharmony_ci if (ret == PARAM_DEFAULT_PARAM_MEMORY_NOT_ENOUGH) { 426d9f0492fSopenharmony_ci PARAM_LOGE("[startup_failed]default_param memory is not enough, system reboot! %d", SYS_PARAM_INIT_FAILED); 427d9f0492fSopenharmony_ci ExecReboot("panic"); 428d9f0492fSopenharmony_ci } 429d9f0492fSopenharmony_ci return ret; 430d9f0492fSopenharmony_ci} 431d9f0492fSopenharmony_ci 432d9f0492fSopenharmony_ciint LoadParamsFile(const char *fileName, bool onlyAdd) 433d9f0492fSopenharmony_ci{ 434d9f0492fSopenharmony_ci return LoadDefaultParams(fileName, onlyAdd ? LOAD_PARAM_ONLY_ADD : LOAD_PARAM_NORMAL); 435d9f0492fSopenharmony_ci} 436d9f0492fSopenharmony_ci 437d9f0492fSopenharmony_ciint LoadDefaultParams(const char *fileName, uint32_t mode) 438d9f0492fSopenharmony_ci{ 439d9f0492fSopenharmony_ci PARAM_CHECK(fileName != NULL, return -1, "Invalid filename for load"); 440d9f0492fSopenharmony_ci PARAM_LOGI("Load default parameters from %s.", fileName); 441d9f0492fSopenharmony_ci struct stat st; 442d9f0492fSopenharmony_ci if ((stat(fileName, &st) == 0) && !S_ISDIR(st.st_mode)) { 443d9f0492fSopenharmony_ci if (strstr(fileName, ".para.dac")) { 444d9f0492fSopenharmony_ci return LoadSecurityLabel(fileName); 445d9f0492fSopenharmony_ci } else { 446d9f0492fSopenharmony_ci return ProcessParamFile(fileName, &mode); 447d9f0492fSopenharmony_ci } 448d9f0492fSopenharmony_ci } else { 449d9f0492fSopenharmony_ci (void)ReadFileInDir(fileName, ".para", ProcessParamFile, &mode); 450d9f0492fSopenharmony_ci (void)ReadFileInDir(fileName, ".para.import", LoadParamFromImport, &mode); 451d9f0492fSopenharmony_ci return LoadSecurityLabel(fileName); 452d9f0492fSopenharmony_ci } 453d9f0492fSopenharmony_ci} 454d9f0492fSopenharmony_ci 455d9f0492fSopenharmony_ciINIT_LOCAL_API void LoadParamFromBuild(void) 456d9f0492fSopenharmony_ci{ 457d9f0492fSopenharmony_ci PARAM_LOGI("load parameters from build "); 458d9f0492fSopenharmony_ci#ifdef INCREMENTAL_VERSION 459d9f0492fSopenharmony_ci if (strlen(INCREMENTAL_VERSION) > 0) { 460d9f0492fSopenharmony_ci WriteParam("const.product.incremental.version", INCREMENTAL_VERSION, NULL, LOAD_PARAM_NORMAL); 461d9f0492fSopenharmony_ci } 462d9f0492fSopenharmony_ci#endif 463d9f0492fSopenharmony_ci#ifdef BUILD_TYPE 464d9f0492fSopenharmony_ci if (strlen(BUILD_TYPE) > 0) { 465d9f0492fSopenharmony_ci WriteParam("const.product.build.type", BUILD_TYPE, NULL, LOAD_PARAM_NORMAL); 466d9f0492fSopenharmony_ci } 467d9f0492fSopenharmony_ci#endif 468d9f0492fSopenharmony_ci#ifdef BUILD_USER 469d9f0492fSopenharmony_ci if (strlen(BUILD_USER) > 0) { 470d9f0492fSopenharmony_ci WriteParam("const.product.build.user", BUILD_USER, NULL, LOAD_PARAM_NORMAL); 471d9f0492fSopenharmony_ci } 472d9f0492fSopenharmony_ci#endif 473d9f0492fSopenharmony_ci#ifdef BUILD_TIME 474d9f0492fSopenharmony_ci if (strlen(BUILD_TIME) > 0) { 475d9f0492fSopenharmony_ci WriteParam("const.product.build.date", BUILD_TIME, NULL, LOAD_PARAM_NORMAL); 476d9f0492fSopenharmony_ci } 477d9f0492fSopenharmony_ci#endif 478d9f0492fSopenharmony_ci#ifdef BUILD_HOST 479d9f0492fSopenharmony_ci if (strlen(BUILD_HOST) > 0) { 480d9f0492fSopenharmony_ci WriteParam("const.product.build.host", BUILD_HOST, NULL, LOAD_PARAM_NORMAL); 481d9f0492fSopenharmony_ci } 482d9f0492fSopenharmony_ci#endif 483d9f0492fSopenharmony_ci#ifdef BUILD_ROOTHASH 484d9f0492fSopenharmony_ci if (strlen(BUILD_ROOTHASH) > 0) { 485d9f0492fSopenharmony_ci WriteParam("const.ohos.buildroothash", BUILD_ROOTHASH, NULL, LOAD_PARAM_NORMAL); 486d9f0492fSopenharmony_ci } 487d9f0492fSopenharmony_ci#endif 488d9f0492fSopenharmony_ci} 489d9f0492fSopenharmony_ci 490d9f0492fSopenharmony_cistatic int LoadOneParamAreaSize_(const uint32_t *context, const char *name, const char *value) 491d9f0492fSopenharmony_ci{ 492d9f0492fSopenharmony_ci uint32_t size = (uint32_t)strtoul(value, NULL, DECIMAL_BASE); 493d9f0492fSopenharmony_ci PARAM_LOGV("LoadOneParamAreaSize_ [%s] [%s]", name, value); 494d9f0492fSopenharmony_ci ParamWorkSpace *paramSpace = GetParamWorkSpace(); 495d9f0492fSopenharmony_ci PARAM_CHECK(paramSpace != NULL && paramSpace->workSpace != NULL, 496d9f0492fSopenharmony_ci return -1, "Invalid workspace name %s", name); 497d9f0492fSopenharmony_ci WorkSpaceSize *spaceSize = GetWorkSpaceSize(GetWorkSpace(WORKSPACE_INDEX_SIZE)); 498d9f0492fSopenharmony_ci PARAM_CHECK(spaceSize != NULL, return PARAM_CODE_ERROR, "Failed to get workspace size"); 499d9f0492fSopenharmony_ci static char buffer[SELINUX_CONTENT_LEN] = {0}; 500d9f0492fSopenharmony_ci int ret = snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "u:object_r:%s:s0", name); 501d9f0492fSopenharmony_ci PARAM_CHECK(ret > 0, return PARAM_CODE_ERROR, "Failed to snprintf workspace name"); 502d9f0492fSopenharmony_ci 503d9f0492fSopenharmony_ci for (uint32_t i = WORKSPACE_INDEX_BASE + 1; i < spaceSize->maxLabelIndex; i++) { 504d9f0492fSopenharmony_ci if (paramSpace->workSpace[i] == NULL) { 505d9f0492fSopenharmony_ci continue; 506d9f0492fSopenharmony_ci } 507d9f0492fSopenharmony_ci if (strcmp(paramSpace->workSpace[i]->fileName, buffer) == 0) { 508d9f0492fSopenharmony_ci spaceSize->spaceSize[i] = size; 509d9f0492fSopenharmony_ci paramSpace->workSpace[i]->spaceSize = size; 510d9f0492fSopenharmony_ci break; 511d9f0492fSopenharmony_ci } 512d9f0492fSopenharmony_ci } 513d9f0492fSopenharmony_ci return 0; 514d9f0492fSopenharmony_ci} 515d9f0492fSopenharmony_ci 516d9f0492fSopenharmony_ciINIT_LOCAL_API void LoadParamAreaSize(void) 517d9f0492fSopenharmony_ci{ 518d9f0492fSopenharmony_ci LoadDefaultParam_("/sys_prod/etc/param/ohos.para.size", 0, NULL, 0, LoadOneParamAreaSize_); 519d9f0492fSopenharmony_ci LoadDefaultParam_(PARAM_AREA_SIZE_CFG, 0, NULL, 0, LoadOneParamAreaSize_); 520d9f0492fSopenharmony_ci} 521