summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Victor Hsieh <victorhsieh@google.com> 2021-06-14 12:48:10 -0700
committer Treehugger Robot <treehugger-gerrit@google.com> 2021-06-16 16:52:52 +0000
commitb3a4e01448a32b2dc53cad8a981ed7c75d12d2cc (patch)
tree6bf28066ed85e965d1bc141abcdac5c3a5a72a7f
parent0be3da60fa382ded4a3f9b714d9da4e22667e15a (diff)
odrefresh: Support option to run dex2oat in PVM
pvm_exec is an executable to run a command remotely, assuming the code is also in the VM. Since the input files may not be available in the VM, pvm_exec internally takes over the FDs and becomes a file server. In the remote execution setup, dex2oat receives the same FD numbers, and relies on "authfs", a FUSE client that talkes to the file server, to translate the read/write. By wrapping dex2oat with pvm_exec, this change makes it possible run dex2oat remotely, though not necessarily securely. For example, a command is not a secure interface since it allows unlimited numbers of combination of input paramters (or even allow manipulating the compilation, e.g. by adjusting Java property). We'll need to change the interface later. But in the meantime, this change will allow us to iterate more easily. Bug: 187346876 Test: 1. Start a PVM with ART and CompOS apex mounted 2. /apex/com.android.art/bin/odrefresh --use-compos=$CID \ --force-compile # odrefresh returns successfully (though much slower right now) Change-Id: I722e5290246e180a89f6d42d9a6bc10c79dc0d1a
-rw-r--r--odrefresh/odr_config.h4
-rw-r--r--odrefresh/odrefresh.cc44
2 files changed, 46 insertions, 2 deletions
diff --git a/odrefresh/odr_config.h b/odrefresh/odr_config.h
index 41619442c6..89ca8c735a 100644
--- a/odrefresh/odr_config.h
+++ b/odrefresh/odr_config.h
@@ -54,6 +54,7 @@ class OdrConfig final {
std::string system_server_classpath_;
std::string updatable_bcp_packages_file_;
ZygoteKind zygote_kind_;
+ std::string compilation_os_address_;
public:
explicit OdrConfig(const char* program_name)
@@ -117,6 +118,8 @@ class OdrConfig final {
bool GetDryRun() const { return dry_run_; }
const std::string& GetSystemServerClasspath() const { return system_server_classpath_; }
const std::string& GetUpdatableBcpPackagesFile() const { return updatable_bcp_packages_file_; }
+ bool UseCompilationOs() const { return !compilation_os_address_.empty(); }
+ std::string GetCompilationOsAddress() const { return compilation_os_address_; }
void SetApexInfoListFile(const std::string& file_path) { apex_info_list_file_ = file_path; }
void SetArtBinDir(const std::string& art_bin_dir) { art_bin_dir_ = art_bin_dir; }
@@ -127,6 +130,7 @@ class OdrConfig final {
void SetDryRun() { dry_run_ = true; }
void SetIsa(const InstructionSet isa) { isa_ = isa; }
+ void SetCompilationOsAddress(const std::string& address) { compilation_os_address_ = address; }
void SetSystemServerClasspath(const std::string& classpath) {
system_server_classpath_ = classpath;
diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc
index 8acaf2266f..aa5b72f38c 100644
--- a/odrefresh/odrefresh.cc
+++ b/odrefresh/odrefresh.cc
@@ -1011,6 +1011,20 @@ class OnDeviceRefresh final {
return Concatenate({staging_dir, "/", android::base::Basename(path)});
}
+ std::string JoinFilesAsFDs(const std::vector<std::unique_ptr<File>>& files, char delimiter) const {
+ std::stringstream output;
+ bool is_first = true;
+ for (const auto& f : files) {
+ output << std::to_string(f->Fd());
+ if (is_first) {
+ is_first = false;
+ } else {
+ output << delimiter;
+ }
+ }
+ return output.str();
+ }
+
WARN_UNUSED bool CompileBootExtensionArtifacts(const InstructionSet isa,
const std::string& staging_dir,
OdrMetrics& metrics,
@@ -1100,6 +1114,17 @@ class OnDeviceRefresh final {
return false;
}
+ if (config_.UseCompilationOs()) {
+ std::vector<std::string> prefix_args = {
+ "/apex/com.android.compos/bin/pvm_exec",
+ "--cid=" + config_.GetCompilationOsAddress(),
+ "--in-fd=" + JoinFilesAsFDs(readonly_files_raii, ','),
+ "--out-fd=" + JoinFilesAsFDs(staging_files, ','),
+ "--",
+ };
+ args.insert(args.begin(), prefix_args.begin(), prefix_args.end());
+ }
+
const time_t timeout = GetSubprocessTimeout();
const std::string cmd_line = android::base::Join(args, ' ');
LOG(INFO) << "Compiling boot extensions (" << isa << "): " << cmd_line
@@ -1234,6 +1259,17 @@ class OnDeviceRefresh final {
const std::string extension_image = GetBootImageExtensionImage(/*on_system=*/false);
args.emplace_back(Concatenate({"--boot-image=", GetBootImage(), ":", extension_image}));
+ if (config_.UseCompilationOs()) {
+ std::vector<std::string> prefix_args = {
+ "/apex/com.android.compos/bin/pvm_exec",
+ "--cid=" + config_.GetCompilationOsAddress(),
+ "--in-fd=" + JoinFilesAsFDs(readonly_files_raii, ','),
+ "--out-fd=" + JoinFilesAsFDs(staging_files, ','),
+ "--",
+ };
+ args.insert(args.begin(), prefix_args.begin(), prefix_args.end());
+ }
+
const time_t timeout = GetSubprocessTimeout();
const std::string cmd_line = android::base::Join(args, ' ');
LOG(INFO) << "Compiling " << jar << ": " << cmd_line << " [timeout " << timeout << "s]";
@@ -1470,8 +1506,12 @@ class OnDeviceRefresh final {
int n = 1;
for (; n < argc - 1; ++n) {
- if (!InitializeCommonConfig(argv[n], config)) {
- UsageError("Unrecognized argument: '%s'", argv[n]);
+ const char* arg = argv[n];
+ std::string value;
+ if (ArgumentMatches(arg, "--use-compilation-os=", &value)) {
+ config->SetCompilationOsAddress(value);
+ } else if (!InitializeCommonConfig(arg, config)) {
+ UsageError("Unrecognized argument: '%s'", arg);
}
}
return n;