Use /bootstrap-apex for bootstrap APEXes
This new directory is bind-mounted to /apex in the bootstrap mount
namespace so that apexd-bootstrap mounts bootstrap APEXes there via
/apex.
The directory is shared between two mount namespaces, hence visible
in the default mount namespace.
Bug: 290148078
Test: VendorApexHostTestCases
Change-Id: I841480e41be8def5a4c6a4aa874c4e21465a71d3
diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp
index 5b53d50..7918f23 100644
--- a/init/mount_namespace.cpp
+++ b/init/mount_namespace.cpp
@@ -66,15 +66,6 @@
return ret;
}
-// In case we have two sets of APEXes (non-updatable, updatable), we need two separate mount
-// namespaces.
-static bool NeedsTwoMountNamespaces() {
- if (IsRecoveryMode()) return false;
- // In microdroid, there's only one set of APEXes in built-in directories include block devices.
- if (IsMicrodroid()) return false;
- return true;
-}
-
static android::base::unique_fd bootstrap_ns_fd;
static android::base::unique_fd default_ns_fd;
@@ -83,6 +74,15 @@
} // namespace
+// In case we have two sets of APEXes (non-updatable, updatable), we need two separate mount
+// namespaces.
+bool NeedsTwoMountNamespaces() {
+ if (IsRecoveryMode()) return false;
+ // In microdroid, there's only one set of APEXes in built-in directories include block devices.
+ if (IsMicrodroid()) return false;
+ return true;
+}
+
bool SetupMountNamespaces() {
// Set the propagation type of / as shared so that any mounting event (e.g.
// /data) is by default visible to all processes. When private mounting is
@@ -163,6 +163,23 @@
PLOG(ERROR) << "Cannot switch back to bootstrap mount namespace";
return false;
}
+
+ // Some components (e.g. servicemanager) need to access bootstrap
+ // APEXes from the default mount namespace. To achieve that, we bind-mount
+ // /apex to /bootstrap-apex in the bootstrap mount namespace. Since /bootstrap-apex
+ // is "shared", the mounts are visible in the default mount namespace as well.
+ //
+ // The end result will look like:
+ // in the bootstrap mount namespace:
+ // /apex (== /bootstrap-apex)
+ // {bootstrap APEXes from the read-only partition}
+ //
+ // in the default mount namespace:
+ // /bootstrap-apex
+ // {bootstrap APEXes from the read-only partition}
+ // /apex
+ // {APEXes, can be from /data partition}
+ if (!(BindMount("/bootstrap-apex", "/apex"))) return false;
} else {
// Otherwise, default == bootstrap
default_ns_fd.reset(OpenMountNamespace());