Bionic libs and the dynamic linker are bind mounted
This change makes the bionic libs and the dynamic linker from the
runtime APEX (com.android.runtime) available to all processes started
after apexd finishes activating APEXes.
Specifically, the device has two sets of bionic libs and the dynamic
linker: one in the system partition for pre-apexd processes and another
in the runtime APEX for post-apexd processes. The former is referred as
the 'bootstrap' bionic and are located at
/system/lib/{libc|libdl|libm}.so and /system/bin/linker. The latter is
referred as the 'runtime' bionic and are located at
/apex/com.android.runtime/lib/bionic/{libc|libdl|libm}.so and
/apex/com.android.runtime/bin/linker.
Although the two sets are located in different directories, at runtime,
they are accessed via the same path: /system/lib/* and
/system/bin/linker ... for both pre/post-apexd processes. This is done
by bind-mounting the bootstrap or the runtime bionic to the same path.
Keeping the same path is necessary because there are many modules and
apps that explicitly or implicitly depend on the fact that bionic libs
are located in /system/lib and are loaded into the default linker
namespace (which has /system/lib in its search paths).
Before the apexd is started, init executes a built-in action
'prepare_bootstrap_bionic' that bind-mounts the bootstrap bionic to the
mount points. Processes started during this time are provided with the
bootstrap bionic. Then after the apexd is finished, init executes
another built-in action 'setup_runtime_bionic' which again mounts the
runtime bionic to the same mount points, thus hiding the previous mounts
that target the bootstrap bionic. The mounting of the runtime bionic
(which is only for post-apexd processes) is hidden from pre-apexd
processes by changing propagation type of the mount points to 'private'
and execute the pre-apexd processes with a new mount namespace using
unshare(2). If a pre-apexd process crashes and re-launched after the
apexd is on, the process still gets the bootstrap bionic by unmounting
the runtime bionic which effectively un-hides the previous bind-mounts
targeting the bootstrap bionic.
Bug: 120266448
Test: device boots
Test: cat /proc/`pidof zygote`/mountinfo shows that
/system/lib/{libc|libdl|libm}.so and /system/bin/linker are from the
runtime APEX
Test: cat /proc/'pidof vold`/mountinfo shows that the same mount points
are from system partition.
Change-Id: I7ca67755dc0656c0f0c834ba94bf23ba9b1aca68
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