diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp index 5305dc7ef..12144c120 100644 --- a/init/mount_namespace.cpp +++ b/init/mount_namespace.cpp @@ -79,6 +79,38 @@ static bool IsApexUpdatable() { return updatable; } +static bool ActivateFlattenedApexesIfPossible() { + if (IsRecoveryMode() || IsApexUpdatable()) { + return true; + } + + constexpr const char kSystemApex[] = "/system/apex"; + constexpr const char kApexTop[] = "/apex"; + if (mount(kSystemApex, kApexTop, nullptr, MS_BIND, nullptr) != 0) { + PLOG(ERROR) << "Could not bind mount " << kSystemApex << " to " << kApexTop; + return false; + } + + // Special casing for the runtime APEX + constexpr const char kRuntimeApexMountPath[] = "/system/apex/com.android.runtime"; + static const std::vector kRuntimeApexDirNames = {"com.android.runtime.release", + "com.android.runtime.debug"}; + bool success = false; + for (const auto& name : kRuntimeApexDirNames) { + std::string path = std::string(kSystemApex) + "/" + name; + if (access(path.c_str(), F_OK) == 0) { + if (mount(path.c_str(), kRuntimeApexMountPath, nullptr, MS_BIND, nullptr) == 0) { + success = true; + break; + } + } + } + if (!success) { + PLOG(ERROR) << "Failed to bind mount the runtime APEX to " << kRuntimeApexMountPath; + } + return success; +} + static android::base::unique_fd bootstrap_ns_fd; static android::base::unique_fd default_ns_fd; @@ -129,6 +161,8 @@ bool SetupMountNamespaces() { default_ns_id = GetMountNamespaceId(); } + success &= ActivateFlattenedApexesIfPossible(); + LOG(INFO) << "SetupMountNamespaces done"; return success; } diff --git a/init/service.cpp b/init/service.cpp index 6887d7b2f..3e865a7bd 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -46,6 +46,7 @@ #include "util.h" #if defined(__ANDROID__) +#include #include #include @@ -372,10 +373,17 @@ void Service::Reap(const siginfo_t& siginfo) { return; } +#if defined(__ANDROID__) + static bool is_apex_updatable = android::sysprop::ApexProperties::updatable().value_or(false); +#else + static bool is_apex_updatable = false; +#endif + const bool is_process_updatable = !pre_apexd_ && is_apex_updatable; + // If we crash > 4 times in 4 minutes or before boot_completed, // reboot into bootloader or set crashing property boot_clock::time_point now = boot_clock::now(); - if (((flags_ & SVC_CRITICAL) || !pre_apexd_) && !(flags_ & SVC_RESTART)) { + if (((flags_ & SVC_CRITICAL) || is_process_updatable) && !(flags_ & SVC_RESTART)) { bool boot_completed = android::base::GetBoolProperty("sys.boot_completed", false); if (now < time_crashed_ + 4min || !boot_completed) { if (++crash_count_ > 4) {