Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 566c6523 authored by Jooyung Han's avatar Jooyung Han
Browse files

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
parent 790c6315
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -832,6 +832,12 @@ static void MountExtraFilesystems() {
    CHECKCALL(mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
                    "mode=0755,uid=0,gid=0"));

    if (NeedsTwoMountNamespaces()) {
        // /bootstrap-apex is used to mount "bootstrap" APEXes.
        CHECKCALL(mount("tmpfs", "/bootstrap-apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
                        "mode=0755,uid=0,gid=0"));
    }

    // /linkerconfig is used to keep generated linker configuration
    CHECKCALL(mount("tmpfs", "/linkerconfig", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
                    "mode=0755,uid=0,gid=0"));
+26 −9
Original line number Diff line number Diff line
@@ -66,15 +66,6 @@ static std::string GetMountNamespaceId() {
    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 @@ static std::string default_ns_id;

}  // 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 @@ bool SetupMountNamespaces() {
            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());
+3 −0
Original line number Diff line number Diff line
@@ -24,9 +24,12 @@ namespace init {
enum MountNamespace { NS_BOOTSTRAP, NS_DEFAULT };

bool SetupMountNamespaces();

base::Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace);

base::Result<MountNamespace> GetCurrentMountNamespace();

bool NeedsTwoMountNamespaces();

}  // namespace init
}  // namespace android
+1 −1
Original line number Diff line number Diff line
@@ -757,7 +757,7 @@ void SelinuxRestoreContext() {
    selinux_android_restorecon("/dev/device-mapper", 0);

    selinux_android_restorecon("/apex", 0);

    selinux_android_restorecon("/bootstrap-apex", 0);
    selinux_android_restorecon("/linkerconfig", 0);

    // adb remount, snapshot-based updates, and DSUs all create files during
+1 −1
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ endif
#
# create some directories (some are mount points) and symlinks
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
    dev proc sys system data data_mirror odm oem acct config storage mnt apex debug_ramdisk \
    dev proc sys system data data_mirror odm oem acct config storage mnt apex bootstrap-apex debug_ramdisk \
    linkerconfig second_stage_resources postinstall $(BOARD_ROOT_EXTRA_FOLDERS)); \
    ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \
    ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \