mirror of
https://gitee.com/openharmony/startup_init
synced 2025-02-25 23:15:38 +00:00
Bugfix: 拆分独立的init_early进程在ramdisk中使用
1)增加init_early完成第一阶段初始化:完成初始文件系统挂载,完成基础的dev节点创建,完成required fs的挂载 2)second stage过程的init去掉第一阶段相关代码,解除仅能静态链接的限制。 3)把init_early打包到ramdisk镜像中,并软链接为init 4)去掉early阶段读取系统参数的无效代码 Signed-off-by: handyohos <zhangxiaotian@huawei.com> Change-Id: I2225f15ade5004441f2acfc6754c29cf5b201f78 #I81HSS
This commit is contained in:
parent
77c8dc9e6a
commit
8b13fa5918
@ -295,16 +295,6 @@ 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};
|
||||
@ -334,21 +324,13 @@ static int GetSlotInfoFromBootctrl(off_t offset, off_t size)
|
||||
|
||||
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");
|
||||
int currentSlot = GetSlotInfoFromCmdLine("currentslot");
|
||||
BEGET_CHECK_RETURN_VALUE(currentSlot <= 0, currentSlot);
|
||||
BEGET_LOGI("No valid slot value found from cmdline, try to get it from bootctrl");
|
||||
|
||||
@ -468,6 +450,7 @@ int MountAllWithFstab(const Fstab *fstab, bool required)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (item = fstab->head; item != NULL; item = item->next) {
|
||||
rc = CheckRequiredAndMount(item, required);
|
||||
if (required && (rc < 0)) { // Init fail to mount in the first stage and exit directly.
|
||||
|
@ -32,6 +32,7 @@ group("startup_init") {
|
||||
deps = [
|
||||
"etc:etc_files",
|
||||
"init/standard:init",
|
||||
"init/standard:init_early",
|
||||
"//third_party/e2fsprogs:e2fsprogs",
|
||||
]
|
||||
|
||||
|
@ -27,8 +27,7 @@ extern "C" {
|
||||
#define DEV_RANDOM_MINOR 8
|
||||
#define DEV_URANDOM_MINOR 9
|
||||
|
||||
void MountBasicFs(void);
|
||||
void CreateDeviceNode(void);
|
||||
void CreateFsAndDeviceNode(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
|
@ -42,7 +42,6 @@ extern "C" {
|
||||
|
||||
void SystemInit(void);
|
||||
void LogInit(void);
|
||||
void SystemPrepare(long long uptime);
|
||||
void SystemConfig(const char *uptime);
|
||||
void SystemRun(void);
|
||||
void SystemExecuteRcs(void);
|
||||
|
@ -46,16 +46,16 @@ void LogInit(void)
|
||||
return;
|
||||
}
|
||||
|
||||
void SystemPrepare(long long uptime)
|
||||
{
|
||||
}
|
||||
|
||||
void ParseInitCfgByPriority(void)
|
||||
{
|
||||
ReadFileInDir(OTHER_CFG_PATH, ".cfg", ParseInitCfg, NULL);
|
||||
ReadFileInDir("/vendor/etc/init", ".cfg", ParseInitCfg, NULL);
|
||||
}
|
||||
|
||||
void CreateFsAndDeviceNode(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SystemConfig(const char *uptime)
|
||||
{
|
||||
InitServiceSpace();
|
||||
|
@ -16,13 +16,13 @@
|
||||
#include "init.h"
|
||||
#include "init_log.h"
|
||||
#include "init_utils.h"
|
||||
#include "device.h"
|
||||
|
||||
static const pid_t INIT_PROCESS_PID = 1;
|
||||
|
||||
int main(int argc, char * const argv[])
|
||||
{
|
||||
const char *uptime = NULL;
|
||||
long long upTimeInMicroSecs = 0;
|
||||
int isSecondStage = 0;
|
||||
(void)signal(SIGPIPE, SIG_IGN);
|
||||
// Number of command line parameters is 2
|
||||
@ -31,19 +31,20 @@ int main(int argc, char * const argv[])
|
||||
if (argc > 2) {
|
||||
uptime = argv[2];
|
||||
}
|
||||
} else {
|
||||
upTimeInMicroSecs = GetUptimeInMicroSeconds(NULL);
|
||||
}
|
||||
if (getpid() != INIT_PROCESS_PID) {
|
||||
INIT_LOGE("Process id error %d!", getpid());
|
||||
return 0;
|
||||
}
|
||||
EnableInitLog(INIT_INFO);
|
||||
|
||||
// Updater mode
|
||||
if (isSecondStage == 0) {
|
||||
SystemPrepare(upTimeInMicroSecs);
|
||||
} else {
|
||||
LogInit();
|
||||
CreateFsAndDeviceNode();
|
||||
}
|
||||
|
||||
LogInit();
|
||||
|
||||
SystemInit();
|
||||
SystemExecuteRcs();
|
||||
SystemConfig(uptime);
|
||||
|
@ -30,6 +30,37 @@ FSCRYPT_PATH =
|
||||
import("//build/ohos.gni")
|
||||
import("//build/ohos/native_stub/native_stub.gni")
|
||||
|
||||
ohos_executable("init_early") {
|
||||
sources = [
|
||||
"//base/startup/init/interfaces/innerkits/hookmgr/hookmgr.c",
|
||||
"//base/startup/init/services/log/init_commlog.c",
|
||||
"bootstagehooker.c",
|
||||
"device.c",
|
||||
"init_mount.c",
|
||||
"main_early.c",
|
||||
"switch_root.c",
|
||||
]
|
||||
include_dirs = [
|
||||
"//third_party/cJSON",
|
||||
"//base/startup/init/services/include",
|
||||
"//base/startup/init/services/init/include",
|
||||
"//base/startup/init/interfaces/innerkits/init_module_engine/include",
|
||||
]
|
||||
configs = [ "//build/config/gcc:symbol_visibility_hidden" ]
|
||||
deps = [
|
||||
"//base/startup/init/interfaces/innerkits/fs_manager:libfsmanager_static",
|
||||
"//base/startup/init/services/log:init_log",
|
||||
"//base/startup/init/ueventd:libueventd_ramdisk_static",
|
||||
"//third_party/bounds_checking_function:libsec_static",
|
||||
]
|
||||
if (startup_init_extra_static_modules != "") {
|
||||
deps += [ startup_init_extra_static_modules ]
|
||||
}
|
||||
install_images = [ "ramdisk" ]
|
||||
install_enable = true
|
||||
part_name = "init"
|
||||
}
|
||||
|
||||
ohos_executable("init") {
|
||||
sources = [
|
||||
"../adapter/init_adapter.c",
|
||||
@ -40,11 +71,10 @@ ohos_executable("init") {
|
||||
"../standard/init_cmds.c",
|
||||
"../standard/init_control_fd_service.c",
|
||||
"../standard/init_jobs.c",
|
||||
"../standard/init_mount.c",
|
||||
"../standard/init_reboot.c",
|
||||
"../standard/init_service.c",
|
||||
"../standard/init_signal_handler.c",
|
||||
"../standard/switch_root.c",
|
||||
"bootstagehooker.c",
|
||||
]
|
||||
|
||||
modulemgr_sources = [
|
||||
@ -66,6 +96,7 @@ ohos_executable("init") {
|
||||
"//base/startup/init/interfaces/innerkits/control_fd:libcontrolfd",
|
||||
"//base/startup/init/interfaces/innerkits/fd_holder:fdholder",
|
||||
"//base/startup/init/interfaces/innerkits/fs_manager:libfsmanager_static",
|
||||
"//base/startup/init/services/log:init_log",
|
||||
"//base/startup/init/services/loopevent:loopevent",
|
||||
"//base/startup/init/services/param/linux:param_init",
|
||||
"//base/startup/init/services/sandbox:sandbox",
|
||||
@ -74,7 +105,6 @@ ohos_executable("init") {
|
||||
deps += [ "//base/startup/init/services/param/base:param_base" ]
|
||||
|
||||
deps += [
|
||||
"//base/startup/init/ueventd:libueventd_ramdisk_static",
|
||||
"//third_party/bounds_checking_function:libsec_static",
|
||||
"//third_party/cJSON:cjson_static",
|
||||
]
|
||||
@ -152,7 +182,6 @@ ohos_executable("init") {
|
||||
install_images = [
|
||||
"system",
|
||||
"updater",
|
||||
"ramdisk",
|
||||
]
|
||||
install_enable = true
|
||||
part_name = "init"
|
||||
|
32
services/init/standard/bootstagehooker.c
Executable file
32
services/init/standard/bootstagehooker.c
Executable file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 "bootstage.h"
|
||||
|
||||
#define INIT_BOOTSTAGE_HOOK_NAME "bootstage"
|
||||
static HOOK_MGR *bootStageHookMgr = NULL;
|
||||
|
||||
HOOK_MGR *GetBootStageHookMgr()
|
||||
{
|
||||
if (bootStageHookMgr != NULL) {
|
||||
return bootStageHookMgr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create bootstage hook manager for booting only.
|
||||
* When boot completed, this manager will be destroyed.
|
||||
*/
|
||||
bootStageHookMgr = HookMgrCreate(INIT_BOOTSTAGE_HOOK_NAME);
|
||||
return bootStageHookMgr;
|
||||
}
|
@ -26,7 +26,7 @@
|
||||
#define DEFAULT_RW_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
|
||||
#define DEFAULT_NO_AUTHORITY_MODE (S_IWUSR | S_IRUSR)
|
||||
|
||||
void MountBasicFs(void)
|
||||
static void MountBasicFs(void)
|
||||
{
|
||||
if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755") != 0) {
|
||||
INIT_LOGE("Mount tmpfs failed. %s", strerror(errno));
|
||||
@ -66,7 +66,7 @@ void MountBasicFs(void)
|
||||
}
|
||||
}
|
||||
|
||||
void CreateDeviceNode(void)
|
||||
static void CreateDeviceNode(void)
|
||||
{
|
||||
if (mknod("/dev/null", S_IFCHR | DEFAULT_RW_MODE, makedev(MEM_MAJOR, DEV_NULL_MINOR)) != 0) {
|
||||
INIT_LOGE("Create /dev/null device node failed. %s", strerror(errno));
|
||||
@ -80,3 +80,23 @@ void CreateDeviceNode(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void EnableDevKmsg(void)
|
||||
{
|
||||
/* printk_devkmsg default value is ratelimit, We need to set "on" and remove the restrictions */
|
||||
int fd = open("/proc/sys/kernel/printk_devkmsg", O_WRONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
char *kmsgStatus = "on";
|
||||
write(fd, kmsgStatus, strlen(kmsgStatus) + 1);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
void CreateFsAndDeviceNode(void)
|
||||
{
|
||||
MountBasicFs();
|
||||
CreateDeviceNode();
|
||||
EnableDevKmsg();
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "config_policy_utils.h"
|
||||
#include "device.h"
|
||||
#include "fd_holder_service.h"
|
||||
#include "fs_manager/fs_manager.h"
|
||||
#include "key_control.h"
|
||||
#include "init_control_fd_service.h"
|
||||
#include "init_log.h"
|
||||
@ -40,9 +39,6 @@
|
||||
#include "init_service_manager.h"
|
||||
#include "init_utils.h"
|
||||
#include "securec.h"
|
||||
#include "switch_root.h"
|
||||
#include "ueventd.h"
|
||||
#include "ueventd_socket.h"
|
||||
#include "fd_holder_internal.h"
|
||||
#include "bootstage.h"
|
||||
|
||||
@ -108,19 +104,6 @@ void SystemInit(void)
|
||||
InitControlFd();
|
||||
}
|
||||
|
||||
static void EnableDevKmsg(void)
|
||||
{
|
||||
/* printk_devkmsg default value is ratelimit, We need to set "on" and remove the restrictions */
|
||||
int fd = open("/proc/sys/kernel/printk_devkmsg", O_WRONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
char *kmsgStatus = "on";
|
||||
write(fd, kmsgStatus, strlen(kmsgStatus) + 1);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
void LogInit(void)
|
||||
{
|
||||
int ret = mknod("/dev/kmsg", S_IFCHR | S_IWUSR | S_IRUSR,
|
||||
@ -130,135 +113,6 @@ void LogInit(void)
|
||||
}
|
||||
}
|
||||
|
||||
static char **GetRequiredDevices(Fstab fstab, int *requiredNum)
|
||||
{
|
||||
int num = 0;
|
||||
FstabItem *item = fstab.head;
|
||||
while (item != NULL) {
|
||||
if (FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) {
|
||||
num++;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
if (num == 0) {
|
||||
return NULL;
|
||||
}
|
||||
char **devices = (char **)calloc(num, sizeof(char *));
|
||||
INIT_ERROR_CHECK(devices != NULL, return NULL, "Failed calloc err=%d", errno);
|
||||
|
||||
int i = 0;
|
||||
item = fstab.head;
|
||||
while (item != NULL) {
|
||||
if (FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) {
|
||||
devices[i] = strdup(item->deviceName);
|
||||
INIT_ERROR_CHECK(devices[i] != NULL, FreeStringVector(devices, num); return NULL,
|
||||
"Failed strdup err=%d", errno);
|
||||
i++;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
*requiredNum = num;
|
||||
return devices;
|
||||
}
|
||||
|
||||
static int StartUeventd(char **requiredDevices, int num)
|
||||
{
|
||||
INIT_ERROR_CHECK(requiredDevices != NULL && num > 0, return -1, "Failed parameters");
|
||||
int ueventSockFd = UeventdSocketInit();
|
||||
if (ueventSockFd < 0) {
|
||||
INIT_LOGE("Failed to create uevent socket");
|
||||
return -1;
|
||||
}
|
||||
RetriggerUevent(ueventSockFd, requiredDevices, num);
|
||||
close(ueventSockFd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void StartInitSecondStage(long long uptime)
|
||||
{
|
||||
int requiredNum = 0;
|
||||
Fstab *fstab = LoadRequiredFstab();
|
||||
char **devices = (fstab != NULL) ? GetRequiredDevices(*fstab, &requiredNum) : NULL;
|
||||
if (devices != NULL && requiredNum > 0) {
|
||||
int ret = StartUeventd(devices, requiredNum);
|
||||
if (ret == 0) {
|
||||
ret = MountRequriedPartitions(fstab);
|
||||
}
|
||||
FreeStringVector(devices, requiredNum);
|
||||
devices = NULL;
|
||||
ReleaseFstab(fstab);
|
||||
fstab = NULL;
|
||||
if (ret < 0) {
|
||||
// If mount required partitions failure.
|
||||
// There is no necessary to continue.
|
||||
// Just abort
|
||||
INIT_LOGE("Mount required partitions failed; please check fstab file");
|
||||
// Execute sh for debugging
|
||||
#ifndef STARTUP_INIT_TEST
|
||||
execv("/bin/sh", NULL);
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (fstab != NULL) {
|
||||
ReleaseFstab(fstab);
|
||||
fstab = NULL;
|
||||
}
|
||||
// It will panic if close stdio before execv("/bin/sh", NULL)
|
||||
CloseStdio();
|
||||
|
||||
INIT_LOGI("Start init second stage.");
|
||||
SwitchRoot("/usr");
|
||||
char buf[64];
|
||||
snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%lld", uptime);
|
||||
// Execute init second stage
|
||||
char * const args[] = {
|
||||
"/bin/init",
|
||||
"--second-stage",
|
||||
buf,
|
||||
NULL,
|
||||
};
|
||||
if (execv("/bin/init", args) != 0) {
|
||||
INIT_LOGE("Failed to exec \"/bin/init\", err = %d", errno);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPrepare(long long uptime)
|
||||
{
|
||||
MountBasicFs();
|
||||
CreateDeviceNode();
|
||||
LogInit();
|
||||
// Make sure init log always output to /dev/kmsg.
|
||||
EnableDevKmsg();
|
||||
INIT_LOGI("Start init first stage.");
|
||||
HookMgrExecute(GetBootStageHookMgr(), INIT_FIRST_STAGE, NULL, NULL);
|
||||
// Only ohos normal system support
|
||||
// two stages of init.
|
||||
// If we are in updater mode, only one stage of init.
|
||||
if (InUpdaterMode() == 0) {
|
||||
StartInitSecondStage(uptime);
|
||||
}
|
||||
}
|
||||
|
||||
#define INIT_BOOTSTAGE_HOOK_NAME "bootstage"
|
||||
static HOOK_MGR *bootStageHookMgr = NULL;
|
||||
|
||||
HOOK_MGR *GetBootStageHookMgr()
|
||||
{
|
||||
if (bootStageHookMgr != NULL) {
|
||||
return bootStageHookMgr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create bootstage hook manager for booting only.
|
||||
* When boot completed, this manager will be destroyed.
|
||||
*/
|
||||
bootStageHookMgr = HookMgrCreate(INIT_BOOTSTAGE_HOOK_NAME);
|
||||
return bootStageHookMgr;
|
||||
}
|
||||
|
||||
INIT_TIMING_STAT g_bootJob = {{0}, {0}};
|
||||
|
||||
static void RecordInitBootEvent(const char *initBootEvent)
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include "fs_manager/fs_manager.h"
|
||||
#include "init_cmds.h"
|
||||
#include "init_log.h"
|
||||
#include "init_utils.h"
|
||||
#include "securec.h"
|
||||
|
162
services/init/standard/main_early.c
Executable file
162
services/init/standard/main_early.c
Executable file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/major.h>
|
||||
#include "securec.h"
|
||||
#include "device.h"
|
||||
#include "init.h"
|
||||
#include "init_log.h"
|
||||
#include "init_utils.h"
|
||||
#include "init_mount.h"
|
||||
#include "fs_manager/fs_manager.h"
|
||||
#include "switch_root.h"
|
||||
#include "ueventd.h"
|
||||
#include "ueventd_socket.h"
|
||||
#include "bootstage.h"
|
||||
|
||||
static char **GetRequiredDevices(Fstab fstab, int *requiredNum)
|
||||
{
|
||||
int num = 0;
|
||||
FstabItem *item = fstab.head;
|
||||
while (item != NULL) {
|
||||
if (FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) {
|
||||
num++;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
if (num == 0) {
|
||||
return NULL;
|
||||
}
|
||||
char **devices = (char **)calloc(num, sizeof(char *));
|
||||
INIT_ERROR_CHECK(devices != NULL, return NULL, "Failed calloc err=%d", errno);
|
||||
|
||||
int i = 0;
|
||||
item = fstab.head;
|
||||
while (item != NULL) {
|
||||
if (FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) {
|
||||
devices[i] = strdup(item->deviceName);
|
||||
INIT_ERROR_CHECK(devices[i] != NULL, FreeStringVector(devices, num); return NULL,
|
||||
"Failed strdup err=%d", errno);
|
||||
i++;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
*requiredNum = num;
|
||||
return devices;
|
||||
}
|
||||
|
||||
static int StartUeventd(char **requiredDevices, int num)
|
||||
{
|
||||
INIT_ERROR_CHECK(requiredDevices != NULL && num > 0, return -1, "Failed parameters");
|
||||
int ueventSockFd = UeventdSocketInit();
|
||||
if (ueventSockFd < 0) {
|
||||
INIT_LOGE("Failed to create uevent socket");
|
||||
return -1;
|
||||
}
|
||||
RetriggerUevent(ueventSockFd, requiredDevices, num);
|
||||
close(ueventSockFd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void MountRequiredPartitions(void)
|
||||
{
|
||||
int requiredNum = 0;
|
||||
Fstab *fstab = LoadRequiredFstab();
|
||||
char **devices = (fstab != NULL) ? GetRequiredDevices(*fstab, &requiredNum) : NULL;
|
||||
if (devices != NULL && requiredNum > 0) {
|
||||
int ret = StartUeventd(devices, requiredNum);
|
||||
if (ret == 0) {
|
||||
ret = MountRequriedPartitions(fstab);
|
||||
}
|
||||
FreeStringVector(devices, requiredNum);
|
||||
devices = NULL;
|
||||
ReleaseFstab(fstab);
|
||||
fstab = NULL;
|
||||
if (ret < 0) {
|
||||
// If mount required partitions failure.
|
||||
// There is no necessary to continue.
|
||||
// Just abort
|
||||
INIT_LOGE("Mount required partitions failed; please check fstab file");
|
||||
// Execute sh for debugging
|
||||
#ifndef STARTUP_INIT_TEST
|
||||
execv("/bin/sh", NULL);
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (fstab != NULL) {
|
||||
ReleaseFstab(fstab);
|
||||
fstab = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void StartSecondStageInit(long long uptime)
|
||||
{
|
||||
INIT_LOGI("Start init second stage.");
|
||||
// It will panic if close stdio before execv("/bin/sh", NULL)
|
||||
CloseStdio();
|
||||
|
||||
SwitchRoot("/usr");
|
||||
char buf[64];
|
||||
snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%lld", uptime);
|
||||
// Execute init second stage
|
||||
char * const args[] = {
|
||||
"/bin/init",
|
||||
"--second-stage",
|
||||
buf,
|
||||
NULL,
|
||||
};
|
||||
if (execv("/bin/init", args) != 0) {
|
||||
INIT_LOGE("Failed to exec \"/bin/init\", err = %d", errno);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void EarlyLogInit(void)
|
||||
{
|
||||
int ret = mknod("/dev/kmsg", S_IFCHR | S_IWUSR | S_IRUSR,
|
||||
makedev(MEM_MAJOR, DEV_KMSG_MINOR));
|
||||
if (ret == 0) {
|
||||
OpenLogDevice();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char * const argv[])
|
||||
{
|
||||
long long upTimeInMicroSecs = GetUptimeInMicroSeconds(NULL);
|
||||
|
||||
(void)signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
EnableInitLog(INIT_INFO);
|
||||
EarlyLogInit();
|
||||
INIT_LOGI("Start init first stage.");
|
||||
|
||||
CreateFsAndDeviceNode();
|
||||
|
||||
HookMgrExecute(GetBootStageHookMgr(), INIT_FIRST_STAGE, NULL, NULL);
|
||||
|
||||
MountRequiredPartitions();
|
||||
|
||||
StartSecondStageInit(upTimeInMicroSecs);
|
||||
return 0;
|
||||
}
|
@ -72,13 +72,11 @@ HWTEST_F(InitUnitTest, TestSystemPrepare, TestSize.Level1)
|
||||
{
|
||||
SetStubResult(STUB_MOUNT, -1);
|
||||
SetStubResult(STUB_MKNODE, -1);
|
||||
MountBasicFs();
|
||||
CreateDeviceNode();
|
||||
CreateFsAndDeviceNode();
|
||||
|
||||
SetStubResult(STUB_MOUNT, 0);
|
||||
SetStubResult(STUB_MKNODE, 0);
|
||||
MountBasicFs();
|
||||
CreateDeviceNode();
|
||||
CreateFsAndDeviceNode();
|
||||
}
|
||||
|
||||
HWTEST_F(InitUnitTest, TestSystemExecRcs, TestSize.Level1)
|
||||
|
@ -596,7 +596,6 @@ static __attribute__((constructor(101))) void ParamTestStubInit(void)
|
||||
#ifndef OHOS_LITE
|
||||
TestBeforeInit();
|
||||
#endif
|
||||
SystemPrepare(0);
|
||||
#ifndef __LITEOS_A__
|
||||
SystemInit();
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user