int SecondStageMain( int argc, char ** argv) {
#ifdef JOURNEY_FEATURE_ROOT_MODE
initJourneyRootMode();
#endif
/*
*init crash时重启引导加载程序
*这个函数主要作用将各种信号量,如SIGABRT,SIGBUS等的行为设置为SA_RESTART,一旦监听到这些信号即执行重启系统
*/
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
boot_clock::time_point start_time = boot_clock::now();
trigger_shutdown = []( const std::string& command) { shutdown_state.TriggerShutdown(command); };
//把标准输入、标准输出和标准错误重定向到空设备文件“/dev/null"
SetStdioToDevNull(argv);
#ifdef MTK_LOG
#ifndef MTK_LOG_DISABLERATELIMIT
{
std::string cmdline;
android::base::ReadFileToString( "/proc/cmdline" , &cmdline);
if (cmdline.find( "init.mtklogdrl=1" ) != std::string::npos)
SetMTKLOGDISABLERATELIMIT();
const char * force_debuggable_env = getenv ( "INIT_FORCE_DEBUGGABLE" );
if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) {
SetMTKLOGDISABLERATELIMIT();
}
}
#else
SetMTKLOGDISABLERATELIMIT();
#endif // MTK_LOG_DISABLERATELIMIT
if (GetMTKLOGDISABLERATELIMIT())
InitKernelLogging_split(argv);
else
InitKernelLogging(argv);
#else
//在/dev目录下挂载好tmpfs以及kmsg
//这样就可以初始化/kernel log系统,供用户打印log
InitKernelLogging(argv);
#endif
LOG(INFO) << "init second stage started!" ;
// Update $PATH in the case the second stage init is newer than first stage init, where it is
// first set.
if (setenv( "PATH" , _PATH_DEFPATH, 1) != 0) {
PLOG(FATAL) << "Could not set $PATH to '" << _PATH_DEFPATH << "' in second stage" ;
}
// Init should not crash because of a dependence on any other process, therefore we ignore
// SIGPIPE and handle EPIPE at the call site directly. Note that setting a signal to SIG_IGN
// is inherited across exec, but custom signal handlers are not. Since we do not want to
// ignore SIGPIPE for child processes, we set a no-op function for the signal handler instead.
{
struct sigaction action = {.sa_flags = SA_RESTART};
action.sa_handler = []( int ) {};
sigaction(SIGPIPE, &action, nullptr);
}
// Set init and its forked children's oom_adj.
if (auto result =
WriteFile( "/proc/1/oom_score_adj" , StringPrintf( "%d" , DEFAULT_OOM_SCORE_ADJUST));
!result.ok()) {
LOG(ERROR) << "Unable to write " << DEFAULT_OOM_SCORE_ADJUST
<< " to /proc/1/oom_score_adj: " << result.error();
}
// Set up a session keyring that all processes will have access to. It
// will hold things like FBE encryption keys. No process should override
// its session keyring.
//01.创建进程会话密钥并初始化属性系统
keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);
// Indicate that booting is in progress to background fw loaders, etc.
//创建/dev/.booting文件,就是个标记,表示booting进行中
close(open( "/dev/.booting" , O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
// See if need to load debug props to allow adb root, when the device is unlocked.
const char * force_debuggable_env = getenv ( "INIT_FORCE_DEBUGGABLE" );
bool load_debug_prop = false ;
if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) {
load_debug_prop = "true" s == force_debuggable_env;
}
unsetenv( "INIT_FORCE_DEBUGGABLE" );
// Umount the debug ramdisk so property service doesn't read .prop files from there, when it
// is not meant to.
if (!load_debug_prop) {
UmountDebugRamdisk();
}
//初始化属性系统,并从指定文件读取属性
PropertyInit();
// Umount second stage resources after property service has read the .prop files.
UmountSecondStageRes();
// Umount the debug ramdisk after property service has read the .prop files when it means to.
if (load_debug_prop) {
UmountDebugRamdisk();
}
// Mount extra filesystems required during second stage init
MountExtraFilesystems();
// Now set up SELinux for second stage.
#ifdef MTK_LOG
if (GetMTKLOGDISABLERATELIMIT())
SelinuxSetupKernelLogging_split();
else
SelinuxSetupKernelLogging();
#else
SelinuxSetupKernelLogging();
#endif
SelabelInitialize();
/*
02.进行SELinux第二阶段并恢复一些文件安全上下文
恢复相关文件的安全上下文,因为这些文件是在SELinux安全机制初始化前创建的
所以需要重新恢复上下文
*/
SelinuxRestoreContext();
/*
03.新建epoll并初始化子进程终止信号处理函数
创建epoll实例,并返回epoll的文件描述
*/
Epoll epoll;
if (auto result = epoll.Open(); !result.ok()) {
PLOG(FATAL) << result.error();
}
#ifdef G1122717
// Watch properties with specific meanings to init.
LOG(INFO) << "Apply watching properties with specific meanings to init." ;
ActionManager::GetInstance().StartWatchingProperty( "sys.powerctl" );
ActionManager::GetInstance().StartWatchingProperty( "ro.persistent_properties.ready" );
ActionManager::GetInstance().StartWatchingProperty(kColdBootDoneProp);
#endif
/*
主要是创建handler处理子进程终止信号,注册一个signal到epoll进行监听
进行子继承处理
*/
InstallSignalFdHandler(&epoll);
InstallInitNotifier(&epoll);
//04.设置其他系统属性并开启系统属性服务
StartPropertyService(&property_fd);
#if defined(MTK_LOG) && defined(MTK_COMMAND_WDOG)
ActionManager::GetInstance().StartCommandWDOG();
#endif
// Make the time that init stages started available for bootstat to log.
RecordStageBoottimes(start_time);
// Set libavb version for Framework-only OTA match in Treble build.
if ( const char * avb_version = getenv ( "INIT_AVB_VERSION" ); avb_version != nullptr) {
SetProperty( "ro.boot.avb_version" , avb_version);
}
unsetenv( "INIT_AVB_VERSION" );
fs_mgr_vendor_overlay_mount_all();
export_oem_lock_status();
MountHandler mount_handler(&epoll);
SetUsbController();
#ifdef JOURNEY_FEATURE_SECURE
CheckJourneySecureMode();
#endif
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
Action::set_function_map(&function_map);
if (!SetupMountNamespaces()) {
PLOG(FATAL) << "SetupMountNamespaces failed" ;
}
//初始化文件上下文
InitializeSubcontext();
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
/*
05.解析init.rc等文件,建立rc文件的action、service,启动其他进程
*/
LoadBootScripts(am, sm);
// Turning this on and letting the INFO logging be discarded adds 0.2s to
// Nexus 9 boot time, so it's disabled by default.
if ( false ) DumpState();
// Make the GSI status available before scripts start running.
//当GSI脚本running时,确保GSI状态可用
auto is_running = android::gsi::IsGsiRunning() ? "1" : "0" ;
SetProperty(gsi::kGsiBootedProp, is_running);
auto is_installed = android::gsi::IsGsiInstalled() ? "1" : "0" ;
SetProperty(gsi::kGsiInstalledProp, is_installed);
am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups" );
am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict" );
am.QueueBuiltinAction(TestPerfEventSelinuxAction, "TestPerfEventSelinux" );
//执行rc文件中触发器为 on early-init的语句
am.QueueEventTrigger( "early-init" );
// Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
//等冷插拔设备初始化完成
am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done" );
// ... so that we can start queuing up actions that require stuff from /dev.
am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits" );
//设备组合键的初始化操作
Keychords keychords;
am.QueueBuiltinAction(
[&epoll, &keychords]( const BuiltinArguments& args) -> Result< void > {
for ( const auto& svc : ServiceList::GetInstance()) {
keychords.Register(svc->keycodes());
}
keychords.Start(&epoll, HandleKeychord);
return {};
},
"KeychordInit" );
// Trigger all the boot actions to get us started.
//执行rc文件中触发器为on init的语句
am.QueueEventTrigger( "init" );
// Don't mount filesystems or start core system services in charger mode.
/*
当设备处于充电模式时,不需要mount文件系统或者启动系统服务
充电模式下,将charger加入执行队列,否则把late-init加入执行队列
*/
std::string bootmode = GetProperty( "ro.bootmode" , "" );
if (bootmode == "charger" ) {
am.QueueEventTrigger( "charger" );
} else {
am.QueueEventTrigger( "late-init" );
}
// Run all property triggers based on current state of the properties.
//基于属性当前状态,运行所有的属性触发器
am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers" );
// Restore prio before main loop
setpriority(PRIO_PROCESS, 0, 0);
while ( true ) {
// By default, sleep until something happens.
auto epoll_timeout = std::optional<std::chrono::milliseconds>{};
auto shutdown_command = shutdown_state.CheckShutdown();
if (shutdown_command) {
LOG(INFO) << "Got shutdown_command '" << *shutdown_command
<< "' Calling HandlePowerctlMessage()" ;
HandlePowerctlMessage(*shutdown_command);
shutdown_state.set_do_shutdown( false );
}
//依次执行每个action中携带command对应的执行函数
if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
}
if (!IsShuttingDown()) {
auto next_process_action_time = HandleProcessActions();
// If there's a process that needs restarting, wake up in time for that.
if (next_process_action_time) {
epoll_timeout = std::chrono:: ceil <std::chrono::milliseconds>(
*next_process_action_time - boot_clock::now());
if (*epoll_timeout < 0ms) epoll_timeout = 0ms;
}
}
if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
// If there's more work to do, wake up again immediately.
if (am.HasMoreCommands()) epoll_timeout = 0ms;
}
#ifdef MTK_LOG
int log_ms = _LogReap(); //PropSetLogReap();
if (log_ms > -1 && (!epoll_timeout || epoll_timeout->count() > log_ms))
epoll_timeout = std::chrono::milliseconds(log_ms);
if (GetMTKLOGDISABLERATELIMIT()) {
if (!Getwhilepiggybacketed(1) && Getwhileepduration(1) > 1999)
LOG(INFO) << "Lastest epoll wait tooks " << Getwhileepduration(1) << "ms" ;
}
android::base::Timer t;
auto pending_functions = epoll.Wait(epoll_timeout);
if (GetMTKLOGDISABLERATELIMIT()) {
uint64_t duration = t.duration().count();
uint64_t nowms = std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now().time_since_epoch()).count();
Setwhiletime(1, duration, nowms);
}
#else
auto pending_functions = epoll.Wait(epoll_timeout);
#endif
if (!pending_functions.ok()) {
LOG(ERROR) << pending_functions.error();
} else if (!pending_functions->empty()) {
// We always reap children before responding to the other pending functions. This is to
// prevent a race where other daemons see that a service has exited and ask init to
// start it again via ctl.start before init has reaped it.
ReapAnyOutstandingChildren();
for ( const auto& function : *pending_functions) {
(*function)();
}
}
if (!IsShuttingDown()) {
HandleControlMessages();
SetUsbController();
}
}
return 0;
}
|