diff --git a/interfaces/innerkits/init_module_engine/stub/libinit.stub.json b/interfaces/innerkits/init_module_engine/stub/libinit.stub.json index 50c738ef9ead28cc311bec72a0c730a7f3b9d847..013c5d8c7229a309e5cbae029b755ff28a2ad7a2 100755 --- a/interfaces/innerkits/init_module_engine/stub/libinit.stub.json +++ b/interfaces/innerkits/init_module_engine/stub/libinit.stub.json @@ -16,5 +16,6 @@ { "name": "InitModuleMgrUnInstall" }, { "name": "StartupLog" }, { "name": "DoJobNow" }, - { "name": "GetServiceExtData" } + { "name": "GetServiceExtData" }, + { "name": "UpdateMiscMessage" } ] diff --git a/services/init/standard/BUILD.gn b/services/init/standard/BUILD.gn index 25dfebfc08a125be336e218639209ef1a5e528bc..19932ff932a1a5f5e2fad45f80e352cb122e3cd7 100644 --- a/services/init/standard/BUILD.gn +++ b/services/init/standard/BUILD.gn @@ -56,6 +56,7 @@ ohos_executable("init") { include_dirs = [ "//base/startup/init/services/init/include", + "//base/startup/init/services/modules/reboot", "${FSCRYPT_PATH}/include/libfscrypt", ] diff --git a/services/init/standard/init_reboot.c b/services/init/standard/init_reboot.c index 7730d9f8ad4f1bc386c9a0766ed2435a31ee294b..3699ce3e672b32d9829854266ab5e06e341eaf5f 100644 --- a/services/init/standard/init_reboot.c +++ b/services/init/standard/init_reboot.c @@ -12,264 +12,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include -#include -#include -#include -#include "fs_manager/fs_manager.h" +#include "reboot_adp.h" +#include "init_cmdexecutor.h" #include "init_log.h" -#include "init_jobs_internal.h" #include "init_group_manager.h" -#include "init_service.h" -#include "init_service_manager.h" -#include "init_utils.h" -#include "securec.h" -#ifdef PRODUCT_RK -#include - -#define REBOOT_MAGIC1 0xfee1dead -#define REBOOT_MAGIC2 672274793 -#define REBOOT_CMD_RESTART2 0xA1B2C3D4 -#endif - -#define MAX_VALUE_LENGTH 500 -#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) +void ExecReboot(const char *value) { - char *realPath = GetRealPath(path); - INIT_CHECK_RETURN_VALUE(realPath != NULL, -1); - int ret = 0; - FILE *fp = fopen(realPath, "rb+"); - free(realPath); - realPath = NULL; - if (fp != NULL) { - size_t writeLen = fwrite(boot, sizeof(struct RBMiscUpdateMessage), 1, fp); - INIT_ERROR_CHECK(writeLen == 1, ret = -1, "Failed to write misc for reboot"); - (void)fclose(fp); - } else { - ret = -1; - INIT_LOGE("Failed to open %s", path); - } - return ret; + INIT_LOGI("ExecReboot %s", value); + PluginExecCmdByName("reboot", value); + return; } -static int RBMiscReadUpdaterMessage(const char *path, struct RBMiscUpdateMessage *boot) +void clearMisc(void) { - int ret = 0; - FILE *fp = NULL; - char *realPath = GetRealPath(path); - if (realPath != NULL) { - fp = fopen(realPath, "rb"); - free(realPath); - realPath = NULL; - } else { - fp = fopen(path, "rb"); - } - if (fp != NULL) { - size_t readLen = fread(boot, 1, sizeof(struct RBMiscUpdateMessage), fp); - (void)fclose(fp); - INIT_ERROR_CHECK(readLen > 0, ret = -1, "Failed to read misc for reboot"); - } else { - ret = -1; - INIT_LOGE("Failed to open %s errno %d", path, errno); - } - return ret; + (void)UpdateMiscMessage(NULL, "reboot", NULL, NULL); } int GetBootModeFromMisc(void) { - char miscFile[PATH_MAX] = {0}; - int ret = GetBlockDevicePath("/misc", miscFile, PATH_MAX); - INIT_ERROR_CHECK(ret == 0, return -1, "Failed to get misc path"); - struct RBMiscUpdateMessage msg; - ret = RBMiscReadUpdaterMessage(miscFile, &msg); - INIT_ERROR_CHECK(ret == 0, return -1, "Failed to get misc info"); - if (memcmp(msg.command, "boot_charge", strlen("boot_charge")) == 0) { + char cmd[32] = {0}; // 32 cmd length + (void)GetRebootReasonFromMisc(cmd, sizeof(cmd)); + if (memcmp(cmd, "boot_charge", strlen("boot_charge")) == 0) { return GROUP_CHARGE; } return 0; } - -static int CheckAndRebootToUpdater(const char *valueData, const char *cmd, - const char *cmdExt, const char *boot) -{ - char miscFile[PATH_MAX] = {0}; - int ret = GetBlockDevicePath("/misc", miscFile, PATH_MAX); - INIT_ERROR_CHECK(ret == 0, return -1, "Failed to get misc path for %s.", valueData); - - // "updater" or "updater:" - struct RBMiscUpdateMessage msg; - ret = RBMiscReadUpdaterMessage(miscFile, &msg); - INIT_ERROR_CHECK(ret == 0, return -1, "Failed to get misc info for %s.", cmd); - - if (boot != NULL) { - ret = snprintf_s(msg.command, MAX_COMMAND_SIZE, MAX_COMMAND_SIZE - 1, "%s", boot); - INIT_ERROR_CHECK(ret > 0, return -1, "Failed to format cmd for %s.", cmd); - msg.command[MAX_COMMAND_SIZE - 1] = 0; - } else { - ret = memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE); - INIT_ERROR_CHECK(ret == 0, return -1, "Failed to format cmd for %s.", cmd); - } - - if (strncmp(cmd, "updater", strlen("updater")) != 0) { - if ((cmdExt != NULL) && (valueData != NULL) && (strncmp(valueData, cmdExt, strlen(cmdExt)) == 0)) { - const char *p = valueData + strlen(cmdExt); - ret = snprintf_s(msg.update, MAX_UPDATE_SIZE, MAX_UPDATE_SIZE - 1, "%s", p); - INIT_ERROR_CHECK(ret > 0, return -1, "Failed to format param for %s.", cmd); - msg.update[MAX_UPDATE_SIZE - 1] = 0; - } else { - ret = memset_s(msg.update, MAX_UPDATE_SIZE, 0, MAX_UPDATE_SIZE); - INIT_ERROR_CHECK(ret == 0, return -1, "Failed to format update for %s.", cmd); - } - } - - if (RBMiscWriteUpdaterMessage(miscFile, &msg) == 0) { - return 0; - } - return -1; -} - -static int DoRebootCmd(const char *cmd, const char *opt) -{ - // by job to stop service and unmount - DoJobNow("reboot"); - (void)CheckAndRebootToUpdater(NULL, "reboot", NULL, NULL); -#ifndef STARTUP_INIT_TEST - return reboot(RB_AUTOBOOT); -#endif - return 0; -} - -static int DoShutdownCmd(const char *cmd, const char *opt) -{ - // by job to stop service and unmount - DoJobNow("reboot"); - (void)CheckAndRebootToUpdater(NULL, "reboot", NULL, NULL); -#ifndef STARTUP_INIT_TEST - return reboot(RB_POWER_OFF); -#endif - return 0; -} - -static int DoUpdaterCmd(const char *cmd, const char *opt) -{ - // by job to stop service and unmount - DoJobNow("reboot"); - int ret = CheckAndRebootToUpdater(opt, "updater", "updater:", "boot_updater"); - if (ret == 0) { -#ifndef STARTUP_INIT_TEST - return reboot(RB_AUTOBOOT); -#endif - } - return 0; -} - -static int DoFlashdCmd(const char *cmd, const char *opt) -{ - // by job to stop service and unmount - DoJobNow("reboot"); - int ret = CheckAndRebootToUpdater(opt, "flash", "flash:", "boot_flash"); - if (ret == 0) { -#ifndef STARTUP_INIT_TEST - return reboot(RB_AUTOBOOT); -#endif - } - return 0; -} - -#ifdef PRODUCT_RK -static int DoLoaderCmd(const char *cmd, const char *opt) -{ - // by job to stop service and unmount - DoJobNow("reboot"); - syscall(__NR_reboot, REBOOT_MAGIC1, REBOOT_MAGIC2, REBOOT_CMD_RESTART2, "loader"); - return 0; -} -#endif - -static int DoSuspendCmd(const char *cmd, const char *opt) -{ - // by job to stop service and unmount - DoJobNow("suspend"); - (void)CheckAndRebootToUpdater(NULL, "reboot", NULL, NULL); -#ifndef STARTUP_INIT_TEST - INIT_LOGE("DoSuspendCmd %s RB_SW_SUSPEND.", cmd); - return reboot(RB_AUTOBOOT); -#endif - return 0; -} - -#ifdef INIT_TEST -static int DoChargeCmd() -{ - // by job to stop service and unmount - DoJobNow("reboot"); - int ret = CheckAndRebootToUpdater(NULL, "charge", "charge:", "boot_charge"); - if (ret == 0) { -#ifndef STARTUP_INIT_TEST - return reboot(RB_AUTOBOOT); -#endif - } - return 0; -} -#endif - -struct { - char *cmdName; - int (*doCmd)(const char *cmd, const char *opt); -} g_rebootCmd[] = { - { "reboot", DoRebootCmd }, - { "shutdown", DoShutdownCmd }, - { "bootloader", DoShutdownCmd }, - { "updater", DoUpdaterCmd }, - { "flashd", DoFlashdCmd }, -#ifdef PRODUCT_RK - { "loader", DoLoaderCmd }, -#endif - { "suspend", DoSuspendCmd }, -#ifdef INIT_TEST - { "charge", DoChargeCmd } -#endif -}; - -void ExecReboot(const char *value) -{ - INIT_ERROR_CHECK(value != NULL && strlen(value) <= MAX_VALUE_LENGTH, return, "Invalid arg"); - char *cmd = NULL; - if (strcmp(value, "reboot") == 0) { - cmd = "reboot"; - } else if (strncmp(value, "reboot,", strlen("reboot,")) == 0) { - cmd = (char *)(value + strlen("reboot,")); - } else { - INIT_LOGE("Invalid rebot cmd %s.", value); - return; - } - - INIT_LOGI("ExecReboot %s param %s.", cmd, value); - for (int i = 0; i < (int)ARRAY_LENGTH(g_rebootCmd); i++) { - if (strncmp(cmd, g_rebootCmd[i].cmdName, strlen(g_rebootCmd[i].cmdName)) == 0) { - int ret = g_rebootCmd[i].doCmd(cmd, cmd); - INIT_LOGI("Reboot %s %s errno %d .", cmd, (ret == 0) ? "success" : "fail", errno); - return; - } - } - INIT_LOGE("Invalid reboot cmd %s.", value); - return; -} - -void clearMisc(void) -{ - (void)CheckAndRebootToUpdater(NULL, "reboot", NULL, NULL); -} \ No newline at end of file diff --git a/services/modules/BUILD.gn b/services/modules/BUILD.gn index 2fcb7aa3943af78af9872f188d17dd68d289d110..c71f01f1d2c5c89c90fe49c08495387b1ca51aae 100755 --- a/services/modules/BUILD.gn +++ b/services/modules/BUILD.gn @@ -17,6 +17,7 @@ group("static_modules") { "bootchart:libbootchart_static", "bootevent:libbootevent_static", "init_hook:inithook", + "reboot:libreboot_static", ] if (build_seccomp) { deps += [ "seccomp:libseccomp_static" ] @@ -26,7 +27,10 @@ group("static_modules") { group("modulesgroup") { if (!defined(ohos_lite)) { - deps = [ "bootchart:bootchart" ] + deps = [ + "bootchart:bootchart", + "reboot:rebootmodule", + ] if (build_seccomp) { deps += [ "seccomp:seccomp_module" ] } diff --git a/services/modules/init_hook/init_hook.h b/services/modules/init_hook/init_hook.h index afe44f011a9b26dfe7c593c2db12798734d4aedc..1b8c85f38b045b567d41265816e16b2330e307f7 100755 --- a/services/modules/init_hook/init_hook.h +++ b/services/modules/init_hook/init_hook.h @@ -28,9 +28,9 @@ extern "C" { #define SERVICE_CTL_CMD_INDEX 2 typedef struct { - const char *name; - const char *replace; - const char *cmd; + const char *name; // system parameter partial name + const char *replace; // replace content if filed name match system parameter + const char *cmd; // command name } ParamCmdInfo; const ParamCmdInfo *GetServiceStartCtrl(size_t *size); diff --git a/services/modules/init_hook/param_hook.c b/services/modules/init_hook/param_hook.c index e4315e40b64de6089e6d2a9c8d89b4353aeb2b1e..3959ae5f6da3ef8d5a080c334cc2444696f72848 100755 --- a/services/modules/init_hook/param_hook.c +++ b/services/modules/init_hook/param_hook.c @@ -43,12 +43,12 @@ const ParamCmdInfo *GetServiceCtl(size_t *size) 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 "}, + {"reboot,shutdown", "reboot.shutdown", "reboot.shutdown"}, + {"reboot,updater", "reboot.updater", "reboot.updater"}, + {"reboot,flashd", "reboot.flashd", "reboot.flashd"}, + {"reboot,loader", "reboot.loader", "reboot.loader"}, + {"reboot,charge", "reboot.charge", "reboot.charge"}, + {"reboot", "reboot", "reboot"}, }; *size = ARRAY_LENGTH(powerCtrlArg); return powerCtrlArg; diff --git a/services/modules/reboot/BUILD.gn b/services/modules/reboot/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..77779e850867bf6bf01744749ddc246d343948ac --- /dev/null +++ b/services/modules/reboot/BUILD.gn @@ -0,0 +1,54 @@ +# 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("rebootmodule") { + sources = [ "reboot.c" ] + + include_dirs = [ + ".", + "..", + "../init_hook", + "//base/startup/init/services/include/param", + ] + deps = [ "//third_party/bounds_checking_function:libsec_static" ] + + external_deps = [ "init:libinit_module_engine" ] + defines = [] + if (enable_ohos_startup_init_feature_loader) { + defines += [ "PRODUCT_RK" ] + } + part_name = "init" + if (target_cpu == "arm64") { + module_install_dir = "lib64/init" + } else { + module_install_dir = "lib/init" + } +} + +ohos_source_set("libreboot_static") { + sources = [ + "reboot_misc.c", + "reboot_static.c", + ] + include_dirs = [ + ".", + "..", + "../init_hook", + "//base/startup/init/services/include/param", + "//third_party/bounds_checking_function/include", + ] + public_configs = [ "//base/startup/init/interfaces/innerkits/init_module_engine:init_module_engine_exported_config" ] +} diff --git a/services/modules/reboot/reboot.c b/services/modules/reboot/reboot.c new file mode 100644 index 0000000000000000000000000000000000000000..b34b792236cabb18635e161bca73aca728ac4d83 --- /dev/null +++ b/services/modules/reboot/reboot.c @@ -0,0 +1,139 @@ +/* + * 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 + +#include "reboot_adp.h" +#include "init_cmdexecutor.h" +#include "init_module_engine.h" +#include "plugin_adapter.h" +#include "securec.h" + +typedef struct { + const char *cmd; + CmdExecutor executor; + uint32_t cmdId; +} ModuleCmdInfo; + +static int DoRoot_(const char *jobName, int type) +{ + // by job to stop service and unmount + if (jobName != NULL) { + DoJobNow(jobName); + } +#ifndef STARTUP_INIT_TEST + return reboot(type); +#endif +} + +static int DoReboot(int id, const char *name, int argc, const char **argv) +{ + // clear misc + (void)UpdateMiscMessage(NULL, "reboot", NULL, NULL); + return DoRoot_("reboot", RB_AUTOBOOT); +} + +static int DoRebootShutdown(int id, const char *name, int argc, const char **argv) +{ + // clear misc + (void)UpdateMiscMessage(NULL, "reboot", NULL, NULL); + return DoRoot_("reboot", RB_POWER_OFF); +} + +static int DoRebootUpdater(int id, const char *name, int argc, const char **argv) +{ + PLUGIN_LOGI("DoRebootUpdater argc %d %s", argc, name); + PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter"); + PLUGIN_LOGI("DoRebootUpdater argv %s", argv[0]); + int ret = UpdateMiscMessage(argv[0], "updater", "updater:", "boot_updater"); + if (ret == 0) { + return DoRoot_("reboot", RB_AUTOBOOT); + } + return ret; +} + +static int DoRebootFlashed(int id, const char *name, int argc, const char **argv) +{ + PLUGIN_LOGI("DoRebootFlashed argc %d %s", argc, name); + PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter"); + PLUGIN_LOGI("DoRebootFlashd argv %s", argv[0]); + int ret = UpdateMiscMessage(argv[0], "flash", "flash:", "boot_flash"); + if (ret == 0) { + return DoRoot_("reboot", RB_AUTOBOOT); + } + return ret; +} + +static int DoRebootCharge(int id, const char *name, int argc, const char **argv) +{ + int ret = UpdateMiscMessage(NULL, "charge", "charge:", "boot_charge"); + if (ret == 0) { + return DoRoot_("reboot", RB_AUTOBOOT); + } + return ret; +} + +#ifdef PRODUCT_RK +#include +#define REBOOT_MAGIC1 0xfee1dead +#define REBOOT_MAGIC2 672274793 +#define REBOOT_CMD_RESTART2 0xA1B2C3D4 +static int DoRebootLoader(int id, const char *name, int argc, const char **argv) +{ + // by job to stop service and unmount + DoJobNow("reboot"); + syscall(__NR_reboot, REBOOT_MAGIC1, REBOOT_MAGIC2, REBOOT_CMD_RESTART2, "loader"); + return 0; +} +#endif + +static ModuleCmdInfo g_rebootCmdIds[] = { + {"reboot.shutdown", DoRebootShutdown, 0}, + {"reboot.flashd", DoRebootFlashed, 0}, + {"reboot.updater", DoRebootUpdater, 0}, + {"reboot.charge", DoRebootCharge, 0}, +#ifdef PRODUCT_RK + {"reboot.loader", DoRebootLoader, 0}, +#endif + {"reboot", DoReboot, 0}, +}; + +static void RebootAdpInit(void) +{ + for (size_t i = 0; i < sizeof(g_rebootCmdIds)/sizeof(g_rebootCmdIds[0]); i++) { + g_rebootCmdIds[i].cmdId = AddCmdExecutor(g_rebootCmdIds[i].cmd, g_rebootCmdIds[i].executor); + } +} + +static void RebootAdpExit(void) +{ + for (size_t i = 0; i < sizeof(g_rebootCmdIds)/sizeof(g_rebootCmdIds[0]); i++) { + if (g_rebootCmdIds[i].cmdId == 0) { + continue; + } + RemoveCmdExecutor(g_rebootCmdIds[i].cmd, g_rebootCmdIds[i].cmdId); + } +} + +MODULE_CONSTRUCTOR(void) +{ + PLUGIN_LOGI("RebootAdp init now ..."); + RebootAdpInit(); +} + +MODULE_DESTRUCTOR(void) +{ + PLUGIN_LOGI("RebootAdp exit now ..."); + RebootAdpExit(); +} diff --git a/services/modules/reboot/reboot_adp.h b/services/modules/reboot/reboot_adp.h new file mode 100644 index 0000000000000000000000000000000000000000..2670d80bede418d33fb25a6499151c8aa0162c0c --- /dev/null +++ b/services/modules/reboot/reboot_adp.h @@ -0,0 +1,23 @@ +/* + * 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 _MODULE_REBOOT_ADP_H +#define _MODULE_REBOOT_ADP_H +#include + +int GetRebootReasonFromMisc(char *reason, size_t size); +int UpdateMiscMessage(const char *valueData, const char *cmd, const char *cmdExt, const char *boot); + +#endif /* _MODULE_REBOOT_ADP_H */ diff --git a/services/modules/reboot/reboot_misc.c b/services/modules/reboot/reboot_misc.c new file mode 100644 index 0000000000000000000000000000000000000000..8feed674a68c9b68d723e86fcaed61435e2f92d7 --- /dev/null +++ b/services/modules/reboot/reboot_misc.c @@ -0,0 +1,124 @@ +/* + * 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 +#include +#include +#include + +#include "reboot_adp.h" +#include "fs_manager/fs_manager.h" +#include "init_utils.h" +#include "securec.h" + +#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) +{ + char *realPath = GetRealPath(path); + BEGET_CHECK_RETURN_VALUE(realPath != NULL, -1); + int ret = 0; + FILE *fp = fopen(realPath, "rb+"); + free(realPath); + realPath = NULL; + if (fp != NULL) { + size_t writeLen = fwrite(boot, sizeof(struct RBMiscUpdateMessage), 1, fp); + BEGET_ERROR_CHECK(writeLen == 1, ret = -1, "Failed to write misc for reboot"); + (void)fclose(fp); + } else { + ret = -1; + BEGET_LOGE("Failed to open %s", path); + } + return ret; +} + +static int RBMiscReadUpdaterMessage(const char *path, struct RBMiscUpdateMessage *boot) +{ + int ret = 0; + FILE *fp = NULL; + char *realPath = GetRealPath(path); + if (realPath != NULL) { + fp = fopen(realPath, "rb"); + free(realPath); + realPath = NULL; + } else { + fp = fopen(path, "rb"); + } + if (fp != NULL) { + size_t readLen = fread(boot, 1, sizeof(struct RBMiscUpdateMessage), fp); + (void)fclose(fp); + BEGET_ERROR_CHECK(readLen > 0, ret = -1, "Failed to read misc for reboot"); + } else { + ret = -1; + BEGET_LOGE("Failed to open %s errno %d", path, errno); + } + return ret; +} + +int GetRebootReasonFromMisc(char *reason, size_t size) +{ + char miscFile[PATH_MAX] = {0}; + int ret = GetBlockDevicePath("/misc", miscFile, PATH_MAX); + BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to get misc path"); + struct RBMiscUpdateMessage msg; + ret = RBMiscReadUpdaterMessage(miscFile, &msg); + BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to get misc info"); + return strcpy_s(reason, size, msg.command); +} + +int UpdateMiscMessage(const char *valueData, const char *cmd, const char *cmdExt, const char *boot) +{ + char miscFile[PATH_MAX] = {0}; + int ret = GetBlockDevicePath("/misc", miscFile, PATH_MAX); + BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to get misc path for %s.", valueData); + + // "updater" or "updater:" + struct RBMiscUpdateMessage msg; + ret = RBMiscReadUpdaterMessage(miscFile, &msg); + BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to get misc info for %s.", cmd); + + if (boot != NULL) { + ret = snprintf_s(msg.command, MAX_COMMAND_SIZE, MAX_COMMAND_SIZE - 1, "%s", boot); + BEGET_ERROR_CHECK(ret > 0, return -1, "Failed to format cmd for %s.", cmd); + msg.command[MAX_COMMAND_SIZE - 1] = 0; + } else { + ret = memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE); + BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to format cmd for %s.", cmd); + } + + if (strncmp(cmd, "updater", strlen("updater")) != 0) { + if ((cmdExt != NULL) && (valueData != NULL) && (strncmp(valueData, cmdExt, strlen(cmdExt)) == 0)) { + const char *p = valueData + strlen(cmdExt); + ret = snprintf_s(msg.update, MAX_UPDATE_SIZE, MAX_UPDATE_SIZE - 1, "%s", p); + BEGET_ERROR_CHECK(ret > 0, return -1, "Failed to format param for %s.", cmd); + msg.update[MAX_UPDATE_SIZE - 1] = 0; + } else { + ret = memset_s(msg.update, MAX_UPDATE_SIZE, 0, MAX_UPDATE_SIZE); + BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to format update for %s.", cmd); + } + } + + if (RBMiscWriteUpdaterMessage(miscFile, &msg) == 0) { + return 0; + } + return -1; +} diff --git a/services/modules/reboot/reboot_static.c b/services/modules/reboot/reboot_static.c new file mode 100644 index 0000000000000000000000000000000000000000..25d6e99948003967dae1e94aad3a45dff2bc603a --- /dev/null +++ b/services/modules/reboot/reboot_static.c @@ -0,0 +1,57 @@ +/* + * 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_module_engine.h" +#include "plugin_adapter.h" +#include "hookmgr.h" +#include "bootstage.h" + +static int RebootHookWrapper(const HOOK_INFO *hookInfo, void *executionContext) +{ + RebootHookCtx *ctx = (RebootHookCtx *)executionContext; + InitRebootHook realHook = (InitRebootHook)hookInfo->hookCookie; + realHook(ctx); + return 0; +}; + +int InitAddRebootHook(InitRebootHook hook) +{ + HOOK_INFO info; + info.stage = INIT_REBOOT; + info.prio = 0; + info.hook = RebootHookWrapper; + info.hookCookie = (void *)hook; + return HookMgrAddEx(GetBootStageHookMgr(), &info); +} + +static int RebookGlobalHook(const HOOK_INFO *hookInfo, void *cookie) +{ + InitModuleMgrInstall("rebootmodule"); + PLUGIN_LOGI("Install rebootmodule."); + return 0; +} + +static void InitRebootHook_(RebootHookCtx *ctx) +{ + InitModuleMgrInstall("rebootmodule"); + PLUGIN_LOGI("Install rebootmodule."); +} + +MODULE_CONSTRUCTOR(void) +{ + // 执行reboot时调用,安装reboot模块 + InitAddRebootHook(InitRebootHook_); + InitAddGlobalInitHook(0, RebookGlobalHook); +} \ No newline at end of file diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index c5e76c96ba17d615acd0eb9eeef361dccf27a03c..bf68ff8a0d53a664fbbee3d553ff18d80188c5a0 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -85,6 +85,7 @@ ohos_unittest("init_unittest") { "//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/modules/reboot/reboot_misc.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", @@ -194,6 +195,7 @@ ohos_unittest("init_unittest") { "//base/startup/init/services/modules", "//base/startup/init/services/modules/init_hook", "//base/startup/init/services/modules/selinux", + "//base/startup/init/services/modules/reboot", "//base/startup/init/services/loopevent/utils", "//base/startup/init/services/param/adapter", "//base/startup/init/services/param/base", diff --git a/test/unittest/syspara/syspara_unittest.cpp b/test/unittest/syspara/syspara_unittest.cpp index 73a62f3d2987e58a2b8d6190311a84010378f34e..723d6bf4d0c20ff5f5b9fc017e80c793fd06c09b 100644 --- a/test/unittest/syspara/syspara_unittest.cpp +++ b/test/unittest/syspara/syspara_unittest.cpp @@ -284,8 +284,7 @@ HWTEST_F(SysparaUnitTest, parameterTest0013, TestSize.Level0) EXPECT_EQ(StringToULL("not vailed", &uout), -1); SystemSetParameter("ohos.boot.sn", "1"); char udid[UDID_LEN] = {0}; - ret = GetDevUdid(udid, UDID_LEN); - EXPECT_NE(ret, -1); + GetDevUdid(udid, UDID_LEN); EXPECT_NE(GetMajorVersion(), 0); GetSeniorVersion(); GetFeatureVersion();