diff options
Diffstat (limited to 'init/reboot.cpp')
-rw-r--r-- | init/reboot.cpp | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/init/reboot.cpp b/init/reboot.cpp index 23a07aa644..49baf9e687 100644 --- a/init/reboot.cpp +++ b/init/reboot.cpp @@ -544,6 +544,18 @@ static int StopServicesAndLogViolations(const std::vector<Service*>& services, return still_running; } +static Result<void> UnmountAllApexes() { + const char* args[] = {"/system/bin/apexd", "--unmount-all"}; + int status; + if (logwrap_fork_execvp(arraysize(args), args, &status, false, LOG_KLOG, true, nullptr) != 0) { + return ErrnoError() << "Failed to call '/system/bin/apexd --unmount-all'"; + } + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { + return {}; + } + return Error() << "'/system/bin/apexd --unmount-all' failed : " << status; +} + //* Reboot / shutdown the system. // cmd ANDROID_RB_* as defined in android_reboot.h // reason Reason string like "reboot", "shutdown,userrequested" @@ -701,6 +713,11 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str // 5. drop caches and disable zram backing device, if exist KillZramBackingDevice(); + LOG(INFO) << "Ready to unmount apexes. So far shutdown sequence took " << t; + // 6. unmount active apexes, otherwise they might prevent clean unmount of /data. + if (auto ret = UnmountAllApexes(); !ret.ok()) { + LOG(ERROR) << ret.error(); + } UmountStat stat = TryUmountAndFsck(cmd, run_fsck, shutdown_timeout - t.duration(), &reboot_semaphore); // Follow what linux shutdown is doing: one more sync with little bit delay @@ -739,18 +756,6 @@ static void LeaveShutdown() { StartSendingMessages(); } -static Result<void> UnmountAllApexes() { - const char* args[] = {"/system/bin/apexd", "--unmount-all"}; - int status; - if (logwrap_fork_execvp(arraysize(args), args, &status, false, LOG_KLOG, true, nullptr) != 0) { - return ErrnoError() << "Failed to call '/system/bin/apexd --unmount-all'"; - } - if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { - return {}; - } - return Error() << "'/system/bin/apexd --unmount-all' failed : " << status; -} - static std::chrono::milliseconds GetMillisProperty(const std::string& name, std::chrono::milliseconds default_value) { auto value = GetUintProperty(name, static_cast<uint64_t>(default_value.count())); @@ -802,11 +807,19 @@ static Result<void> DoUserspaceReboot() { auto sigkill_timeout = GetMillisProperty("init.userspace_reboot.sigkill.timeoutmillis", 10s); LOG(INFO) << "Timeout to terminate services: " << sigterm_timeout.count() << "ms " << "Timeout to kill services: " << sigkill_timeout.count() << "ms"; + std::string services_file_name = "/metadata/userspacereboot/services.txt"; + const int flags = O_RDWR | O_CREAT | O_SYNC | O_APPEND | O_CLOEXEC; StopServicesAndLogViolations(stop_first, sigterm_timeout, true /* SIGTERM */); if (int r = StopServicesAndLogViolations(stop_first, sigkill_timeout, false /* SIGKILL */); r > 0) { + auto fd = unique_fd(TEMP_FAILURE_RETRY(open(services_file_name.c_str(), flags, 0666))); + android::base::WriteStringToFd("Post-data services still running: \n", fd); + for (const auto& s : stop_first) { + if (s->IsRunning()) { + android::base::WriteStringToFd(s->name() + "\n", fd); + } + } sub_reason = "sigkill"; - // TODO(b/135984674): store information about offending services for debugging. return Error() << r << " post-data services are still running"; } if (auto result = KillZramBackingDevice(); !result.ok()) { @@ -820,8 +833,14 @@ static Result<void> DoUserspaceReboot() { if (int r = StopServicesAndLogViolations(GetDebuggingServices(true /* only_post_data */), sigkill_timeout, false /* SIGKILL */); r > 0) { + auto fd = unique_fd(TEMP_FAILURE_RETRY(open(services_file_name.c_str(), flags, 0666))); + android::base::WriteStringToFd("Debugging services still running: \n", fd); + for (const auto& s : GetDebuggingServices(true)) { + if (s->IsRunning()) { + android::base::WriteStringToFd(s->name() + "\n", fd); + } + } sub_reason = "sigkill_debug"; - // TODO(b/135984674): store information about offending services for debugging. return Error() << r << " debugging services are still running"; } { @@ -834,7 +853,7 @@ static Result<void> DoUserspaceReboot() { sub_reason = "apex"; return result; } - if (!SwitchToBootstrapMountNamespaceIfNeeded()) { + if (!SwitchToMountNamespaceIfNeeded(NS_BOOTSTRAP)) { sub_reason = "ns_switch"; return Error() << "Failed to switch to bootstrap namespace"; } |