Loading init/builtins.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -1221,6 +1221,20 @@ static Result<void> GenerateLinkerConfiguration() { return {}; } static Result<void> MountLinkerConfigForDefaultNamespace() { // No need to mount linkerconfig for default mount namespace if the path does not exist (which // would mean it is already mounted) if (access("/linkerconfig/default", 0) != 0) { return {}; } if (mount("/linkerconfig/default", "/linkerconfig", nullptr, MS_BIND | MS_REC, nullptr) != 0) { return ErrnoError() << "Failed to mount linker configuration for default mount namespace."; } return {}; } static bool IsApexUpdatable() { static bool updatable = android::sysprop::ApexProperties::updatable().value_or(false); return updatable; Loading Loading @@ -1319,11 +1333,14 @@ static Result<void> do_perform_apex_config(const BuiltinArguments& args) { } static Result<void> do_enter_default_mount_ns(const BuiltinArguments& args) { if (SwitchToDefaultMountNamespace()) { return {}; } else { return Error() << "Failed to enter into default mount namespace"; if (auto result = SwitchToMountNamespaceIfNeeded(NS_DEFAULT); !result.ok()) { return result.error(); } if (auto result = MountLinkerConfigForDefaultNamespace(); !result.ok()) { return result.error(); } LOG(INFO) << "Switched to default mount namespace"; return {}; } // Builtin-function-map start Loading init/mount_namespace.cpp +11 −45 Original line number Diff line number Diff line Loading @@ -176,20 +176,6 @@ static bool ActivateFlattenedApexesIfPossible() { return true; } static Result<void> MountLinkerConfigForDefaultNamespace() { // No need to mount linkerconfig for default mount namespace if the path does not exist (which // would mean it is already mounted) if (access("/linkerconfig/default", 0) != 0) { return {}; } if (mount("/linkerconfig/default", "/linkerconfig", nullptr, MS_BIND | MS_REC, nullptr) != 0) { return ErrnoError() << "Failed to mount linker configuration for default mount namespace."; } return {}; } static android::base::unique_fd bootstrap_ns_fd; static android::base::unique_fd default_ns_fd; Loading Loading @@ -290,40 +276,20 @@ bool SetupMountNamespaces() { return success; } bool SwitchToDefaultMountNamespace() { if (IsRecoveryMode()) { // we don't have multiple namespaces in recovery mode return true; } if (default_ns_id != GetMountNamespaceId()) { if (setns(default_ns_fd.get(), CLONE_NEWNS) == -1) { PLOG(ERROR) << "Failed to switch back to the default mount namespace."; return false; } if (auto result = MountLinkerConfigForDefaultNamespace(); !result.ok()) { LOG(ERROR) << result.error(); return false; } } LOG(INFO) << "Switched to default mount namespace"; return true; } bool SwitchToBootstrapMountNamespaceIfNeeded() { if (IsRecoveryMode()) { // we don't have multiple namespaces in recovery mode return true; Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace) { if (IsRecoveryMode() || !IsApexUpdatable()) { // we don't have multiple namespaces in recovery mode or if apex is not updatable return {}; } if (bootstrap_ns_id != GetMountNamespaceId() && bootstrap_ns_fd.get() != -1 && IsApexUpdatable()) { if (setns(bootstrap_ns_fd.get(), CLONE_NEWNS) == -1) { PLOG(ERROR) << "Failed to switch to bootstrap mount namespace."; return false; const auto& ns_id = target_mount_namespace == NS_BOOTSTRAP ? bootstrap_ns_id : default_ns_id; const auto& ns_fd = target_mount_namespace == NS_BOOTSTRAP ? bootstrap_ns_fd : default_ns_fd; const auto& ns_name = target_mount_namespace == NS_BOOTSTRAP ? "bootstrap" : "default"; if (ns_id != GetMountNamespaceId() && ns_fd.get() != -1) { if (setns(ns_fd.get(), CLONE_NEWNS) == -1) { return ErrnoError() << "Failed to switch to " << ns_name << " mount namespace."; } } return true; return {}; } } // namespace init Loading init/mount_namespace.h +5 −2 Original line number Diff line number Diff line Loading @@ -16,12 +16,15 @@ #pragma once #include <android-base/result.h> namespace android { namespace init { enum MountNamespace { NS_BOOTSTRAP, NS_DEFAULT }; bool SetupMountNamespaces(); bool SwitchToDefaultMountNamespace(); bool SwitchToBootstrapMountNamespaceIfNeeded(); base::Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace); } // namespace init } // namespace android init/reboot.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -831,7 +831,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"; } Loading init/service.cpp +12 −1 Original line number Diff line number Diff line Loading @@ -465,6 +465,16 @@ Result<void> Service::Start() { pre_apexd_ = true; } // For pre-apexd services, override mount namespace as "bootstrap" one before starting. // Note: "ueventd" is supposed to be run in "default" mount namespace even if it's pre-apexd // to support loading firmwares from APEXes. std::optional<MountNamespace> override_mount_namespace; if (name_ == "ueventd") { override_mount_namespace = NS_DEFAULT; } else if (pre_apexd_) { override_mount_namespace = NS_BOOTSTRAP; } post_data_ = ServiceList::GetInstance().IsPostData(); LOG(INFO) << "starting service '" << name_ << "'..."; Loading Loading @@ -496,7 +506,8 @@ Result<void> Service::Start() { if (pid == 0) { umask(077); if (auto result = EnterNamespaces(namespaces_, name_, pre_apexd_); !result.ok()) { if (auto result = EnterNamespaces(namespaces_, name_, override_mount_namespace); !result.ok()) { LOG(FATAL) << "Service '" << name_ << "' failed to set up namespaces: " << result.error(); } Loading Loading
init/builtins.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -1221,6 +1221,20 @@ static Result<void> GenerateLinkerConfiguration() { return {}; } static Result<void> MountLinkerConfigForDefaultNamespace() { // No need to mount linkerconfig for default mount namespace if the path does not exist (which // would mean it is already mounted) if (access("/linkerconfig/default", 0) != 0) { return {}; } if (mount("/linkerconfig/default", "/linkerconfig", nullptr, MS_BIND | MS_REC, nullptr) != 0) { return ErrnoError() << "Failed to mount linker configuration for default mount namespace."; } return {}; } static bool IsApexUpdatable() { static bool updatable = android::sysprop::ApexProperties::updatable().value_or(false); return updatable; Loading Loading @@ -1319,11 +1333,14 @@ static Result<void> do_perform_apex_config(const BuiltinArguments& args) { } static Result<void> do_enter_default_mount_ns(const BuiltinArguments& args) { if (SwitchToDefaultMountNamespace()) { return {}; } else { return Error() << "Failed to enter into default mount namespace"; if (auto result = SwitchToMountNamespaceIfNeeded(NS_DEFAULT); !result.ok()) { return result.error(); } if (auto result = MountLinkerConfigForDefaultNamespace(); !result.ok()) { return result.error(); } LOG(INFO) << "Switched to default mount namespace"; return {}; } // Builtin-function-map start Loading
init/mount_namespace.cpp +11 −45 Original line number Diff line number Diff line Loading @@ -176,20 +176,6 @@ static bool ActivateFlattenedApexesIfPossible() { return true; } static Result<void> MountLinkerConfigForDefaultNamespace() { // No need to mount linkerconfig for default mount namespace if the path does not exist (which // would mean it is already mounted) if (access("/linkerconfig/default", 0) != 0) { return {}; } if (mount("/linkerconfig/default", "/linkerconfig", nullptr, MS_BIND | MS_REC, nullptr) != 0) { return ErrnoError() << "Failed to mount linker configuration for default mount namespace."; } return {}; } static android::base::unique_fd bootstrap_ns_fd; static android::base::unique_fd default_ns_fd; Loading Loading @@ -290,40 +276,20 @@ bool SetupMountNamespaces() { return success; } bool SwitchToDefaultMountNamespace() { if (IsRecoveryMode()) { // we don't have multiple namespaces in recovery mode return true; } if (default_ns_id != GetMountNamespaceId()) { if (setns(default_ns_fd.get(), CLONE_NEWNS) == -1) { PLOG(ERROR) << "Failed to switch back to the default mount namespace."; return false; } if (auto result = MountLinkerConfigForDefaultNamespace(); !result.ok()) { LOG(ERROR) << result.error(); return false; } } LOG(INFO) << "Switched to default mount namespace"; return true; } bool SwitchToBootstrapMountNamespaceIfNeeded() { if (IsRecoveryMode()) { // we don't have multiple namespaces in recovery mode return true; Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace) { if (IsRecoveryMode() || !IsApexUpdatable()) { // we don't have multiple namespaces in recovery mode or if apex is not updatable return {}; } if (bootstrap_ns_id != GetMountNamespaceId() && bootstrap_ns_fd.get() != -1 && IsApexUpdatable()) { if (setns(bootstrap_ns_fd.get(), CLONE_NEWNS) == -1) { PLOG(ERROR) << "Failed to switch to bootstrap mount namespace."; return false; const auto& ns_id = target_mount_namespace == NS_BOOTSTRAP ? bootstrap_ns_id : default_ns_id; const auto& ns_fd = target_mount_namespace == NS_BOOTSTRAP ? bootstrap_ns_fd : default_ns_fd; const auto& ns_name = target_mount_namespace == NS_BOOTSTRAP ? "bootstrap" : "default"; if (ns_id != GetMountNamespaceId() && ns_fd.get() != -1) { if (setns(ns_fd.get(), CLONE_NEWNS) == -1) { return ErrnoError() << "Failed to switch to " << ns_name << " mount namespace."; } } return true; return {}; } } // namespace init Loading
init/mount_namespace.h +5 −2 Original line number Diff line number Diff line Loading @@ -16,12 +16,15 @@ #pragma once #include <android-base/result.h> namespace android { namespace init { enum MountNamespace { NS_BOOTSTRAP, NS_DEFAULT }; bool SetupMountNamespaces(); bool SwitchToDefaultMountNamespace(); bool SwitchToBootstrapMountNamespaceIfNeeded(); base::Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace); } // namespace init } // namespace android
init/reboot.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -831,7 +831,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"; } Loading
init/service.cpp +12 −1 Original line number Diff line number Diff line Loading @@ -465,6 +465,16 @@ Result<void> Service::Start() { pre_apexd_ = true; } // For pre-apexd services, override mount namespace as "bootstrap" one before starting. // Note: "ueventd" is supposed to be run in "default" mount namespace even if it's pre-apexd // to support loading firmwares from APEXes. std::optional<MountNamespace> override_mount_namespace; if (name_ == "ueventd") { override_mount_namespace = NS_DEFAULT; } else if (pre_apexd_) { override_mount_namespace = NS_BOOTSTRAP; } post_data_ = ServiceList::GetInstance().IsPostData(); LOG(INFO) << "starting service '" << name_ << "'..."; Loading Loading @@ -496,7 +506,8 @@ Result<void> Service::Start() { if (pid == 0) { umask(077); if (auto result = EnterNamespaces(namespaces_, name_, pre_apexd_); !result.ok()) { if (auto result = EnterNamespaces(namespaces_, name_, override_mount_namespace); !result.ok()) { LOG(FATAL) << "Service '" << name_ << "' failed to set up namespaces: " << result.error(); } Loading