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

Commit 8a3d4d4e authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topics "ota-apex-list", "otapreopt-linkerconfig"

* changes:
  Generate apex-info-list.xml in the ota chroot
  Make otapreopt_chroot setup linker
parents c9c0dfbf cf7e6de6
Loading
Loading
Loading
Loading
+55 −8
Original line number Original line Diff line number Diff line
@@ -20,15 +20,19 @@
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/wait.h>


#include <fstream>
#include <sstream>
#include <sstream>


#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <libdm/dm.h>
#include <libdm/dm.h>
#include <selinux/android.h>
#include <selinux/android.h>


#include <apex_file_repository.h>
#include <apex_file_repository.h>
#include <apex_constants.h>
#include <apexd.h>
#include <apexd.h>


#include "installd_constants.h"
#include "installd_constants.h"
@@ -77,6 +81,22 @@ static std::vector<apex::ApexFile> ActivateApexPackages() {
    return apex::GetActivePackages();
    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 DeactivateApexPackages(const std::vector<apex::ApexFile>& active_packages) {
static void DeactivateApexPackages(const std::vector<apex::ApexFile>& active_packages) {
    for (const apex::ApexFile& apex_file : active_packages) {
    for (const apex::ApexFile& apex_file : active_packages) {
        const std::string& package_path = apex_file.GetPath();
        const std::string& package_path = apex_file.GetPath();
@@ -185,6 +205,13 @@ static int otapreopt_chroot(const int argc, char **arg) {
    // want it for product APKs. Same notes as vendor above.
    // want it for product APKs. Same notes as vendor above.
    TryExtraMount("product", arg[2], "/postinstall/product");
    TryExtraMount("product", arg[2], "/postinstall/product");


    constexpr const char* kPostInstallLinkerconfig = "/postinstall/linkerconfig";
    // Try to mount /postinstall/linkerconfig. we will set it up after performing the chroot
    if (mount("tmpfs", kPostInstallLinkerconfig, "tmpfs", 0, nullptr) != 0) {
        PLOG(ERROR) << "Failed to mount a tmpfs for " << kPostInstallLinkerconfig;
        exit(215);
    }

    // Setup APEX mount point and its security context.
    // Setup APEX mount point and its security context.
    static constexpr const char* kPostinstallApexDir = "/postinstall/apex";
    static constexpr const char* kPostinstallApexDir = "/postinstall/apex";
    // The following logic is similar to the one in system/core/rootdir/init.rc:
    // The following logic is similar to the one in system/core/rootdir/init.rc:
@@ -243,18 +270,38 @@ static int otapreopt_chroot(const int argc, char **arg) {
    // Try to mount APEX packages in "/apex" in the chroot dir. We need at least
    // 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.
    // the ART APEX, as it is required by otapreopt to run dex2oat.
    std::vector<apex::ApexFile> active_packages = ActivateApexPackages();
    std::vector<apex::ApexFile> active_packages = ActivateApexPackages();
    CreateApexInfoList(active_packages);


    // Check that an ART APEX has been activated; clean up and exit
    // Check that an ART APEX has been activated; clean up and exit
    // early otherwise.
    // early otherwise.
    if (std::none_of(active_packages.begin(),
    static constexpr const std::string_view kRequiredApexs[] = {
                     active_packages.end(),
      "com.android.art",
                     [](const apex::ApexFile& package){
      "com.android.runtime",
                         return package.GetManifest().name() == "com.android.art";
    };
    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 com.android.art APEX package.";
            LOG(FATAL_WITHOUT_ABORT) << "No activated " << apex << " APEX package.";
            DeactivateApexPackages(active_packages);
            DeactivateApexPackages(active_packages);
            exit(217);
            exit(217);
        }
        }
    }

    // Setup /linkerconfig. Doing it after the chroot means it doesn't need its own category
    if (selinux_android_restorecon("/linkerconfig", 0) < 0) {
        PLOG(ERROR) << "Failed to restorecon /linkerconfig";
        exit(219);
    }
    std::vector<std::string> linkerconfig_cmd{"/apex/com.android.runtime/bin/linkerconfig",
                                              "--target", "/linkerconfig"};
    std::string linkerconfig_error_msg;
    bool linkerconfig_exec_result = Exec(linkerconfig_cmd, &linkerconfig_error_msg);
    if (!linkerconfig_exec_result) {
        LOG(ERROR) << "Running linkerconfig failed: " << linkerconfig_error_msg;
        exit(218);
    }


    // Now go on and run otapreopt.
    // Now go on and run otapreopt.