Merge changes from topic "move_bionic_to_apex"
* changes:
Don't create separate mount namespaces for pre-apexd processes
Bionic libs are located at /system/lib
Bionic libs and the dynamic linker are bind mounted
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 52828c0..4a66e46 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -1093,6 +1093,86 @@
}
}
+static Result<Success> bind_mount_file(const char* source, const char* mount_point,
+ bool remount_private) {
+ if (remount_private && mount(nullptr, mount_point, nullptr, MS_PRIVATE, nullptr) == -1) {
+ return ErrnoError() << "Could not change " << mount_point << " to a private mount point";
+ }
+ if (mount(source, mount_point, nullptr, MS_BIND, nullptr) == -1) {
+ return ErrnoError() << "Could not bind-mount " << source << " to " << mount_point;
+ }
+ return Success();
+}
+
+static Result<Success> bind_mount_bionic(const char* linker_source, const char* lib_dir_source,
+ const char* linker_mount_point, const char* lib_mount_dir,
+ bool remount_private) {
+ if (access(linker_source, F_OK) != 0) {
+ return Success();
+ }
+ if (auto result = bind_mount_file(linker_source, linker_mount_point, remount_private);
+ !result) {
+ return result;
+ }
+ for (auto libname : kBionicLibFileNames) {
+ std::string mount_point = lib_mount_dir + libname;
+ std::string source = lib_dir_source + libname;
+ if (auto result = bind_mount_file(source.c_str(), mount_point.c_str(), remount_private);
+ !result) {
+ return result;
+ }
+ }
+ return Success();
+}
+
+// The bootstrap bionic libs and the bootstrap linker are bind-mounted to
+// the mount points for pre-apexd processes.
+static Result<Success> do_prepare_bootstrap_bionic(const BuiltinArguments& args) {
+ static bool prepare_bootstrap_bionic_done = false;
+ if (prepare_bootstrap_bionic_done) {
+ return Error() << "prepare_bootstrap_bionic was already executed. Cannot be executed again";
+ }
+ if (auto result = bind_mount_bionic(kBootstrapLinkerPath, kBootstrapBionicLibsDir,
+ kLinkerMountPoint, kBionicLibsMountPointDir, false);
+ !result) {
+ return result;
+ }
+ if (auto result = bind_mount_bionic(kBootstrapLinkerPath64, kBootstrapBionicLibsDir64,
+ kLinkerMountPoint64, kBionicLibsMountPointDir64, false);
+ !result) {
+ return result;
+ }
+
+ LOG(INFO) << "prepare_bootstrap_bionic done";
+ prepare_bootstrap_bionic_done = true;
+ return Success();
+}
+
+// The bionic libs and the dynamic linker from the runtime APEX are bind-mounted
+// to the mount points. As a result, the previous mounts done by
+// prepare_bootstrap_bionic become hidden.
+static Result<Success> do_setup_runtime_bionic(const BuiltinArguments& args) {
+ static bool setup_runtime_bionic_done = false;
+ if (setup_runtime_bionic_done) {
+ return Error() << "setup_runtime_bionic was already executed. Cannot be executed again";
+ }
+ if (auto result = bind_mount_bionic(kRuntimeLinkerPath, kRuntimeBionicLibsDir,
+ kLinkerMountPoint, kBionicLibsMountPointDir, true);
+ !result) {
+ return result;
+ }
+ if (auto result = bind_mount_bionic(kRuntimeLinkerPath64, kRuntimeBionicLibsDir64,
+ kLinkerMountPoint64, kBionicLibsMountPointDir64, true);
+ !result) {
+ return result;
+ }
+
+ ServiceList::GetInstance().MarkRuntimeAvailable();
+ LOG(INFO) << "setup_runtime_bionic done";
+ setup_runtime_bionic_done = true;
+ return Success();
+}
+
// Builtin-function-map start
const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
@@ -1131,6 +1211,7 @@
{"mount_all", {1, kMax, {false, do_mount_all}}},
{"mount", {3, kMax, {false, do_mount}}},
{"parse_apex_configs", {0, 0, {false, do_parse_apex_configs}}},
+ {"prepare_bootstrap_bionic",{0, 0, {false, do_prepare_bootstrap_bionic}}},
{"umount", {1, 1, {false, do_umount}}},
{"readahead", {1, 2, {true, do_readahead}}},
{"restart", {1, 1, {false, do_restart}}},
@@ -1139,6 +1220,7 @@
{"rm", {1, 1, {true, do_rm}}},
{"rmdir", {1, 1, {true, do_rmdir}}},
{"setprop", {2, 2, {true, do_setprop}}},
+ {"setup_runtime_bionic", {0, 0, {false, do_setup_runtime_bionic}}},
{"setrlimit", {3, 3, {false, do_setrlimit}}},
{"start", {1, 1, {false, do_start}}},
{"stop", {1, 1, {false, do_stop}}},
diff --git a/init/service.cpp b/init/service.cpp
index 272809f..eec55c3 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -140,6 +140,43 @@
return Success();
}
+Result<Success> Service::SetUpPreApexdMounts() const {
+ // If a pre-apexd service is 're' launched after the runtime APEX is
+ // available, unmount the linker and bionic libs which are currently
+ // bind mounted to the files in the runtime APEX. This will reveal
+ // the hidden mount points (targetting the bootstrap ones in the
+ // system partition) which were setup before the runtime APEX was
+ // started. Note that these unmounts are done in a separate mount namespace
+ // for the process. It does not affect other processes including the init.
+ if (pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) {
+ if (access(kLinkerMountPoint, F_OK) == 0) {
+ if (umount(kLinkerMountPoint) == -1) {
+ return ErrnoError() << "Could not umount " << kLinkerMountPoint;
+ }
+ for (const auto& libname : kBionicLibFileNames) {
+ std::string mount_point = kBionicLibsMountPointDir + libname;
+ if (umount(mount_point.c_str()) == -1) {
+ return ErrnoError() << "Could not umount " << mount_point;
+ }
+ }
+ }
+
+ if (access(kLinkerMountPoint64, F_OK) == 0) {
+ if (umount(kLinkerMountPoint64) == -1) {
+ return ErrnoError() << "Could not umount " << kLinkerMountPoint64;
+ }
+ for (const auto& libname : kBionicLibFileNames) {
+ std::string mount_point = kBionicLibsMountPointDir64 + libname;
+ std::string source = kBootstrapBionicLibsDir64 + libname;
+ if (umount(mount_point.c_str()) == -1) {
+ return ErrnoError() << "Could not umount " << mount_point;
+ }
+ }
+ }
+ }
+ return Success();
+}
+
Result<Success> Service::SetUpPidNamespace() const {
if (prctl(PR_SET_NAME, name_.c_str()) == -1) {
return ErrnoError() << "Could not set name";
@@ -929,6 +966,14 @@
scon = *result;
}
+ if (!ServiceList::GetInstance().IsRuntimeAvailable() && !pre_apexd_) {
+ // If this service is started before the runtime APEX gets 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;
+ }
+
LOG(INFO) << "starting service '" << name_ << "'...";
pid_t pid = -1;
@@ -945,6 +990,37 @@
LOG(FATAL) << "Service '" << name_ << "' could not enter namespaces: " << result.error();
}
+ // b/122559956: mount namespace is not cloned for the devices that don't support
+ // the update of bionic libraries via APEX. In that case, because the bionic
+ // libraries in the runtime APEX and the bootstrap bionic libraries are
+ // identical, it doesn't matter which libs are used. This is also to avoid the
+ // bug in sdcardfs which is triggered when we have multiple mount namespaces
+ // across vold and the others. BIONIC_UPDATABLE shall be true only for the
+ // devices where kernel has the fix for the sdcardfs bug (see the commit message
+ // for the fix).
+ static bool bionic_updatable =
+ android::base::GetBoolProperty("ro.apex.bionic_updatable", false);
+
+ if (bionic_updatable && pre_apexd_) {
+ // pre-apexd process gets a private copy of the mount namespace.
+ // However, this does not mean that mount/unmount events are not
+ // shared across pre-apexd processes and post-apexd processes.
+ // *Most* of the events are still shared because the propagation
+ // type of / is set to 'shared'. (see `mount rootfs rootfs /shared
+ // rec` in init.rc)
+ //
+ // This unsharing is required to not propagate the mount events
+ // under /system/lib/{libc|libdl|libm}.so and /system/bin/linker(64)
+ // whose propagation type is set to private. With this,
+ // bind-mounting the bionic libs and the dynamic linker from the
+ // runtime APEX to the mount points does not affect pre-apexd
+ // processes which should use the bootstrap ones.
+ if (unshare(CLONE_NEWNS) != 0) {
+ LOG(FATAL) << "Creating a new mount namespace for service"
+ << " '" << name_ << "' failed: " << strerror(errno);
+ }
+ }
+
if (namespace_flags_ & CLONE_NEWNS) {
if (auto result = SetUpMountNamespace(); !result) {
LOG(FATAL) << "Service '" << name_
@@ -952,6 +1028,14 @@
}
}
+ // b/122559956: same as above
+ if (bionic_updatable && pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) {
+ if (auto result = SetUpPreApexdMounts(); !result) {
+ LOG(FATAL) << "Pre-apexd service '" << name_
+ << "' could not setup the mount points: " << result.error();
+ }
+ }
+
if (namespace_flags_ & CLONE_NEWPID) {
// This will fork again to run an init process inside the PID
// namespace.
@@ -1324,6 +1408,10 @@
delayed_service_names_.clear();
}
+void ServiceList::MarkRuntimeAvailable() {
+ runtime_available_ = true;
+}
+
void ServiceList::DelayService(const Service& service) {
if (services_update_finished_) {
LOG(ERROR) << "Cannot delay the start of service '" << service.name()
diff --git a/init/service.h b/init/service.h
index 56e75b0..676111f 100644
--- a/init/service.h
+++ b/init/service.h
@@ -62,6 +62,24 @@
namespace android {
namespace init {
+static constexpr const char* kLinkerMountPoint = "/system/bin/linker";
+static constexpr const char* kBootstrapLinkerPath = "/system/bin/linker";
+static constexpr const char* kRuntimeLinkerPath = "/apex/com.android.runtime/bin/linker";
+
+static constexpr const char* kBionicLibsMountPointDir = "/system/lib/";
+static constexpr const char* kBootstrapBionicLibsDir = "/system/lib/";
+static constexpr const char* kRuntimeBionicLibsDir = "/apex/com.android.runtime/lib/bionic/";
+
+static constexpr const char* kLinkerMountPoint64 = "/system/bin/linker64";
+static constexpr const char* kBootstrapLinkerPath64 = "/system/bin/linker64";
+static constexpr const char* kRuntimeLinkerPath64 = "/apex/com.android.runtime/bin/linker64";
+
+static constexpr const char* kBionicLibsMountPointDir64 = "/system/lib64/";
+static constexpr const char* kBootstrapBionicLibsDir64 = "/system/lib64/";
+static constexpr const char* kRuntimeBionicLibsDir64 = "/apex/com.android.runtime/lib64/bionic/";
+
+static const std::vector<std::string> kBionicLibFileNames = {"libc.so", "libm.so", "libdl.so"};
+
class Service {
public:
Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
@@ -124,6 +142,7 @@
std::optional<std::chrono::seconds> timeout_period() const { return timeout_period_; }
const std::vector<std::string>& args() const { return args_; }
bool is_updatable() const { return updatable_; }
+ bool is_pre_apexd() const { return pre_apexd_; }
private:
using OptionParser = Result<Success> (Service::*)(std::vector<std::string>&& args);
@@ -132,6 +151,7 @@
Result<Success> SetUpMountNamespace() const;
Result<Success> SetUpPidNamespace() const;
Result<Success> EnterNamespaces() const;
+ Result<Success> SetUpPreApexdMounts() const;
void NotifyStateChange(const std::string& new_state) const;
void StopOrReset(int how);
void ZapStdio() const;
@@ -242,6 +262,8 @@
std::vector<std::string> args_;
std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
+
+ bool pre_apexd_ = false;
};
class ServiceList {
@@ -284,13 +306,16 @@
const std::vector<Service*> services_in_shutdown_order() const;
void MarkServicesUpdate();
+ void MarkRuntimeAvailable();
bool IsServicesUpdated() const { return services_update_finished_; }
+ bool IsRuntimeAvailable() const { return runtime_available_; }
void DelayService(const Service& service);
private:
std::vector<std::unique_ptr<Service>> services_;
bool services_update_finished_ = false;
+ bool runtime_available_ = false;
std::vector<std::string> delayed_service_names_;
};
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 5601e53..2dda648 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -109,8 +109,7 @@
# Keep in sync with ld.config.txt in the com.android.runtime APEX.
namespace.default.links = runtime
-namespace.default.link.runtime.shared_libs = libc.so:libdl.so:libm.so
-namespace.default.link.runtime.shared_libs += libart.so:libartd.so
+namespace.default.link.runtime.shared_libs = libart.so:libartd.so
namespace.default.link.runtime.shared_libs += libnativebridge.so
namespace.default.link.runtime.shared_libs += libnativehelper.so
namespace.default.link.runtime.shared_libs += libnativeloader.so
@@ -163,12 +162,8 @@
# Once in this namespace, access to libraries in /system/lib is restricted. Only
# libs listed here can be used.
-namespace.sphal.links = runtime,default,vndk,rs
+namespace.sphal.links = default,vndk,rs
-namespace.sphal.link.runtime.shared_libs = libc.so:libdl.so:libm.so
-
-# LLNDK_LIBRARIES includes the runtime libs above, but the order here ensures
-# that they are loaded from the runtime namespace.
namespace.sphal.link.default.shared_libs = %LLNDK_LIBRARIES%
namespace.sphal.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -215,9 +210,7 @@
namespace.rs.asan.permitted.paths += /vendor/${LIB}
namespace.rs.asan.permitted.paths += /data
-namespace.rs.links = runtime,default,vndk
-
-namespace.rs.link.runtime.shared_libs = libc.so:libdl.so:libm.so
+namespace.rs.links = default,vndk
namespace.rs.link.default.shared_libs = %LLNDK_LIBRARIES%
namespace.rs.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -265,13 +258,10 @@
namespace.vndk.asan.permitted.paths += /data/asan/system/${LIB}/vndk-sp%VNDK_VER%/hw
namespace.vndk.asan.permitted.paths += /system/${LIB}/vndk-sp%VNDK_VER%/hw
-# The "vndk" namespace links to "runtime" for Bionic libs, "default" namespace
-# for LLNDK libs, and links to "sphal" namespace for vendor libs. The ordering
-# matters. The "default" namespace has higher priority than the "sphal"
-# namespace.
-namespace.vndk.links = runtime,default,sphal
-
-namespace.vndk.link.runtime.shared_libs = libc.so:libdl.so:libm.so
+# The "vndk" namespace links to "default" namespace for LLNDK libs and links to
+# "sphal" namespace for vendor libs. The ordering matters. The "default"
+# namespace has higher priority than the "sphal" namespace.
+namespace.vndk.links = default,sphal
# When these NDK libs are required inside this namespace, then it is redirected
# to the default namespace. This is possible since their ABI is stable across
@@ -290,7 +280,7 @@
# (LL-NDK only) access.
###############################################################################
[vendor]
-additional.namespaces = runtime,system,vndk
+additional.namespaces = system,vndk
###############################################################################
# "default" namespace
@@ -321,24 +311,12 @@
namespace.default.asan.permitted.paths += /data/asan/vendor
namespace.default.asan.permitted.paths += /vendor
-namespace.default.links = runtime,system,vndk
-namespace.default.link.runtime.shared_libs = libc.so:libdl.so:libm.so
+namespace.default.links = system,vndk
namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%
namespace.default.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES%
namespace.default.link.vndk.shared_libs += %VNDK_CORE_LIBRARIES%
###############################################################################
-# "runtime" APEX namespace
-#
-# This namespace pulls in externally accessible libs from the Runtime APEX.
-###############################################################################
-namespace.runtime.isolated = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.links = system
-# TODO(b/119867084): Restrict to Bionic dlopen dependencies.
-namespace.runtime.link.system.allow_all_shared_libs = true
-
-###############################################################################
# "vndk" namespace
#
# This namespace is where VNDK and VNDK-SP libraries are loaded for
@@ -369,9 +347,7 @@
# When these NDK libs are required inside this namespace, then it is redirected
# to the system namespace. This is possible since their ABI is stable across
# Android releases.
-namespace.vndk.links = runtime,system,default
-
-namespace.vndk.link.runtime.shared_libs = libc.so:libdl.so:libm.so
+namespace.vndk.links = system,default
namespace.vndk.link.system.shared_libs = %LLNDK_LIBRARIES%
namespace.vndk.link.system.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -397,36 +373,16 @@
namespace.system.asan.search.paths += /data/asan/product_services/${LIB}
namespace.system.asan.search.paths += /%PRODUCT_SERVICES%/${LIB}
-namespace.system.links = runtime
-namespace.system.link.runtime.shared_libs = libc.so:libdl.so:libm.so
-
-
###############################################################################
# Namespace config for binaries under /postinstall.
-# Only default and runtime namespaces are defined and default has no directories
+# Only default namespace is defined and default has no directories
# other than /system/lib in the search paths. This is because linker calls
# realpath on the search paths and this causes selinux denial if the paths
# (/vendor, /odm) are not allowed to the postinstall binaries. There is no
# reason to allow the binaries to access the paths.
###############################################################################
[postinstall]
-additional.namespaces = runtime
-
namespace.default.isolated = false
namespace.default.search.paths = /system/${LIB}
namespace.default.search.paths += /%PRODUCT%/${LIB}
namespace.default.search.paths += /%PRODUCT_SERVICES%/${LIB}
-
-namespace.default.links = runtime
-namespace.default.link.runtime.shared_libs = libc.so:libdl.so:libm.so
-
-###############################################################################
-# "runtime" APEX namespace
-#
-# This namespace pulls in externally accessible libs from the Runtime APEX.
-###############################################################################
-namespace.runtime.isolated = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.links = default
-# TODO(b/119867084): Restrict to Bionic dlopen dependencies.
-namespace.runtime.link.default.allow_all_shared_libs = true
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index 7ca45ff..33b4698 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -57,8 +57,7 @@
# Keep in sync with ld.config.txt in the com.android.runtime APEX.
namespace.default.links = runtime
-namespace.default.link.runtime.shared_libs = libc.so:libdl.so:libm.so
-namespace.default.link.runtime.shared_libs += libart.so:libartd.so
+namespace.default.link.runtime.shared_libs = libart.so:libartd.so
namespace.default.link.runtime.shared_libs += libnativehelper.so
namespace.default.link.runtime.shared_libs += libnativeloader.so
@@ -110,12 +109,8 @@
# Once in this namespace, access to libraries in /system/lib is restricted. Only
# libs listed here can be used.
-namespace.sphal.links = runtime,default,vndk,rs
+namespace.sphal.links = default,vndk,rs
-namespace.sphal.link.runtime.shared_libs = libc.so:libdl.so:libm.so
-
-# LLNDK_LIBRARIES includes the runtime libs above, but the order here ensures
-# that they are loaded from the runtime namespace.
namespace.sphal.link.default.shared_libs = %LLNDK_LIBRARIES%
namespace.sphal.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -162,9 +157,7 @@
namespace.rs.asan.permitted.paths += /vendor/${LIB}
namespace.rs.asan.permitted.paths += /data
-namespace.rs.links = runtime,default,vndk
-
-namespace.rs.link.runtime.shared_libs = libc.so:libdl.so:libm.so
+namespace.rs.links = default,vndk
namespace.rs.link.default.shared_libs = %LLNDK_LIBRARIES%
namespace.rs.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -215,9 +208,7 @@
# When these NDK libs are required inside this namespace, then it is redirected
# to the default namespace. This is possible since their ABI is stable across
# Android releases.
-namespace.vndk.links = runtime,default
-
-namespace.vndk.link.runtime.shared_libs = libc.so:libdl.so:libm.so
+namespace.vndk.links = default
namespace.vndk.link.default.shared_libs = %LLNDK_LIBRARIES%
namespace.vndk.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -230,7 +221,6 @@
# (LL-NDK only) access.
###############################################################################
[vendor]
-additional.namespaces = runtime
namespace.default.isolated = false
namespace.default.search.paths = /odm/${LIB}
@@ -270,47 +260,16 @@
namespace.default.asan.search.paths += /data/asan/product_services/${LIB}
namespace.default.asan.search.paths += /%PRODUCT_SERVICES%/${LIB}
-namespace.default.links = runtime
-namespace.default.link.runtime.shared_libs = libc.so:libdl.so:libm.so
-
-###############################################################################
-# "runtime" APEX namespace
-#
-# This namespace pulls in externally accessible libs from the Runtime APEX.
-###############################################################################
-namespace.runtime.isolated = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.links = default
-# TODO(b/119867084): Restrict to Bionic dlopen dependencies.
-namespace.runtime.link.default.allow_all_shared_libs = true
-
-
###############################################################################
# Namespace config for binaries under /postinstall.
-# Only default and runtime namespaces are defined and default has no directories
+# Only default namespace is defined and default has no directories
# other than /system/lib in the search paths. This is because linker calls
# realpath on the search paths and this causes selinux denial if the paths
# (/vendor, /odm) are not allowed to the postinstall binaries. There is no
# reason to allow the binaries to access the paths.
###############################################################################
[postinstall]
-additional.namespaces = runtime
-
namespace.default.isolated = false
namespace.default.search.paths = /system/${LIB}
namespace.default.search.paths += /%PRODUCT%/${LIB}
namespace.default.search.paths += /%PRODUCT_SERVICES%/${LIB}
-
-namespace.default.links = runtime
-namespace.default.link.runtime.shared_libs = libc.so:libdl.so:libm.so
-
-###############################################################################
-# "runtime" APEX namespace
-#
-# This namespace pulls in externally accessible libs from the Runtime APEX.
-###############################################################################
-namespace.runtime.isolated = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.links = default
-# TODO(b/119867084): Restrict to Bionic dlopen dependencies.
-namespace.runtime.link.default.allow_all_shared_libs = true
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 0ec6e17..b34399d 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -12,6 +12,12 @@
import /init.${ro.zygote}.rc
on early-init
+ # Mount shared so changes propagate into child namespaces
+ # Do this before other processes are started from init. Otherwise,
+ # processes launched while the propagation type of / is 'private'
+ # won't get mount events from others.
+ mount rootfs rootfs / shared rec
+
# Set init and its forked children's oom_adj.
write /proc/1/oom_score_adj -1000
@@ -40,6 +46,8 @@
# cgroup for system_server and surfaceflinger
mkdir /dev/memcg/system 0550 system system
+ prepare_bootstrap_bionic
+
start ueventd
on init
@@ -350,8 +358,6 @@
# Once everything is setup, no need to modify /.
# The bind+remount combination allows this to work in containers.
mount rootfs rootfs / remount bind ro nodev
- # Mount shared so changes propagate into child namespaces
- mount rootfs rootfs / shared rec
# Mount default storage into root namespace
mount none /mnt/runtime/default /storage bind rec
mount none none /storage slave rec
@@ -587,6 +593,14 @@
# Check any timezone data in /data is newer than the copy in the runtime module, delete if not.
exec - system system -- /system/bin/tzdatacheck /apex/com.android.runtime/etc/tz /data/misc/zoneinfo
+ # Wait for apexd to finish activating APEXes before starting more processes.
+ # This certainly reduces the parallelism but is required to make as many processes
+ # as possible to use the bionic libs from the runtime APEX. This takes less than 50ms
+ # so the impact on the booting time is not significant.
+ wait_for_prop apexd.status ready
+ setup_runtime_bionic
+ parse_apex_configs
+
# If there is no post-fs-data action in the init.<device>.rc file, you
# must uncomment this line, otherwise encrypted filesystems
# won't work.
@@ -808,6 +822,3 @@
service flash_recovery /system/bin/install-recovery.sh
class main
oneshot
-
-on property:apexd.status=ready
- parse_apex_configs