From 1d96ec3641da30a39181469d26b010bd230a9783 Mon Sep 17 00:00:00 2001 From: Nikita Ioffe Date: Thu, 16 Apr 2020 21:37:03 +0100 Subject: [PATCH] Cleanup logic in KillZramBackingDevice Since this function is used in userspace reboot, we need to be more diligent with error handling, e.g.: * If init fails to read /sys/block/zram0/backing_dev, then fail and fallback to hard reboot. * Always call swapoff. * Always reset zram. * Tear down loop device only if zram is backed by a loop device. Test: adb reboot userspace Bug: 153917129 Change-Id: I4709da1d08cf427ad9c898cfb2506b6a29f1d680 Former-commit-id: a840d405ebfbbbd18450f9a32933701dd417d3a4 --- init/reboot.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/init/reboot.cpp b/init/reboot.cpp index 2f9166325..72f0450da 100644 --- a/init/reboot.cpp +++ b/init/reboot.cpp @@ -203,6 +203,7 @@ static void TurnOffBacklight() { } static Result CallVdc(const std::string& system, const std::string& cmd) { + LOG(INFO) << "Calling /system/bin/vdc " << system << " " << cmd; const char* vdc_argv[] = {"/system/bin/vdc", system.c_str(), cmd.c_str()}; int status; if (logwrap_fork_execvp(arraysize(vdc_argv), vdc_argv, &status, false, LOG_KLOG, true, @@ -456,10 +457,14 @@ static UmountStat TryUmountAndFsck(unsigned int cmd, bool run_fsck, #define ZRAM_RESET "/sys/block/zram0/reset" #define ZRAM_BACK_DEV "/sys/block/zram0/backing_dev" static Result KillZramBackingDevice() { + if (access(ZRAM_BACK_DEV, F_OK) != 0 && errno == ENOENT) { + LOG(INFO) << "No zram backing device configured"; + return {}; + } std::string backing_dev; - if (!android::base::ReadFileToString(ZRAM_BACK_DEV, &backing_dev)) return {}; - - if (!android::base::StartsWith(backing_dev, "/dev/block/loop")) return {}; + if (!android::base::ReadFileToString(ZRAM_BACK_DEV, &backing_dev)) { + return ErrnoError() << "Failed to read " << ZRAM_BACK_DEV; + } // cut the last "\n" backing_dev.erase(backing_dev.length() - 1); @@ -478,6 +483,11 @@ static Result KillZramBackingDevice() { << " failed"; } + if (!android::base::StartsWith(backing_dev, "/dev/block/loop")) { + LOG(INFO) << backing_dev << " is not a loop device. Exiting early"; + return {}; + } + // clear loopback device unique_fd loop(TEMP_FAILURE_RETRY(open(backing_dev.c_str(), O_RDWR | O_CLOEXEC))); if (loop.get() < 0) { @@ -785,7 +795,7 @@ static Result DoUserspaceReboot() { } auto sigterm_timeout = GetMillisProperty("init.userspace_reboot.sigterm.timeoutmillis", 5s); auto sigkill_timeout = GetMillisProperty("init.userspace_reboot.sigkill.timeoutmillis", 10s); - LOG(INFO) << "Timeout to terminate services : " << sigterm_timeout.count() << "ms" + LOG(INFO) << "Timeout to terminate services: " << sigterm_timeout.count() << "ms " << "Timeout to kill services: " << sigkill_timeout.count() << "ms"; StopServicesAndLogViolations(stop_first, sigterm_timeout, true /* SIGTERM */); if (int r = StopServicesAndLogViolations(stop_first, sigkill_timeout, false /* SIGKILL */);