diff options
Diffstat (limited to 'cmds/installd/otapreopt.cpp')
-rw-r--r-- | cmds/installd/otapreopt.cpp | 149 |
1 files changed, 70 insertions, 79 deletions
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp index 6aa32b8d8e..18f8268bf3 100644 --- a/cmds/installd/otapreopt.cpp +++ b/cmds/installd/otapreopt.cpp @@ -26,18 +26,18 @@ #include <sys/capability.h> #include <sys/prctl.h> #include <sys/stat.h> -#include <sys/mman.h> #include <android-base/logging.h> #include <android-base/macros.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include <art_image_values.h> #include <cutils/fs.h> #include <cutils/properties.h> +#include <dex2oat_return_codes.h> #include <log/log.h> #include <private/android_filesystem_config.h> -#include "android-base/file.h" #include "dexopt.h" #include "file_parsing.h" #include "globals.h" @@ -96,7 +96,7 @@ static constexpr bool IsPowerOfTwo(T x) { template<typename T> static constexpr T RoundDown(T x, typename std::decay<T>::type n) { - return (x & -n); + return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n); } template<typename T> @@ -177,10 +177,8 @@ class OTAPreoptService { private: bool ReadSystemProperties() { - // TODO This file does not have a stable format. It should be read by - // code shared by init and otapreopt. See b/181182967#comment80 static constexpr const char* kPropertyFiles[] = { - "/system/build.prop" + "/default.prop", "/system/build.prop" }; for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) { @@ -197,61 +195,26 @@ private: // export NAME VALUE // For simplicity, don't respect string quotation. The values we are interested in can be // encoded without them. - // - // init.environ.rc and derive_classpath all have the same format for - // environment variable exports (since they are all meant to be read by - // init) and can be matched by the same regex. - std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)"); - auto parse_results = [&](auto& input) { - ParseFile(input, [&](const std::string& line) { - std::smatch export_match; - if (!std::regex_match(line, export_match, export_regex)) { - return true; - } - - if (export_match.size() != 3) { - return true; - } + bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) { + std::smatch export_match; + if (!std::regex_match(line, export_match, export_regex)) { + return true; + } - std::string name = export_match[1].str(); - std::string value = export_match[2].str(); + if (export_match.size() != 3) { + return true; + } - system_properties_.SetProperty(name, value); + std::string name = export_match[1].str(); + std::string value = export_match[2].str(); - return true; - }); - }; + system_properties_.SetProperty(name, value); - // TODO Just like with the system-properties above we really should have - // common code between init and otapreopt to deal with reading these - // things. See b/181182967 - // There have been a variety of places the various env-vars have been - // over the years. Expand or reduce this list as needed. - static constexpr const char* kEnvironmentVariableSources[] = { - "/init.environ.rc", - }; - // First get everything from the static files. - for (const char* env_vars_file : kEnvironmentVariableSources) { - parse_results(env_vars_file); - } - - // Next get everything from derive_classpath, since we're already in the - // chroot it will get the new versions of any dependencies. - { - android::base::unique_fd fd(memfd_create("derive_classpath_temp", MFD_CLOEXEC)); - if (!fd.ok()) { - LOG(ERROR) << "Unable to create fd for derive_classpath"; - return false; - } - std::string memfd_file = StringPrintf("/proc/%d/fd/%d", getpid(), fd.get()); - std::string error_msg; - if (!Exec({"/apex/com.android.sdkext/bin/derive_classpath", memfd_file}, &error_msg)) { - PLOG(ERROR) << "Running derive_classpath failed: " << error_msg; + return true; + }); + if (!parse_result) { return false; - } - std::ifstream ifs(memfd_file); - parse_results(ifs); } if (system_properties_.GetProperty(kAndroidDataPathPropertyName) == nullptr) { @@ -376,6 +339,9 @@ private: } } + // Clear cached artifacts. + ClearDirectory(isa_path); + // Check whether we have a boot image. // TODO: check that the files are correct wrt/ jars. std::string preopted_boot_art_path = @@ -419,6 +385,37 @@ private: return false; } + static void ClearDirectory(const std::string& dir) { + DIR* c_dir = opendir(dir.c_str()); + if (c_dir == nullptr) { + PLOG(WARNING) << "Unable to open " << dir << " to delete it's contents"; + return; + } + + for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) { + const char* name = de->d_name; + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + continue; + } + // We only want to delete regular files and symbolic links. + std::string file = StringPrintf("%s/%s", dir.c_str(), name); + if (de->d_type != DT_REG && de->d_type != DT_LNK) { + LOG(WARNING) << "Unexpected file " + << file + << " of type " + << std::hex + << de->d_type + << " encountered."; + } else { + // Try to unlink the file. + if (unlink(file.c_str()) != 0) { + PLOG(ERROR) << "Unable to unlink " << file; + } + } + } + CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory."; + } + static const char* ParseNull(const char* arg) { return (strcmp(arg, "!") == 0) ? nullptr : arg; } @@ -478,29 +475,24 @@ private: // Run dexopt with the parameters of parameters_. // TODO(calin): embed the profile name in the parameters. int Dexopt() { - std::string error; - int res = dexopt(parameters_.apk_path, - parameters_.uid, - parameters_.pkgName, - parameters_.instruction_set, - parameters_.dexopt_needed, - parameters_.oat_dir, - parameters_.dexopt_flags, - parameters_.compiler_filter, - parameters_.volume_uuid, - parameters_.shared_libraries, - parameters_.se_info, - parameters_.downgrade, - parameters_.target_sdk_version, - parameters_.profile_name, - parameters_.dex_metadata_path, - parameters_.compilation_reason, - &error); - if (res != 0) { - LOG(ERROR) << "During preopt of " << parameters_.apk_path << " got result " << res - << " error: " << error; - } - return res; + std::string dummy; + return dexopt(parameters_.apk_path, + parameters_.uid, + parameters_.pkgName, + parameters_.instruction_set, + parameters_.dexopt_needed, + parameters_.oat_dir, + parameters_.dexopt_flags, + parameters_.compiler_filter, + parameters_.volume_uuid, + parameters_.shared_libraries, + parameters_.se_info, + parameters_.downgrade, + parameters_.target_sdk_version, + parameters_.profile_name, + parameters_.dex_metadata_path, + parameters_.compilation_reason, + &dummy); } int RunPreopt() { @@ -531,7 +523,6 @@ private: // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc. static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) { constexpr size_t kPageSize = PAGE_SIZE; - static_assert(IsPowerOfTwo(kPageSize), "page size must be power of two"); CHECK_EQ(min_delta % kPageSize, 0u); CHECK_EQ(max_delta % kPageSize, 0u); CHECK_LT(min_delta, max_delta); |