diff options
| author | 2021-06-14 12:48:10 -0700 | |
|---|---|---|
| committer | 2021-06-16 16:52:52 +0000 | |
| commit | b3a4e01448a32b2dc53cad8a981ed7c75d12d2cc (patch) | |
| tree | 6bf28066ed85e965d1bc141abcdac5c3a5a72a7f | |
| parent | 0be3da60fa382ded4a3f9b714d9da4e22667e15a (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.h | 4 | ||||
| -rw-r--r-- | odrefresh/odrefresh.cc | 44 |
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; |