Merge "Use apexd to set up chroot apex dir" into sc-dev
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index 5c2211f..a546236 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -189,8 +189,8 @@
"liblog",
"libutils",
],
- static_libs: [
- "libapexd",
+ required: [
+ "apexd"
],
}
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 379cf92..c04b558 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -20,6 +20,7 @@
#include <sys/stat.h>
#include <sys/wait.h>
+#include <array>
#include <fstream>
#include <sstream>
@@ -31,10 +32,6 @@
#include <libdm/dm.h>
#include <selinux/android.h>
-#include <apex_file_repository.h>
-#include <apex_constants.h>
-#include <apexd.h>
-
#include "installd_constants.h"
#include "otapreopt_utils.h"
@@ -64,47 +61,14 @@
}
}
-static std::vector<apex::ApexFile> ActivateApexPackages() {
- // The logic here is (partially) copied and adapted from
- // system/apex/apexd/apexd.cpp.
- //
- // Only scan the APEX directory under /system, /system_ext and /vendor (within the chroot dir).
- std::vector<std::string> apex_dirs{apex::kApexPackageSystemDir, apex::kApexPackageSystemExtDir,
- apex::kApexPackageVendorDir};
- // Initialize ApexFileRepository used internally in ScanPackagesDirAndActivate.
- // This is a quick fix to fix apex activation in otapreopt_chroot.
- apex::ApexFileRepository::GetInstance().AddPreInstalledApex(apex_dirs);
- for (const auto& dir : apex_dirs) {
- // Cast call to void to suppress warn_unused_result.
- static_cast<void>(apex::ScanPackagesDirAndActivate(dir.c_str()));
- }
- return apex::GetActivePackages();
-}
+static void ActivateApexPackages() {
+ std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--otachroot-bootstrap"};
+ std::string apexd_error_msg;
-static void CreateApexInfoList(const std::vector<apex::ApexFile>& apex_files) {
- // Setup the apex-info-list.xml file
- const std::string apex_info_file = std::string(apex::kApexRoot) + "/" + apex::kApexInfoList;
- std::fstream xml(apex_info_file.c_str(), std::ios::out | std::ios::trunc);
- if (!xml.is_open()) {
- PLOG(ERROR) << "Failed to open " << apex_info_file;
- exit(216);
- }
-
- // we do not care about inactive apexs
- std::vector<apex::ApexFile> inactive;
- apex::CollectApexInfoList(xml, apex_files, inactive);
- xml.flush();
- xml.close();
-}
-
-static void DeactivateApexPackages(const std::vector<apex::ApexFile>& active_packages) {
- for (const apex::ApexFile& apex_file : active_packages) {
- const std::string& package_path = apex_file.GetPath();
- base::Result<void> status = apex::DeactivatePackage(package_path);
- if (!status.ok()) {
- LOG(ERROR) << "Failed to deactivate " << package_path << ": "
- << status.error();
- }
+ bool exec_result = Exec(apexd_cmd, &apexd_error_msg);
+ if (!exec_result) {
+ PLOG(ERROR) << "Running otapreopt failed: " << apexd_error_msg;
+ exit(220);
}
}
@@ -269,8 +233,7 @@
// Try to mount APEX packages in "/apex" in the chroot dir. We need at least
// the ART APEX, as it is required by otapreopt to run dex2oat.
- std::vector<apex::ApexFile> active_packages = ActivateApexPackages();
- CreateApexInfoList(active_packages);
+ ActivateApexPackages();
// Check that an ART APEX has been activated; clean up and exit
// early otherwise.
@@ -278,16 +241,27 @@
"com.android.art",
"com.android.runtime",
};
- for (std::string_view apex : kRequiredApexs) {
- if (std::none_of(active_packages.begin(), active_packages.end(),
- [&](const apex::ApexFile& package) {
- return package.GetManifest().name() == apex;
- })) {
- LOG(FATAL_WITHOUT_ABORT) << "No activated " << apex << " APEX package.";
- DeactivateApexPackages(active_packages);
- exit(217);
+ std::array<bool, arraysize(kRequiredApexs)> found_apexs{ false, false };
+ DIR* apex_dir = opendir("/apex");
+ if (apex_dir == nullptr) {
+ PLOG(ERROR) << "unable to open /apex";
+ exit(220);
+ }
+ for (dirent* entry = readdir(apex_dir); entry != nullptr; entry = readdir(apex_dir)) {
+ for (int i = 0; i < found_apexs.size(); i++) {
+ if (kRequiredApexs[i] == std::string_view(entry->d_name)) {
+ found_apexs[i] = true;
+ break;
+ }
}
}
+ closedir(apex_dir);
+ auto it = std::find(found_apexs.cbegin(), found_apexs.cend(), false);
+ if (it != found_apexs.cend()) {
+ LOG(ERROR) << "No activated " << kRequiredApexs[std::distance(found_apexs.cbegin(), it)]
+ << " package!";
+ exit(221);
+ }
// Setup /linkerconfig. Doing it after the chroot means it doesn't need its own category
if (selinux_android_restorecon("/linkerconfig", 0) < 0) {
@@ -323,9 +297,6 @@
LOG(ERROR) << "Running otapreopt failed: " << error_msg;
}
- // Tear down the work down by the apexd logic. (i.e. deactivate packages).
- DeactivateApexPackages(active_packages);
-
if (!exec_result) {
exit(213);
}