diff options
| author | 2019-01-31 18:30:17 +0000 | |
|---|---|---|
| committer | 2019-02-01 13:27:27 +0000 | |
| commit | c3265aef20d4afca0eb62d0ce02fdbc8a254c421 (patch) | |
| tree | 54b38e19c4cba1e5ee2e010124e2d86bb84d314f | |
| parent | 6520ccab30167593f447c0183d78f78d0b56ceb9 (diff) | |
Have `otapreopt_chroot` bind-mount Bionic artifacts from the Runtime APEX.
Have `otapreopt_chroot` bind-mount Bionic artifacts (`linker(64)`,
`libc.so`, `libm.so`, `libdl.so`) from the Runtime APEX
(`/postinstall/apex/com.android.runtime`) into `/postinstall/bionic/`,
much the same way `init` sets up Bionic bind-mounts in the default
mount namespace.
Test: m otapreopt_chroot
Test: A/B OTA update test (asit/dexoptota/self_full).
Bug: 113373927
Bug: 120266448
Change-Id: Ie254a94ae35e62f88375bc89380456f15796566a
| -rw-r--r-- | cmds/installd/otapreopt_chroot.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp index 1c996632bf..609ddaf9d7 100644 --- a/cmds/installd/otapreopt_chroot.cpp +++ b/cmds/installd/otapreopt_chroot.cpp @@ -41,6 +41,23 @@ using android::base::StringPrintf; namespace android { namespace installd { +// Configuration for bind-mounted Bionic artifacts. + +static constexpr const char* kLinkerMountPoint = "/bionic/bin/linker"; +static constexpr const char* kRuntimeLinkerPath = "/apex/com.android.runtime/bin/linker"; + +static constexpr const char* kBionicLibsMountPointDir = "/bionic/lib/"; +static constexpr const char* kRuntimeBionicLibsDir = "/apex/com.android.runtime/lib/bionic/"; + +static constexpr const char* kLinkerMountPoint64 = "/bionic/bin/linker64"; +static constexpr const char* kRuntimeLinkerPath64 = "/apex/com.android.runtime/bin/linker64"; + +static constexpr const char* kBionicLibsMountPointDir64 = "/bionic/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"}; + + static void CloseDescriptor(int fd) { if (fd >= 0) { int result = close(fd); @@ -79,6 +96,43 @@ static void DeactivateApexPackages(const std::vector<apex::ApexFile>& active_pac } } +// Copied from system/core/init/mount_namespace.cpp. +static bool BindMount(const std::string& source, const std::string& mount_point, + bool recursive = false) { + unsigned long mountflags = MS_BIND; + if (recursive) { + mountflags |= MS_REC; + } + if (mount(source.c_str(), mount_point.c_str(), nullptr, mountflags, nullptr) == -1) { + PLOG(ERROR) << "Could not bind-mount " << source << " to " << mount_point; + return false; + } + return true; +} + +// Copied from system/core/init/mount_namespace.cpp and and adjusted (bind +// mounts are not made private, as the /postinstall is already private (see +// `android::installd::otapreopt_chroot`). +static bool BindMountBionic(const std::string& linker_source, const std::string& lib_dir_source, + const std::string& linker_mount_point, + const std::string& lib_mount_dir) { + if (access(linker_source.c_str(), F_OK) != 0) { + PLOG(INFO) << linker_source << " does not exist. Skipping mounting Bionic there."; + return true; + } + if (!BindMount(linker_source, linker_mount_point)) { + return false; + } + for (const auto& libname : kBionicLibFileNames) { + std::string mount_point = lib_mount_dir + libname; + std::string source = lib_dir_source + libname; + if (!BindMount(source, mount_point)) { + return false; + } + } + return true; +} + // Entry for otapreopt_chroot. Expected parameters are: // [cmd] [status-fd] [target-slot] "dexopt" [dexopt-params] // The file descriptor denoted by status-fd will be closed. The rest of the parameters will @@ -222,6 +276,23 @@ static int otapreopt_chroot(const int argc, char **arg) { // the Android Runtime APEX, as it is required by otapreopt to run dex2oat. std::vector<apex::ApexFile> active_packages = ActivateApexPackages(); + // Bind-mount Bionic artifacts from the Runtime APEX. + // This logic is copied and adapted from system/core/init/mount_namespace.cpp. + if (!BindMountBionic(kRuntimeLinkerPath, kRuntimeBionicLibsDir, kLinkerMountPoint, + kBionicLibsMountPointDir)) { + LOG(ERROR) << "Failed to mount 32-bit Bionic artifacts from the Runtime APEX."; + // Clean up and exit. + DeactivateApexPackages(active_packages); + exit(215); + } + if (!BindMountBionic(kRuntimeLinkerPath64, kRuntimeBionicLibsDir64, kLinkerMountPoint64, + kBionicLibsMountPointDir64)) { + LOG(ERROR) << "Failed to mount 64-bit Bionic artifacts from the Runtime APEX."; + // Clean up and exit. + DeactivateApexPackages(active_packages); + exit(216); + } + // Now go on and run otapreopt. // Incoming: cmd + status-fd + target-slot + cmd... | Incoming | = argc |