reboot.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. /*
  2. * Copyright (C) 2017 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "reboot.h"
  17. #include <dirent.h>
  18. #include <fcntl.h>
  19. #include <linux/fs.h>
  20. #include <mntent.h>
  21. #include <linux/loop.h>
  22. #include <sys/cdefs.h>
  23. #include <sys/ioctl.h>
  24. #include <sys/mount.h>
  25. #include <sys/swap.h>
  26. #include <sys/stat.h>
  27. #include <sys/syscall.h>
  28. #include <sys/types.h>
  29. #include <sys/wait.h>
  30. #include <memory>
  31. #include <set>
  32. #include <thread>
  33. #include <vector>
  34. #include <android-base/chrono_utils.h>
  35. #include <android-base/file.h>
  36. #include <android-base/logging.h>
  37. #include <android-base/macros.h>
  38. #include <android-base/properties.h>
  39. #include <android-base/stringprintf.h>
  40. #include <android-base/strings.h>
  41. #include <android-base/unique_fd.h>
  42. #include <bootloader_message/bootloader_message.h>
  43. #include <cutils/android_reboot.h>
  44. #include <fs_mgr.h>
  45. #include <logwrap/logwrap.h>
  46. #include <private/android_filesystem_config.h>
  47. #include <selinux/selinux.h>
  48. #include "action_manager.h"
  49. #include "init.h"
  50. #include "property_service.h"
  51. #include "reboot_utils.h"
  52. #include "service.h"
  53. #include "sigchld_handler.h"
  54. using android::base::GetBoolProperty;
  55. using android::base::Split;
  56. using android::base::StringPrintf;
  57. using android::base::Timer;
  58. using android::base::unique_fd;
  59. namespace android {
  60. namespace init {
  61. // represents umount status during reboot / shutdown.
  62. enum UmountStat {
  63. /* umount succeeded. */
  64. UMOUNT_STAT_SUCCESS = 0,
  65. /* umount was not run. */
  66. UMOUNT_STAT_SKIPPED = 1,
  67. /* umount failed with timeout. */
  68. UMOUNT_STAT_TIMEOUT = 2,
  69. /* could not run due to error */
  70. UMOUNT_STAT_ERROR = 3,
  71. /* not used by init but reserved for other part to use this to represent the
  72. the state where umount status before reboot is not found / available. */
  73. UMOUNT_STAT_NOT_AVAILABLE = 4,
  74. };
  75. // Utility for struct mntent
  76. class MountEntry {
  77. public:
  78. explicit MountEntry(const mntent& entry)
  79. : mnt_fsname_(entry.mnt_fsname),
  80. mnt_dir_(entry.mnt_dir),
  81. mnt_type_(entry.mnt_type),
  82. mnt_opts_(entry.mnt_opts) {}
  83. bool Umount(bool force) {
  84. LOG(INFO) << "Unmounting " << mnt_fsname_ << ":" << mnt_dir_ << " opts " << mnt_opts_;
  85. int r = umount2(mnt_dir_.c_str(), force ? MNT_FORCE : 0);
  86. if (r == 0) {
  87. LOG(INFO) << "Umounted " << mnt_fsname_ << ":" << mnt_dir_ << " opts " << mnt_opts_;
  88. return true;
  89. } else {
  90. PLOG(WARNING) << "Cannot umount " << mnt_fsname_ << ":" << mnt_dir_ << " opts "
  91. << mnt_opts_;
  92. return false;
  93. }
  94. }
  95. void DoFsck() {
  96. int st;
  97. if (IsF2Fs()) {
  98. const char* f2fs_argv[] = {
  99. "/system/bin/fsck.f2fs",
  100. "-a",
  101. mnt_fsname_.c_str(),
  102. };
  103. android_fork_execvp_ext(arraysize(f2fs_argv), (char**)f2fs_argv, &st, true, LOG_KLOG,
  104. true, nullptr, nullptr, 0);
  105. } else if (IsExt4()) {
  106. const char* ext4_argv[] = {
  107. "/system/bin/e2fsck",
  108. "-y",
  109. mnt_fsname_.c_str(),
  110. };
  111. android_fork_execvp_ext(arraysize(ext4_argv), (char**)ext4_argv, &st, true, LOG_KLOG,
  112. true, nullptr, nullptr, 0);
  113. }
  114. }
  115. static bool IsBlockDevice(const struct mntent& mntent) {
  116. return android::base::StartsWith(mntent.mnt_fsname, "/dev/block");
  117. }
  118. static bool IsEmulatedDevice(const struct mntent& mntent) {
  119. return android::base::StartsWith(mntent.mnt_fsname, "/data/");
  120. }
  121. private:
  122. bool IsF2Fs() const { return mnt_type_ == "f2fs"; }
  123. bool IsExt4() const { return mnt_type_ == "ext4"; }
  124. std::string mnt_fsname_;
  125. std::string mnt_dir_;
  126. std::string mnt_type_;
  127. std::string mnt_opts_;
  128. };
  129. // Turn off backlight while we are performing power down cleanup activities.
  130. static void TurnOffBacklight() {
  131. Service* service = ServiceList::GetInstance().FindService("blank_screen");
  132. if (service == nullptr) {
  133. LOG(WARNING) << "cannot find blank_screen in TurnOffBacklight";
  134. return;
  135. }
  136. if (auto result = service->Start(); !result) {
  137. LOG(WARNING) << "Could not start blank_screen service: " << result.error();
  138. }
  139. }
  140. static void ShutdownVold() {
  141. const char* vdc_argv[] = {"/system/bin/vdc", "volume", "shutdown"};
  142. int status;
  143. android_fork_execvp_ext(arraysize(vdc_argv), (char**)vdc_argv, &status, true, LOG_KLOG, true,
  144. nullptr, nullptr, 0);
  145. }
  146. static void LogShutdownTime(UmountStat stat, Timer* t) {
  147. LOG(WARNING) << "powerctl_shutdown_time_ms:" << std::to_string(t->duration().count()) << ":"
  148. << stat;
  149. }
  150. /* Find all read+write block devices and emulated devices in /proc/mounts
  151. * and add them to correpsponding list.
  152. */
  153. static bool FindPartitionsToUmount(std::vector<MountEntry>* blockDevPartitions,
  154. std::vector<MountEntry>* emulatedPartitions, bool dump) {
  155. std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "re"), endmntent);
  156. if (fp == nullptr) {
  157. PLOG(ERROR) << "Failed to open /proc/mounts";
  158. return false;
  159. }
  160. mntent* mentry;
  161. while ((mentry = getmntent(fp.get())) != nullptr) {
  162. if (dump) {
  163. LOG(INFO) << "mount entry " << mentry->mnt_fsname << ":" << mentry->mnt_dir << " opts "
  164. << mentry->mnt_opts << " type " << mentry->mnt_type;
  165. } else if (MountEntry::IsBlockDevice(*mentry) && hasmntopt(mentry, "rw")) {
  166. std::string mount_dir(mentry->mnt_dir);
  167. // These are R/O partitions changed to R/W after adb remount.
  168. // Do not umount them as shutdown critical services may rely on them.
  169. if (mount_dir != "/" && mount_dir != "/system" && mount_dir != "/vendor" &&
  170. mount_dir != "/oem") {
  171. blockDevPartitions->emplace(blockDevPartitions->begin(), *mentry);
  172. }
  173. } else if (MountEntry::IsEmulatedDevice(*mentry)) {
  174. emulatedPartitions->emplace(emulatedPartitions->begin(), *mentry);
  175. }
  176. }
  177. return true;
  178. }
  179. static void DumpUmountDebuggingInfo() {
  180. int status;
  181. if (!security_getenforce()) {
  182. LOG(INFO) << "Run lsof";
  183. const char* lsof_argv[] = {"/system/bin/lsof"};
  184. android_fork_execvp_ext(arraysize(lsof_argv), (char**)lsof_argv, &status, true, LOG_KLOG,
  185. true, nullptr, nullptr, 0);
  186. }
  187. FindPartitionsToUmount(nullptr, nullptr, true);
  188. // dump current CPU stack traces and uninterruptible tasks
  189. android::base::WriteStringToFile("l", "/proc/sysrq-trigger");
  190. android::base::WriteStringToFile("w", "/proc/sysrq-trigger");
  191. }
  192. static UmountStat UmountPartitions(std::chrono::milliseconds timeout) {
  193. Timer t;
  194. /* data partition needs all pending writes to be completed and all emulated partitions
  195. * umounted.If the current waiting is not good enough, give
  196. * up and leave it to e2fsck after reboot to fix it.
  197. */
  198. while (true) {
  199. std::vector<MountEntry> block_devices;
  200. std::vector<MountEntry> emulated_devices;
  201. if (!FindPartitionsToUmount(&block_devices, &emulated_devices, false)) {
  202. return UMOUNT_STAT_ERROR;
  203. }
  204. if (block_devices.size() == 0) {
  205. return UMOUNT_STAT_SUCCESS;
  206. }
  207. bool unmount_done = true;
  208. if (emulated_devices.size() > 0) {
  209. for (auto& entry : emulated_devices) {
  210. if (!entry.Umount(false)) unmount_done = false;
  211. }
  212. if (unmount_done) {
  213. sync();
  214. }
  215. }
  216. for (auto& entry : block_devices) {
  217. if (!entry.Umount(timeout == 0ms)) unmount_done = false;
  218. }
  219. if (unmount_done) {
  220. return UMOUNT_STAT_SUCCESS;
  221. }
  222. if ((timeout < t.duration())) { // try umount at least once
  223. return UMOUNT_STAT_TIMEOUT;
  224. }
  225. std::this_thread::sleep_for(100ms);
  226. }
  227. }
  228. static void KillAllProcesses() { android::base::WriteStringToFile("i", "/proc/sysrq-trigger"); }
  229. /* Try umounting all emulated file systems R/W block device cfile systems.
  230. * This will just try umount and give it up if it fails.
  231. * For fs like ext4, this is ok as file system will be marked as unclean shutdown
  232. * and necessary check can be done at the next reboot.
  233. * For safer shutdown, caller needs to make sure that
  234. * all processes / emulated partition for the target fs are all cleaned-up.
  235. *
  236. * return true when umount was successful. false when timed out.
  237. */
  238. static UmountStat TryUmountAndFsck(bool runFsck, std::chrono::milliseconds timeout) {
  239. Timer t;
  240. std::vector<MountEntry> block_devices;
  241. std::vector<MountEntry> emulated_devices;
  242. if (runFsck && !FindPartitionsToUmount(&block_devices, &emulated_devices, false)) {
  243. return UMOUNT_STAT_ERROR;
  244. }
  245. UmountStat stat = UmountPartitions(timeout - t.duration());
  246. if (stat != UMOUNT_STAT_SUCCESS) {
  247. LOG(INFO) << "umount timeout, last resort, kill all and try";
  248. if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
  249. KillAllProcesses();
  250. // even if it succeeds, still it is timeout and do not run fsck with all processes killed
  251. UmountStat st = UmountPartitions(0ms);
  252. if ((st != UMOUNT_STAT_SUCCESS) && DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
  253. }
  254. if (stat == UMOUNT_STAT_SUCCESS && runFsck) {
  255. // fsck part is excluded from timeout check. It only runs for user initiated shutdown
  256. // and should not affect reboot time.
  257. for (auto& entry : block_devices) {
  258. entry.DoFsck();
  259. }
  260. }
  261. return stat;
  262. }
  263. // zram is able to use backing device on top of a loopback device.
  264. // In order to unmount /data successfully, we have to kill the loopback device first
  265. #define ZRAM_DEVICE "/dev/block/zram0"
  266. #define ZRAM_RESET "/sys/block/zram0/reset"
  267. #define ZRAM_BACK_DEV "/sys/block/zram0/backing_dev"
  268. static void KillZramBackingDevice() {
  269. std::string backing_dev;
  270. if (!android::base::ReadFileToString(ZRAM_BACK_DEV, &backing_dev)) return;
  271. if (!android::base::StartsWith(backing_dev, "/dev/block/loop")) return;
  272. // cut the last "\n"
  273. backing_dev.erase(backing_dev.length() - 1);
  274. // shutdown zram handle
  275. Timer swap_timer;
  276. LOG(INFO) << "swapoff() start...";
  277. if (swapoff(ZRAM_DEVICE) == -1) {
  278. LOG(ERROR) << "zram_backing_dev: swapoff (" << backing_dev << ")" << " failed";
  279. return;
  280. }
  281. LOG(INFO) << "swapoff() took " << swap_timer;;
  282. if (!android::base::WriteStringToFile("1", ZRAM_RESET)) {
  283. LOG(ERROR) << "zram_backing_dev: reset (" << backing_dev << ")" << " failed";
  284. return;
  285. }
  286. // clear loopback device
  287. unique_fd loop(TEMP_FAILURE_RETRY(open(backing_dev.c_str(), O_RDWR | O_CLOEXEC)));
  288. if (loop.get() < 0) {
  289. LOG(ERROR) << "zram_backing_dev: open(" << backing_dev << ")" << " failed";
  290. return;
  291. }
  292. if (ioctl(loop.get(), LOOP_CLR_FD, 0) < 0) {
  293. LOG(ERROR) << "zram_backing_dev: loop_clear (" << backing_dev << ")" << " failed";
  294. return;
  295. }
  296. LOG(INFO) << "zram_backing_dev: `" << backing_dev << "` is cleared successfully.";
  297. }
  298. //* Reboot / shutdown the system.
  299. // cmd ANDROID_RB_* as defined in android_reboot.h
  300. // reason Reason string like "reboot", "shutdown,userrequested"
  301. // rebootTarget Reboot target string like "bootloader". Otherwise, it should be an
  302. // empty string.
  303. // runFsck Whether to run fsck after umount is done.
  304. //
  305. static void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget,
  306. bool runFsck) {
  307. Timer t;
  308. LOG(INFO) << "Reboot start, reason: " << reason << ", rebootTarget: " << rebootTarget;
  309. // Ensure last reboot reason is reduced to canonical
  310. // alias reported in bootloader or system boot reason.
  311. size_t skip = 0;
  312. std::vector<std::string> reasons = Split(reason, ",");
  313. if (reasons.size() >= 2 && reasons[0] == "reboot" &&
  314. (reasons[1] == "recovery" || reasons[1] == "bootloader" || reasons[1] == "cold" ||
  315. reasons[1] == "hard" || reasons[1] == "warm")) {
  316. skip = strlen("reboot,");
  317. }
  318. property_set(LAST_REBOOT_REASON_PROPERTY, reason.c_str() + skip);
  319. sync();
  320. bool is_thermal_shutdown = cmd == ANDROID_RB_THERMOFF;
  321. auto shutdown_timeout = 0ms;
  322. if (!SHUTDOWN_ZERO_TIMEOUT) {
  323. constexpr unsigned int shutdown_timeout_default = 6;
  324. constexpr unsigned int max_thermal_shutdown_timeout = 3;
  325. auto shutdown_timeout_final = android::base::GetUintProperty("ro.build.shutdown_timeout",
  326. shutdown_timeout_default);
  327. if (is_thermal_shutdown && shutdown_timeout_final > max_thermal_shutdown_timeout) {
  328. shutdown_timeout_final = max_thermal_shutdown_timeout;
  329. }
  330. shutdown_timeout = std::chrono::seconds(shutdown_timeout_final);
  331. }
  332. LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " ms";
  333. // keep debugging tools until non critical ones are all gone.
  334. const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"};
  335. // watchdogd is a vendor specific component but should be alive to complete shutdown safely.
  336. const std::set<std::string> to_starts{"watchdogd"};
  337. for (const auto& s : ServiceList::GetInstance()) {
  338. if (kill_after_apps.count(s->name())) {
  339. s->SetShutdownCritical();
  340. } else if (to_starts.count(s->name())) {
  341. if (auto result = s->Start(); !result) {
  342. LOG(ERROR) << "Could not start shutdown 'to_start' service '" << s->name()
  343. << "': " << result.error();
  344. }
  345. s->SetShutdownCritical();
  346. } else if (s->IsShutdownCritical()) {
  347. // Start shutdown critical service if not started.
  348. if (auto result = s->Start(); !result) {
  349. LOG(ERROR) << "Could not start shutdown critical service '" << s->name()
  350. << "': " << result.error();
  351. }
  352. }
  353. }
  354. // remaining operations (specifically fsck) may take a substantial duration
  355. if (cmd == ANDROID_RB_POWEROFF || is_thermal_shutdown) {
  356. TurnOffBacklight();
  357. }
  358. Service* bootAnim = ServiceList::GetInstance().FindService("bootanim");
  359. Service* surfaceFlinger = ServiceList::GetInstance().FindService("surfaceflinger");
  360. if (bootAnim != nullptr && surfaceFlinger != nullptr && surfaceFlinger->IsRunning()) {
  361. bool do_shutdown_animation = GetBoolProperty("ro.init.shutdown_animation", false);
  362. if (do_shutdown_animation) {
  363. property_set("service.bootanim.exit", "0");
  364. // Could be in the middle of animation. Stop and start so that it can pick
  365. // up the right mode.
  366. bootAnim->Stop();
  367. }
  368. for (const auto& service : ServiceList::GetInstance()) {
  369. if (service->classnames().count("animation") == 0) {
  370. continue;
  371. }
  372. // start all animation classes if stopped.
  373. if (do_shutdown_animation) {
  374. service->Start().IgnoreError();
  375. }
  376. service->SetShutdownCritical(); // will not check animation class separately
  377. }
  378. if (do_shutdown_animation) {
  379. bootAnim->Start().IgnoreError();
  380. surfaceFlinger->SetShutdownCritical();
  381. bootAnim->SetShutdownCritical();
  382. }
  383. }
  384. // optional shutdown step
  385. // 1. terminate all services except shutdown critical ones. wait for delay to finish
  386. if (shutdown_timeout > 0ms) {
  387. LOG(INFO) << "terminating init services";
  388. // Ask all services to terminate except shutdown critical ones.
  389. for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
  390. if (!s->IsShutdownCritical()) s->Terminate();
  391. }
  392. int service_count = 0;
  393. // Only wait up to half of timeout here
  394. auto termination_wait_timeout = shutdown_timeout / 2;
  395. while (t.duration() < termination_wait_timeout) {
  396. ReapAnyOutstandingChildren();
  397. service_count = 0;
  398. for (const auto& s : ServiceList::GetInstance()) {
  399. // Count the number of services running except shutdown critical.
  400. // Exclude the console as it will ignore the SIGTERM signal
  401. // and not exit.
  402. // Note: SVC_CONSOLE actually means "requires console" but
  403. // it is only used by the shell.
  404. if (!s->IsShutdownCritical() && s->pid() != 0 && (s->flags() & SVC_CONSOLE) == 0) {
  405. service_count++;
  406. }
  407. }
  408. if (service_count == 0) {
  409. // All terminable services terminated. We can exit early.
  410. break;
  411. }
  412. // Wait a bit before recounting the number or running services.
  413. std::this_thread::sleep_for(50ms);
  414. }
  415. LOG(INFO) << "Terminating running services took " << t
  416. << " with remaining services:" << service_count;
  417. }
  418. // minimum safety steps before restarting
  419. // 2. kill all services except ones that are necessary for the shutdown sequence.
  420. for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
  421. if (!s->IsShutdownCritical()) s->Stop();
  422. }
  423. SubcontextTerminate();
  424. ReapAnyOutstandingChildren();
  425. // 3. send volume shutdown to vold
  426. Service* voldService = ServiceList::GetInstance().FindService("vold");
  427. if (voldService != nullptr && voldService->IsRunning()) {
  428. ShutdownVold();
  429. voldService->Stop();
  430. } else {
  431. LOG(INFO) << "vold not running, skipping vold shutdown";
  432. }
  433. // logcat stopped here
  434. for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
  435. if (kill_after_apps.count(s->name())) s->Stop();
  436. }
  437. // 4. sync, try umount, and optionally run fsck for user shutdown
  438. {
  439. Timer sync_timer;
  440. LOG(INFO) << "sync() before umount...";
  441. sync();
  442. LOG(INFO) << "sync() before umount took" << sync_timer;
  443. }
  444. // 5. drop caches and disable zram backing device, if exist
  445. KillZramBackingDevice();
  446. UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration());
  447. // Follow what linux shutdown is doing: one more sync with little bit delay
  448. {
  449. Timer sync_timer;
  450. LOG(INFO) << "sync() after umount...";
  451. sync();
  452. LOG(INFO) << "sync() after umount took" << sync_timer;
  453. }
  454. if (!is_thermal_shutdown) std::this_thread::sleep_for(100ms);
  455. LogShutdownTime(stat, &t);
  456. // Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.
  457. RebootSystem(cmd, rebootTarget);
  458. abort();
  459. }
  460. bool HandlePowerctlMessage(const std::string& command) {
  461. unsigned int cmd = 0;
  462. std::vector<std::string> cmd_params = Split(command, ",");
  463. std::string reboot_target = "";
  464. bool run_fsck = false;
  465. bool command_invalid = false;
  466. if (cmd_params.size() > 3) {
  467. command_invalid = true;
  468. } else if (cmd_params[0] == "shutdown") {
  469. cmd = ANDROID_RB_POWEROFF;
  470. if (cmd_params.size() == 2) {
  471. if (cmd_params[1] == "userrequested") {
  472. // The shutdown reason is PowerManager.SHUTDOWN_USER_REQUESTED.
  473. // Run fsck once the file system is remounted in read-only mode.
  474. run_fsck = true;
  475. } else if (cmd_params[1] == "thermal") {
  476. // Turn off sources of heat immediately.
  477. TurnOffBacklight();
  478. // run_fsck is false to avoid delay
  479. cmd = ANDROID_RB_THERMOFF;
  480. }
  481. }
  482. } else if (cmd_params[0] == "reboot") {
  483. cmd = ANDROID_RB_RESTART2;
  484. if (cmd_params.size() >= 2) {
  485. reboot_target = cmd_params[1];
  486. // adb reboot fastboot should boot into bootloader for devices not
  487. // supporting logical partitions.
  488. if (reboot_target == "fastboot" &&
  489. !android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {
  490. reboot_target = "bootloader";
  491. }
  492. // When rebooting to the bootloader notify the bootloader writing
  493. // also the BCB.
  494. if (reboot_target == "bootloader") {
  495. std::string err;
  496. if (!write_reboot_bootloader(&err)) {
  497. LOG(ERROR) << "reboot-bootloader: Error writing "
  498. "bootloader_message: "
  499. << err;
  500. }
  501. } else if (reboot_target == "sideload" || reboot_target == "sideload-auto-reboot" ||
  502. reboot_target == "fastboot") {
  503. std::string arg = reboot_target == "sideload-auto-reboot" ? "sideload_auto_reboot"
  504. : reboot_target;
  505. const std::vector<std::string> options = {
  506. "--" + arg,
  507. };
  508. std::string err;
  509. if (!write_bootloader_message(options, &err)) {
  510. LOG(ERROR) << "Failed to set bootloader message: " << err;
  511. return false;
  512. }
  513. reboot_target = "recovery";
  514. }
  515. // If there is an additional parameter, pass it along
  516. if ((cmd_params.size() == 3) && cmd_params[2].size()) {
  517. reboot_target += "," + cmd_params[2];
  518. }
  519. }
  520. } else {
  521. command_invalid = true;
  522. }
  523. if (command_invalid) {
  524. LOG(ERROR) << "powerctl: unrecognized command '" << command << "'";
  525. return false;
  526. }
  527. LOG(INFO) << "Clear action queue and start shutdown trigger";
  528. ActionManager::GetInstance().ClearQueue();
  529. // Queue shutdown trigger first
  530. ActionManager::GetInstance().QueueEventTrigger("shutdown");
  531. // Queue built-in shutdown_done
  532. auto shutdown_handler = [cmd, command, reboot_target, run_fsck](const BuiltinArguments&) {
  533. DoReboot(cmd, command, reboot_target, run_fsck);
  534. return Success();
  535. };
  536. ActionManager::GetInstance().QueueBuiltinAction(shutdown_handler, "shutdown_done");
  537. // Skip wait for prop if it is in progress
  538. ResetWaitForProp();
  539. // Clear EXEC flag if there is one pending
  540. for (const auto& s : ServiceList::GetInstance()) {
  541. s->UnSetExec();
  542. }
  543. return true;
  544. }
  545. } // namespace init
  546. } // namespace android