日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android关机分区卸载,Android关机重启流程(二)

發(fā)布時間:2023/12/20 Android 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android关机分区卸载,Android关机重启流程(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、回顧

先回顧下上部分得分析,從最開始的PM.reboot(),經過層層調用,最終調用

SystemProperties.set(“sys.powerctl”, “reboot,” + reason);

二、重啟流程

aosp/system/core/init/property_service.cpp

aosp/system/core/init/reboot.cpp

aosp/system/core/init/reboot_utils.cpp

aosp/system/core/init/init.cpp

PM.reboot最終也就是setprop?sys.powerctl,那么誰來監(jiān)聽sys.powerctl 值呢,肯定是init了,接下來就也就引入本節(jié)得重點,

init監(jiān)聽?sys.powerctl?處理關機后半部流程

2.1?HandlePropertySet

[->property_service.cpp]

// This returns one of the enum of PROP_SUCCESS or PROP_ERROR*.

uint32_t HandlePropertySet(const std::string& name, const std::string& value,

const std::string& source_context, const ucred& cr, std::string* error) {

...

// sys.powerctl is a special property that is used to make the device reboot. We want to log

// any process that sets this property to be able to accurately blame the cause of a shutdown.

//此時會記錄到logcat中,那個進程設置sys.powerctl得以及原因

if (name == "sys.powerctl") {

std::string cmdline_path = StringPrintf("proc/%d/cmdline", cr.pid);

std::string process_cmdline;

std::string process_log_string;

if (ReadFileToString(cmdline_path, &process_cmdline)) {

// Since cmdline is null deliminated, .c_str() conveniently gives us just the process

// path.

process_log_string = StringPrintf(" (%s)", process_cmdline.c_str());

}

LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid

<< process_log_string;

}

...

return PropertySet(name, value, error); //設置屬性值

}

2.2?HandlePropertySet

[->property_service.cpp]

static uint32_t PropertySet(const std::string& name, const std::string& value, std::string* error) {

...

property_changed(name, value);// 會通知init property值改變

return PROP_SUCCESS;

}

2.3? property_changed

[->init.cpp]

void property_changed(const std::string& name, const std::string& value) {

// If the property is sys.powerctl, we bypass the event queue and immediately handle it.

// This is to ensure that init will always and immediately shutdown/reboot, regardless of

// if there are other pending events to process or if init is waiting on an exec service or

// waiting on a property.

// In non-thermal-shutdown case, 'shutdown' trigger will be fired to let device specific

// commands to be executed.

if (name == "sys.powerctl") { //當init檢測到某個進程設置 sys.powerctl時,會把do_shutdown 置true,init主循環(huán)會執(zhí)行關機動作 見2.3節(jié)

// Despite the above comment, we can't call HandlePowerctlMessage() in this function,

// because it modifies the contents of the action queue, which can cause the action queue

// to get into a bad state if this function is called from a command being executed by the

// action queue. Instead we set this flag and ensure that shutdown happens before the next

// command is run in the main init loop.

// TODO: once property service is removed from init, this will never happen from a builtin,

// but rather from a callback from the property service socket, in which case this hack can

// go away.

shutdown_command = value;

do_shutdown = true;

}

if (property_triggers_enabled) ActionManager::GetInstance().QueuePropertyChange(name, value);

if (waiting_for_prop) {

if (wait_prop_name == name && wait_prop_value == value) {

LOG(INFO) << "Wait for property took " << *waiting_for_prop;

ResetWaitForProp();

}

}

}

2.4?SecondStageMain

[->init.cpp]

int SecondStageMain(int argc, char** argv) {

...

while (true) {

// By default, sleep until something happens.

auto epoll_timeout = std::optional<:chrono::milliseconds>{};

if (do_shutdown && !shutting_down) {

do_shutdown = false;

if (HandlePowerctlMessage(shutdown_command)) { //執(zhí)行關機重啟流程

shutting_down = true;

}

}

if (!(waiting_for_prop || Service::is_exec_service_running())) {

am.ExecuteOneCommand();

}

if (!(waiting_for_prop || Service::is_exec_service_running())) {

if (!shutting_down) {

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<:chrono::milliseconds>(

*next_process_action_time - boot_clock::now());

if (*epoll_timeout < 0ms) epoll_timeout = 0ms;

}

}

// If there's more work to do, wake up again immediately.

if (am.HasMoreCommands()) epoll_timeout = 0ms;

}

if (auto result = epoll.Wait(epoll_timeout); !result) {

LOG(ERROR) << result.error();

}

}

return 0;

}

2.5 HandlePowerctlMessage

[->reboot.cpp]

bool HandlePowerctlMessage(const std::string& command) {

unsigned int cmd = 0;

std::vector<:string> cmd_params = Split(command, ",");

std::string reboot_target = "";

bool run_fsck = false;

bool command_invalid = false;

if (cmd_params.size() > 3) {

command_invalid = true;

} else if (cmd_params[0] == "shutdown") {

cmd = ANDROID_RB_POWEROFF;

if (cmd_params.size() == 2) {

if (cmd_params[1] == "userrequested") {

// The shutdown reason is PowerManager.SHUTDOWN_USER_REQUESTED.

// Run fsck once the file system is remounted in read-only mode.

run_fsck = true;

} else if (cmd_params[1] == "thermal") {

// Turn off sources of heat immediately.

TurnOffBacklight();

// run_fsck is false to avoid delay

cmd = ANDROID_RB_THERMOFF;

}

}

} else if (cmd_params[0] == "reboot") {

cmd = ANDROID_RB_RESTART2;

if (cmd_params.size() >= 2) {

reboot_target = cmd_params[1];

// adb reboot fastboot should boot into bootloader for devices not

// supporting logical partitions.

if (reboot_target == "fastboot" &&

!android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {

reboot_target = "bootloader";

}

// When rebooting to the bootloader notify the bootloader writing

// also the BCB.

if (reboot_target == "bootloader") {

std::string err;

if (!write_reboot_bootloader(&err)) {//會把bootloader寫到kernel,重啟使用

LOG(ERROR) << "reboot-bootloader: Error writing "

"bootloader_message: "

<< err;

}

} else if (reboot_target == "sideload" || reboot_target == "sideload-auto-reboot" ||

reboot_target == "fastboot") {

std::string arg = reboot_target == "sideload-auto-reboot" ? "sideload_auto_reboot"

: reboot_target;

const std::vector<:string> options = {

"--" + arg,

};

std::string err;

if (!write_bootloader_message(options, &err)) {//會把recovery寫到kernel,重啟使用

LOG(ERROR) << "Failed to set bootloader message: " << err;

return false;

}

reboot_target = "recovery";

}

// If there is an additional parameter, pass it along

if ((cmd_params.size() == 3) && cmd_params[2].size()) {

reboot_target += "," + cmd_params[2];

}

}

} else {

command_invalid = true;

}

if (command_invalid) {

LOG(ERROR) << "powerctl: unrecognized command '" << command << "'";

return false;

}

LOG(INFO) << "Clear action queue and start shutdown trigger";

ActionManager::GetInstance().ClearQueue();

// Queue shutdown trigger first

ActionManager::GetInstance().QueueEventTrigger("shutdown");//處理init.rc中shutdown部分,依次關閉各個模塊

// Queue built-in shutdown_done

auto shutdown_handler = [cmd, command, reboot_target, run_fsck](const BuiltinArguments&) {

DoReboot(cmd, command, reboot_target, run_fsck); //reboot 流程核心,見下節(jié)

return Success();

};

ActionManager::GetInstance().QueueBuiltinAction(shutdown_handler, "shutdown_done");//設置中shutdown_done部分,shutdown執(zhí)行完會執(zhí)行DoReboot

// Skip wait for prop if it is in progress

ResetWaitForProp();

// Clear EXEC flag if there is one pending

for (const auto& s : ServiceList::GetInstance()) {

s->UnSetExec();

}

return true;

}

2.6 DoReboot

[->reboot.cpp]

//* Reboot / shutdown the system.

// cmd ANDROID_RB_* as defined in android_reboot.h

// reason Reason string like "reboot", "shutdown,userrequested"

// rebootTarget Reboot target string like "bootloader". Otherwise, it should be an

// empty string.

// runFsck Whether to run fsck after umount is done.

//

static void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget,

bool runFsck) {

Timer t;

LOG(INFO) << "Reboot start, reason: " << reason << ", rebootTarget: " << rebootTarget;

// Ensure last reboot reason is reduced to canonical

// alias reported in bootloader or system boot reason.

size_t skip = 0;

std::vector<:string> reasons = Split(reason, ",");

if (reasons.size() >= 2 && reasons[0] == "reboot" &&

(reasons[1] == "recovery" || reasons[1] == "bootloader" || reasons[1] == "cold" ||

reasons[1] == "hard" || reasons[1] == "warm")) {

skip = strlen("reboot,");

}

property_set(LAST_REBOOT_REASON_PROPERTY, reason.c_str() + skip);//設置reboot 重啟原因到persist.sys.boot.reason,重啟后可以查看

sync();

bool is_thermal_shutdown = cmd == ANDROID_RB_THERMOFF;

auto shutdown_timeout = 0ms;

if (!SHUTDOWN_ZERO_TIMEOUT) {

constexpr unsigned int shutdown_timeout_default = 6;

constexpr unsigned int max_thermal_shutdown_timeout = 3;

auto shutdown_timeout_final = android::base::GetUintProperty("ro.build.shutdown_timeout",

shutdown_timeout_default);

if (is_thermal_shutdown && shutdown_timeout_final > max_thermal_shutdown_timeout) {

shutdown_timeout_final = max_thermal_shutdown_timeout;

}

shutdown_timeout = std::chrono::seconds(shutdown_timeout_final);

}

LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " ms";

// keep debugging tools until non critical ones are all gone.

const std::set<:string> kill_after_apps{"tombstoned", "logd", "adbd"};

// watchdogd is a vendor specific component but should be alive to complete shutdown safely.

const std::set<:string> to_starts{"watchdogd"};

for (const auto& s : ServiceList::GetInstance()) {

if (kill_after_apps.count(s->name())) {

s->SetShutdownCritical();

} else if (to_starts.count(s->name())) {

if (auto result = s->Start(); !result) {

LOG(ERROR) << "Could not start shutdown 'to_start' service '" << s->name()

<< "': " << result.error();

}

s->SetShutdownCritical();

} else if (s->IsShutdownCritical()) {

// Start shutdown critical service if not started.

if (auto result = s->Start(); !result) {

LOG(ERROR) << "Could not start shutdown critical service '" << s->name()

<< "': " << result.error();

}

}

}

// remaining operations (specifically fsck) may take a substantial duration

if (cmd == ANDROID_RB_POWEROFF || is_thermal_shutdown) {

TurnOffBacklight();

}

Service* bootAnim = ServiceList::GetInstance().FindService("bootanim");

Service* surfaceFlinger = ServiceList::GetInstance().FindService("surfaceflinger");

if (bootAnim != nullptr && surfaceFlinger != nullptr && surfaceFlinger->IsRunning()) {

// will not check animation class separately

for (const auto& service : ServiceList::GetInstance()) {

if (service->classnames().count("animation")) service->SetShutdownCritical();

}

}

// optional shutdown step

// 1. terminate all services except shutdown critical ones. wait for delay to finish

//終止除shutdown關鍵之外的所有服務。 等待完成

if (shutdown_timeout > 0ms) {

LOG(INFO) << "terminating init services";

// Ask all services to terminate except shutdown critical ones.

for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {

if (!s->IsShutdownCritical()) s->Terminate();

}

int service_count = 0;

// Only wait up to half of timeout here

auto termination_wait_timeout = shutdown_timeout / 2;

while (t.duration() < termination_wait_timeout) {

ReapAnyOutstandingChildren();

service_count = 0;

for (const auto& s : ServiceList::GetInstance()) {

// Count the number of services running except shutdown critical.

// Exclude the console as it will ignore the SIGTERM signal

// and not exit.

// Note: SVC_CONSOLE actually means "requires console" but

// it is only used by the shell.

if (!s->IsShutdownCritical() && s->pid() != 0 && (s->flags() & SVC_CONSOLE) == 0) {

service_count++;

}

}

if (service_count == 0) {

// All terminable services terminated. We can exit early.

break;

}

// Wait a bit before recounting the number or running services.

std::this_thread::sleep_for(50ms);

}

LOG(INFO) << "Terminating running services took " << t

<< " with remaining services:" << service_count;

}

// minimum safety steps before restarting

// 2. kill all services except ones that are necessary for the shutdown sequence.

//2. 關閉所有得服務

for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {

if (!s->IsShutdownCritical()) s->Stop();

}

SubcontextTerminate();

ReapAnyOutstandingChildren();

// 3. send volume shutdown to vold

// 3. 關閉vold

Service* voldService = ServiceList::GetInstance().FindService("vold");

if (voldService != nullptr && voldService->IsRunning()) {

ShutdownVold();

voldService->Stop();

} else {

LOG(INFO) << "vold not running, skipping vold shutdown";

}

// logcat stopped here

for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {

if (kill_after_apps.count(s->name())) s->Stop();

}

// 4. sync, try umount, and optionally run fsck for user shutdown

//4. 同步,卸載分區(qū),

{

Timer sync_timer;

LOG(INFO) << "sync() before umount...";

sync();

LOG(INFO) << "sync() before umount took" << sync_timer;

}

UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration());

// Follow what linux shutdown is doing: one more sync with little bit delay

{

Timer sync_timer;

LOG(INFO) << "sync() after umount...";

sync();

LOG(INFO) << "sync() after umount took" << sync_timer;

}

if (!is_thermal_shutdown) std::this_thread::sleep_for(100ms);

LogShutdownTime(stat, &t);

// Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.

RebootSystem(cmd, rebootTarget); //重啟系統(tǒng)

abort();

}

2.7?RebootSystem

[->reboot_utils.cpp]

void __attribute__((noreturn)) RebootSystem(unsigned int cmd, const std::string& rebootTarget) {

LOG(INFO) << "Reboot ending, jumping to kernel";

if (!IsRebootCapable()) {

// On systems where init does not have the capability of rebooting the

// device, just exit cleanly.

exit(0);

}

//下面就是reboot的system call進入內核空間了:

switch (cmd) {

case ANDROID_RB_POWEROFF:

reboot(RB_POWER_OFF); //調用reboot函數執(zhí)行關機

break;

case ANDROID_RB_RESTART2:

syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,

LINUX_REBOOT_CMD_RESTART2, rebootTarget.c_str());//調用syscall函數執(zhí)行重啟

break;

case ANDROID_RB_THERMOFF:

reboot(RB_POWER_OFF);//調用reboot函數執(zhí)行重啟

break;

}

// In normal case, reboot should not return.

PLOG(ERROR) << "reboot call returned";

abort();

}

三、總結

一句話總結,從 設置屬性sys.powerctrl,最終重啟調用libc庫得? reboot或syscall, 也就意味這reboot下一步流程到達內核空間,

內核空間部分留著下一節(jié)繼續(xù)。

總結

以上是生活随笔為你收集整理的android关机分区卸载,Android关机重启流程(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。