Merge "Check if service is executed before APEX is ready"

This commit is contained in:
Kiyoung Kim 2021-03-07 23:56:06 +00:00 committed by Gerrit Code Review
commit fcb28f5d30
7 changed files with 46 additions and 12 deletions

View file

@ -1278,6 +1278,14 @@ static Result<void> 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";

View file

@ -301,5 +301,20 @@ Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespac
return {};
}
base::Result<MountNamespace> 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

View file

@ -26,5 +26,7 @@ enum MountNamespace { NS_BOOTSTRAP, NS_DEFAULT };
bool SetupMountNamespaces();
base::Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace);
base::Result<MountNamespace> GetCurrentMountNamespace();
} // namespace init
} // namespace android

View file

@ -125,11 +125,6 @@ static bool ExpandArgsAndExecv(const std::vector<std::string>& 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<void> 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<void> Service::Start() {
std::optional<MountNamespace> 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;
}

View file

@ -207,7 +207,7 @@ class Service {
std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
bool pre_apexd_ = false;
bool use_bootstrap_ns_ = false;
bool post_data_ = false;

View file

@ -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

View file

@ -100,5 +100,8 @@ Result<std::string> ParseUmountAll(const std::vector<std::string>& args);
void SetStdioToDevNull(char** argv);
void InitKernelLogging(char** argv);
bool IsRecoveryMode();
bool IsDefaultMountNamespaceReady();
void SetDefaultMountNamespaceReady();
} // namespace init
} // namespace android