diff --git a/init/builtins.cpp b/init/builtins.cpp index dcc9582e2..035038f32 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -1278,6 +1278,14 @@ static Result GenerateLinkerConfiguration() { return ErrnoError() << "failed to execute linkerconfig"; } + auto current_mount_ns = GetCurrentMountNamespace(); + if (!current_mount_ns.ok()) { + return current_mount_ns.error(); + } + if (*current_mount_ns == NS_DEFAULT) { + SetDefaultMountNamespaceReady(); + } + LOG(INFO) << "linkerconfig generated " << linkerconfig_target << " with mounted APEX modules info"; diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp index ec48cde02..15252a622 100644 --- a/init/mount_namespace.cpp +++ b/init/mount_namespace.cpp @@ -301,5 +301,20 @@ Result SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespac return {}; } +base::Result GetCurrentMountNamespace() { + std::string current_namespace_id = GetMountNamespaceId(); + if (current_namespace_id == "") { + return Error() << "Failed to get current mount namespace ID"; + } + + if (current_namespace_id == bootstrap_ns_id) { + return NS_BOOTSTRAP; + } else if (current_namespace_id == default_ns_id) { + return NS_DEFAULT; + } + + return Error() << "Failed to find current mount namespace"; +} + } // namespace init } // namespace android diff --git a/init/mount_namespace.h b/init/mount_namespace.h index d4d6f82da..5e3dab241 100644 --- a/init/mount_namespace.h +++ b/init/mount_namespace.h @@ -26,5 +26,7 @@ enum MountNamespace { NS_BOOTSTRAP, NS_DEFAULT }; bool SetupMountNamespaces(); base::Result SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace); +base::Result GetCurrentMountNamespace(); + } // namespace init } // namespace android diff --git a/init/service.cpp b/init/service.cpp index cfb82842d..836dc4722 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -125,11 +125,6 @@ static bool ExpandArgsAndExecv(const std::vector& args, bool sigsto return execv(c_strings[0], c_strings.data()) == 0; } -static bool AreRuntimeApexesReady() { - struct stat buf; - return stat("/apex/com.android.runtime/", &buf) == 0; -} - unsigned long Service::next_start_order_ = 1; bool Service::is_exec_service_running_ = false; @@ -312,7 +307,7 @@ void Service::Reap(const siginfo_t& siginfo) { #else static bool is_apex_updatable = false; #endif - const bool is_process_updatable = !pre_apexd_ && is_apex_updatable; + const bool is_process_updatable = !use_bootstrap_ns_ && is_apex_updatable; // If we crash > 4 times in 'fatal_crash_window_' minutes or before boot_completed, // reboot into bootloader or set crashing property @@ -465,12 +460,12 @@ Result Service::Start() { scon = *result; } - if (!AreRuntimeApexesReady() && !pre_apexd_) { - // If this service is started before the Runtime and ART APEXes get - // available, mark it as pre-apexd one. Note that this marking is + if (!IsDefaultMountNamespaceReady() && name_ != "apexd") { + // If this service is started before APEXes and corresponding linker configuration + // get available, mark it as pre-apexd one. Note that this marking is // permanent. So for example, if the service is re-launched (e.g., due // to crash), it is still recognized as pre-apexd... for consistency. - pre_apexd_ = true; + use_bootstrap_ns_ = true; } // For pre-apexd services, override mount namespace as "bootstrap" one before starting. @@ -479,7 +474,7 @@ Result Service::Start() { std::optional override_mount_namespace; if (name_ == "ueventd") { override_mount_namespace = NS_DEFAULT; - } else if (pre_apexd_) { + } else if (use_bootstrap_ns_) { override_mount_namespace = NS_BOOTSTRAP; } diff --git a/init/service.h b/init/service.h index aee1e5dfa..043555fa4 100644 --- a/init/service.h +++ b/init/service.h @@ -207,7 +207,7 @@ class Service { std::vector> reap_callbacks_; - bool pre_apexd_ = false; + bool use_bootstrap_ns_ = false; bool post_data_ = false; diff --git a/init/util.cpp b/init/util.cpp index e69b43f8c..eab99d4e3 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -735,5 +735,16 @@ bool IsRecoveryMode() { return access("/system/bin/recovery", F_OK) == 0; } +// Check if default mount namespace is ready to be used with APEX modules +static bool is_default_mount_namespace_ready = false; + +bool IsDefaultMountNamespaceReady() { + return is_default_mount_namespace_ready; +} + +void SetDefaultMountNamespaceReady() { + is_default_mount_namespace_ready = true; +} + } // namespace init } // namespace android diff --git a/init/util.h b/init/util.h index 7745d775a..daba85247 100644 --- a/init/util.h +++ b/init/util.h @@ -100,5 +100,8 @@ Result ParseUmountAll(const std::vector& args); void SetStdioToDevNull(char** argv); void InitKernelLogging(char** argv); bool IsRecoveryMode(); + +bool IsDefaultMountNamespaceReady(); +void SetDefaultMountNamespaceReady(); } // namespace init } // namespace android