Loading cmds/installd/Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -189,8 +189,8 @@ cc_binary { "liblog", "libutils", ], static_libs: [ "libapexd", required: [ "apexd" ], } Loading cmds/installd/otapreopt_chroot.cpp +28 −57 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <sys/stat.h> #include <sys/wait.h> #include <array> #include <fstream> #include <sstream> Loading @@ -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" Loading Loading @@ -64,47 +61,14 @@ static void CloseDescriptor(const char* descriptor_string) { } } 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 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 ActivateApexPackages() { std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--otachroot-bootstrap"}; std::string apexd_error_msg; 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); } } Loading Loading @@ -269,8 +233,7 @@ static int otapreopt_chroot(const int argc, char **arg) { // 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. Loading @@ -278,16 +241,27 @@ static int otapreopt_chroot(const int argc, char **arg) { "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) { Loading Loading @@ -323,9 +297,6 @@ static int otapreopt_chroot(const int argc, char **arg) { 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); } Loading Loading
cmds/installd/Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -189,8 +189,8 @@ cc_binary { "liblog", "libutils", ], static_libs: [ "libapexd", required: [ "apexd" ], } Loading
cmds/installd/otapreopt_chroot.cpp +28 −57 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <sys/stat.h> #include <sys/wait.h> #include <array> #include <fstream> #include <sstream> Loading @@ -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" Loading Loading @@ -64,47 +61,14 @@ static void CloseDescriptor(const char* descriptor_string) { } } 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 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 ActivateApexPackages() { std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--otachroot-bootstrap"}; std::string apexd_error_msg; 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); } } Loading Loading @@ -269,8 +233,7 @@ static int otapreopt_chroot(const int argc, char **arg) { // 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. Loading @@ -278,16 +241,27 @@ static int otapreopt_chroot(const int argc, char **arg) { "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) { Loading Loading @@ -323,9 +297,6 @@ static int otapreopt_chroot(const int argc, char **arg) { 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); } Loading