diff options
author | 2021-10-13 11:07:25 +0100 | |
---|---|---|
committer | 2021-10-15 15:03:44 +0000 | |
commit | d4d21bf191f2afcd4d6479d60a4d3ab7a19af839 (patch) | |
tree | 904e32af33a858babf5b05bfee05683e5866069c | |
parent | 740e1f972ab1401d0afa98f365d9f5fe70a8a895 (diff) |
Allow odrefresh to write elsewhere than dalvik-cache
For CompOS we want to be able to generate artifacts in different
subdirectories, e.g. /data/misc/apexdata/com.android.art/pending
rather than /data/misc/apexdata/com.android.art/dalvik-cache.
Add a command line flag to enable this.
Bug: 200020887
Test: atest art_standalone_libartbase_tests
Test: manual: odrefresh --dalvik-cache=foo --force-compile
Change-Id: Id10c9bcc8cb9f810c48727abc1858f5b16b360d2
-rw-r--r-- | libartbase/base/file_utils.cc | 11 | ||||
-rw-r--r-- | libartbase/base/file_utils.h | 4 | ||||
-rw-r--r-- | libartbase/base/file_utils_test.cc | 42 | ||||
-rw-r--r-- | odrefresh/include/odrefresh/odrefresh.h | 2 | ||||
-rw-r--r-- | odrefresh/odr_config.h | 11 | ||||
-rw-r--r-- | odrefresh/odrefresh.cc | 6 | ||||
-rw-r--r-- | odrefresh/odrefresh_main.cc | 76 |
7 files changed, 126 insertions, 26 deletions
diff --git a/libartbase/base/file_utils.cc b/libartbase/base/file_utils.cc index 0780fe021c..0cbc77b6c5 100644 --- a/libartbase/base/file_utils.cc +++ b/libartbase/base/file_utils.cc @@ -370,11 +370,18 @@ std::string GetBootImagePath(bool on_system, const std::string& jar_path) { } } +static /*constinit*/ std::string_view dalvik_cache_sub_dir = "dalvik-cache"; + +void OverrideDalvikCacheSubDirectory(std::string sub_dir) { + static std::string overridden_dalvik_cache_sub_dir; + overridden_dalvik_cache_sub_dir = std::move(sub_dir); + dalvik_cache_sub_dir = overridden_dalvik_cache_sub_dir; +} + static std::string GetDalvikCacheDirectory(std::string_view root_directory, std::string_view sub_directory = {}) { - static constexpr std::string_view kDalvikCache = "dalvik-cache"; std::stringstream oss; - oss << root_directory << '/' << kDalvikCache; + oss << root_directory << '/' << dalvik_cache_sub_dir; if (!sub_directory.empty()) { oss << '/' << sub_directory; } diff --git a/libartbase/base/file_utils.h b/libartbase/base/file_utils.h index 6fc1caab2e..33ea2e9e4a 100644 --- a/libartbase/base/file_utils.h +++ b/libartbase/base/file_utils.h @@ -80,6 +80,10 @@ std::string GetDefaultBootImageLocation(const std::string& android_root, // Returns the boot image path of the provided jar, on /system or /data. std::string GetBootImagePath(bool on_system, const std::string& jar_path); +// Allows the name to be used for the dalvik cache directory (normally "dalvik-cache") to be +// overridden with a new value. +void OverrideDalvikCacheSubDirectory(std::string sub_dir); + // Return true if we found the dalvik cache and stored it in the dalvik_cache argument. // `have_android_data` will be set to true if we have an ANDROID_DATA that exists, // `dalvik_cache_exists` will be true if there is a dalvik-cache directory that is present. diff --git a/libartbase/base/file_utils_test.cc b/libartbase/base/file_utils_test.cc index a0b3325648..7678df40b0 100644 --- a/libartbase/base/file_utils_test.cc +++ b/libartbase/base/file_utils_test.cc @@ -29,6 +29,21 @@ namespace art { static constexpr const char kAndroidWifiApexDefaultPath[] = "/apex/com.android.wifi"; +namespace { +class ScopedOverrideDalvikCacheSubDirectory { + public: + explicit ScopedOverrideDalvikCacheSubDirectory(const char* override) { + OverrideDalvikCacheSubDirectory(override); + } + + ~ScopedOverrideDalvikCacheSubDirectory() { + OverrideDalvikCacheSubDirectory("dalvik-cache"); + } + private: + DISALLOW_COPY_AND_ASSIGN(ScopedOverrideDalvikCacheSubDirectory); +}; +} // namespace + class FileUtilsTest : public CommonArtTest {}; TEST_F(FileUtilsTest, GetDalvikCacheFilename) { @@ -271,6 +286,33 @@ TEST_F(FileUtilsTest, GetApexDataDalvikCacheFilename) { CHECK_EQ(vdex_filename, ReplaceFileExtension(art_filename, "vdex")); } +TEST_F(FileUtilsTest, OverrideDalvikCacheSubDirectory) { + ScopedUnsetEnvironmentVariable android_root("ANDROID_ROOT"); + ScopedUnsetEnvironmentVariable i18n_root("ANDROID_I18N_ROOT"); + ScopedUnsetEnvironmentVariable art_apex_data("ART_APEX_DATA"); + + ScopedOverrideDalvikCacheSubDirectory dalvik_cache("overridden-cache"); + + EXPECT_EQ(GetArtApexData() + "/overridden-cache/arm/boot-beep.oat", + GetApexDataOatFilename("/product/javalib/beep.jar", InstructionSet::kArm)); + + EXPECT_EQ(GetArtApexData() + "/overridden-cache/arm/data@some@code.odex", + GetApexDataOdexFilename("/data/some/code.dex", InstructionSet::kArm)); + + const std::string system_jar = "/system/framework/disk.jar"; + const std::string boot_image = GetApexDataBootImage(system_jar.c_str()); + EXPECT_EQ(GetArtApexData() + "/overridden-cache/boot-disk.art", boot_image); + + EXPECT_EQ( + GetArtApexData() + "/overridden-cache/apex@com.android.wifi@lib@javalib@bar.jar@classes.art", + GetApexDataImage(std::string {kAndroidWifiApexDefaultPath} + "/lib/javalib/bar.jar")); + + const std::string apex_jar = std::string {kAndroidWifiApexDefaultPath} + "/lib/javalib/bar.jar"; + EXPECT_EQ(GetArtApexData() + + "/overridden-cache/x86_64/apex@com.android.wifi@lib@javalib@bar.jar@classes.art", + GetApexDataDalvikCacheFilename(apex_jar, InstructionSet::kX86_64, "art")); +} + TEST_F(FileUtilsTest, GetSystemOdexFilenameForApex) { ScopedUnsetEnvironmentVariable android_root("ANDROID_ROOT"); diff --git a/odrefresh/include/odrefresh/odrefresh.h b/odrefresh/include/odrefresh/odrefresh.h index 1fe23821d8..f1c18ac81c 100644 --- a/odrefresh/include/odrefresh/odrefresh.h +++ b/odrefresh/include/odrefresh/odrefresh.h @@ -22,6 +22,8 @@ namespace art { namespace odrefresh { +// Default directory to which artifacts are written. (Overridable via the --dalvik-cache command +// line argument.) static constexpr const char* kOdrefreshArtifactDirectory = "/data/misc/apexdata/com.android.art/dalvik-cache"; diff --git a/odrefresh/odr_config.h b/odrefresh/odr_config.h index 253bd492a8..402955c98f 100644 --- a/odrefresh/odr_config.h +++ b/odrefresh/odr_config.h @@ -24,6 +24,7 @@ #include "arch/instruction_set.h" #include "base/globals.h" #include "log/log.h" +#include "odrefresh/odrefresh.h" namespace art { namespace odrefresh { @@ -55,6 +56,7 @@ class OdrConfig final { ZygoteKind zygote_kind_; int compilation_os_address_ = 0; std::string boot_classpath_; + std::string artifact_dir_; // Staging directory for artifacts. The directory must exist and will be automatically removed // after compilation. If empty, use the default directory. @@ -64,7 +66,8 @@ class OdrConfig final { explicit OdrConfig(const char* program_name) : dry_run_(false), isa_(InstructionSet::kNone), - program_name_(android::base::Basename(program_name)) { + program_name_(android::base::Basename(program_name)), + artifact_dir_(kOdrefreshArtifactDirectory) { } const std::string& GetApexInfoListFile() const { return apex_info_list_file_; } @@ -96,6 +99,8 @@ class OdrConfig final { const std::string& GetDex2oatBootClasspath() const { return dex2oat_boot_classpath_; } + const std::string& GetArtifactDirectory() const { return artifact_dir_; } + std::string GetDex2Oat() const { const char* prefix = UseDebugBinaries() ? "dex2oatd" : "dex2oat"; const char* suffix = ""; @@ -136,6 +141,10 @@ class OdrConfig final { dex2oat_boot_classpath_ = classpath; } + void SetArtifactDirectory(const std::string& artifact_dir) { + artifact_dir_ = artifact_dir; + } + void SetDryRun() { dry_run_ = true; } void SetIsa(const InstructionSet isa) { isa_ = isa; } void SetCompilationOsAddress(int address) { compilation_os_address_ = address; } diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc index 4e4c800fdd..be58702660 100644 --- a/odrefresh/odrefresh.cc +++ b/odrefresh/odrefresh.cc @@ -472,7 +472,7 @@ CompilerFilter CompilerFilterStringToAidl(const std::string& compiler_filter) { OnDeviceRefresh::OnDeviceRefresh(const OdrConfig& config) : OnDeviceRefresh(config, - Concatenate({kOdrefreshArtifactDirectory, "/", kCacheInfoFile}), + Concatenate({config.GetArtifactDirectory(), "/", kCacheInfoFile}), std::make_unique<ExecUtils>(), std::move(OdrDexopt::Create(config, std::make_unique<ExecUtils>()))) {} @@ -700,11 +700,11 @@ WARN_UNUSED bool OnDeviceRefresh::RemoveArtifacts(const OdrArtifacts& artifacts) WARN_UNUSED bool OnDeviceRefresh::RemoveArtifactsDirectory() const { if (config_.GetDryRun()) { - LOG(INFO) << "Directory " << QuotePath(kOdrefreshArtifactDirectory) + LOG(INFO) << "Directory " << QuotePath(config_.GetArtifactDirectory()) << " and contents would be removed (dry-run)."; return true; } - return RemoveDirectory(kOdrefreshArtifactDirectory); + return RemoveDirectory(config_.GetArtifactDirectory()); } WARN_UNUSED bool OnDeviceRefresh::BootExtensionArtifactsExist( diff --git a/odrefresh/odrefresh_main.cc b/odrefresh/odrefresh_main.cc index 21352240ea..7359df5ec0 100644 --- a/odrefresh/odrefresh_main.cc +++ b/odrefresh/odrefresh_main.cc @@ -71,25 +71,6 @@ NO_RETURN void ArgumentError(const char* fmt, ...) { exit(EX_USAGE); } -NO_RETURN void UsageHelp(const char* argv0) { - std::string name(android::base::Basename(argv0)); - UsageError("Usage: %s ACTION", name.c_str()); - UsageError("On-device refresh tool for boot class path extensions and system server"); - UsageError("following an update of the ART APEX."); - UsageError(""); - UsageError("Valid ACTION choices are:"); - UsageError(""); - UsageError( - "--check Check compilation artifacts are up-to-date based on metadata (fast)."); - UsageError("--compile Compile boot class path extensions and system_server jars"); - UsageError(" when necessary."); - UsageError("--force-compile Unconditionally compile the boot class path extensions and"); - UsageError(" system_server jars."); - UsageError("--verify Verify artifacts are up-to-date with dexoptanalyzer (slow)."); - UsageError("--help Display this help information."); - exit(EX_USAGE); -} - bool ParseZygoteKind(const char* input, ZygoteKind* zygote_kind) { std::string_view z(input); if (z == "zygote32") { @@ -135,6 +116,10 @@ bool InitializeCommonConfig(std::string_view argument, OdrConfig* config) { return false; } +void CommonOptionsHelp() { + UsageError("--dry-run"); +} + int InitializeHostConfig(int argc, char** argv, OdrConfig* config) { __android_log_set_logger(__android_log_stderr_logger); @@ -181,6 +166,17 @@ int InitializeHostConfig(int argc, char** argv, OdrConfig* config) { return n; } +void HostOptionsHelp() { + UsageError("--android-root"); + UsageError("--android-art-root"); + UsageError("--apex-info-list"); + UsageError("--art-apex-data"); + UsageError("--dex2oat-bootclasspath"); + UsageError("--isa-root"); + UsageError("--system-server-classpath"); + UsageError("--zygote-arch"); +} + int InitializeTargetConfig(int argc, char** argv, OdrConfig* config) { config->SetApexInfoListFile("/apex/apex-info-list.xml"); config->SetArtBinDir(art::GetArtBinDir()); @@ -206,6 +202,10 @@ int InitializeTargetConfig(int argc, char** argv, OdrConfig* config) { ArgumentError("Failed to parse CID: %s", value.c_str()); } config->SetCompilationOsAddress(cid); + } else if (ArgumentMatches(arg, "--dalvik-cache=", &value)) { + art::OverrideDalvikCacheSubDirectory(value); + config->SetArtifactDirectory(Concatenate( + {android::base::Dirname(art::odrefresh::kOdrefreshArtifactDirectory), "/", value})); } else if (!InitializeCommonConfig(arg, config)) { UsageError("Unrecognized argument: '%s'", arg); } @@ -213,6 +213,13 @@ int InitializeTargetConfig(int argc, char** argv, OdrConfig* config) { return n; } +void TargetOptionsHelp() { + UsageError("--use-compilation-os=<CID> Run compilation in the VM with the given CID."); + UsageError(" (0 = do not use VM, -1 = use composd's VM)"); + UsageError( + "--dalvik-cache=<DIR> Write artifacts to .../<DIR> rather than .../dalvik-cache"); +} + int InitializeConfig(int argc, char** argv, OdrConfig* config) { if (art::kIsTargetBuild) { return InitializeTargetConfig(argc, argv, config); @@ -221,6 +228,35 @@ int InitializeConfig(int argc, char** argv, OdrConfig* config) { } } +NO_RETURN void UsageHelp(const char* argv0) { + std::string name(android::base::Basename(argv0)); + UsageError("Usage: %s [OPTION...] ACTION", name.c_str()); + UsageError("On-device refresh tool for boot class path extensions and system server"); + UsageError("following an update of the ART APEX."); + UsageError(""); + UsageError("Valid ACTION choices are:"); + UsageError(""); + UsageError( + "--check Check compilation artifacts are up-to-date based on metadata (fast)."); + UsageError("--compile Compile boot class path extensions and system_server jars"); + UsageError(" when necessary."); + UsageError("--force-compile Unconditionally compile the boot class path extensions and"); + UsageError(" system_server jars."); + UsageError("--verify Verify artifacts are up-to-date with dexoptanalyzer (slow)."); + UsageError("--help Display this help information."); + UsageError(""); + UsageError("Available OPTIONs are:"); + UsageError(""); + CommonOptionsHelp(); + if (art::kIsTargetBuild) { + TargetOptionsHelp(); + } else { + HostOptionsHelp(); + } + + exit(EX_USAGE); +} + } // namespace int main(int argc, char** argv) { @@ -240,7 +276,7 @@ int main(int argc, char** argv) { UsageError("Expected 1 argument, but have %d.", argc); } - OdrMetrics metrics(art::odrefresh::kOdrefreshArtifactDirectory); + OdrMetrics metrics(config.GetArtifactDirectory()); OnDeviceRefresh odr(config); for (int i = 0; i < argc; ++i) { std::string_view action(argv[i]); |