Merge "ART: Remove zygote OTA code"
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 8d406b3..6fcad29 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -384,30 +384,7 @@
&has_system, &cache_filename, &dalvik_cache_exists,
&has_cache, &is_global_cache);
- // If we're starting with the global cache, and we're the zygote, try to see whether there are
- // OTA artifacts from the A/B OTA preopting to move over.
- // (It is structurally simpler to check this here, instead of complicating the compile/relocate
- // logic below.)
const bool is_zygote = Runtime::Current()->IsZygote();
- if (is_global_cache && is_zygote) {
- VLOG(startup) << "Checking for A/B OTA data.";
- TryMoveOTAArtifacts(cache_filename, dalvik_cache_exists);
-
- // Retry. There are two cases where the old info is outdated:
- // * There wasn't a boot image before (e.g., some failure on boot), but now the OTA preopted
- // image has been moved in-place.
- // * There was a boot image before, and we tried to move the OTA preopted image, but a failure
- // happened and there is no file anymore.
- found_image = FindImageFilename(image_location,
- image_isa,
- &system_filename,
- &has_system,
- &cache_filename,
- &dalvik_cache_exists,
- &has_cache,
- &is_global_cache);
- }
-
if (is_zygote && !secondary_image) {
MarkZygoteStart(image_isa, Runtime::Current()->GetZygoteMaxFailedBoots());
}
diff --git a/runtime/gc/space/image_space_fs.h b/runtime/gc/space/image_space_fs.h
index 4d539d2..fc9a3cf 100644
--- a/runtime/gc/space/image_space_fs.h
+++ b/runtime/gc/space/image_space_fs.h
@@ -79,115 +79,6 @@
CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
}
-static bool HasContent(const char* dir) {
- if (!OS::DirectoryExists(dir)) {
- return false;
- }
- DIR* c_dir = opendir(dir);
- if (c_dir == nullptr) {
- PLOG(WARNING) << "Unable to open " << dir << " to delete it if empty";
- return false;
- }
-
- 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;
- }
- // Something here.
- CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
- return true;
- }
- CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
- return false;
-}
-
-// Delete this directory, if empty. Then repeat with the parents. Skips non-existing directories.
-// If stop_at isn't null, the recursion will stop when a directory with the given name is found.
-static void DeleteEmptyDirectoriesUpTo(const std::string& dir, const char* stop_at) {
- if (HasContent(dir.c_str())) {
- return;
- }
- if (stop_at != nullptr) {
- // This check isn't precise, but good enough in practice.
- if (EndsWith(dir, stop_at)) {
- return;
- }
- }
- if (OS::DirectoryExists(dir.c_str())) {
- if (rmdir(dir.c_str()) != 0) {
- PLOG(ERROR) << "Unable to rmdir " << dir;
- return;
- }
- }
- size_t last_slash = dir.rfind('/');
- if (last_slash != std::string::npos) {
- DeleteEmptyDirectoriesUpTo(dir.substr(0, last_slash), stop_at);
- }
-}
-
-static void MoveOTAArtifacts(const char* src, const char* trg) {
- DCHECK(OS::DirectoryExists(src));
- DCHECK(OS::DirectoryExists(trg));
-
- if (HasContent(trg)) {
- LOG(WARNING) << "We do not support merging caches, but the target isn't empty: " << src
- << " to " << trg;
- return;
- }
-
- if (rename(src, trg) != 0) {
- PLOG(ERROR) << "Could not rename OTA cache " << src << " to target " << trg;
- }
-}
-
-// This is some dlopen/dlsym and hardcoded data to avoid a dependency on libselinux. Make sure
-// this stays in sync!
-static bool RelabelOTAFiles(const std::string& dalvik_cache_dir) {
- // We only expect selinux on devices. Don't even attempt this on the host.
- if (!kIsTargetBuild) {
- return true;
- }
-
- // Custom deleter, so we can use std::unique_ptr.
- struct HandleDeleter {
- void operator()(void* in) {
- if (in != nullptr && dlclose(in) != 0) {
- PLOG(ERROR) << "Could not close selinux handle.";
- }
- }
- };
-
- // Look for selinux library.
- std::unique_ptr<void, HandleDeleter> selinux_handle(dlopen("libselinux.so", RTLD_NOW));
- if (selinux_handle == nullptr) {
- // Assume everything's OK if we can't open the library.
- return true;
- }
- dlerror(); // Clean dlerror string.
-
- void* restorecon_ptr = dlsym(selinux_handle.get(), "selinux_android_restorecon");
- if (restorecon_ptr == nullptr) {
- // Can't find the relabel function. That's bad. Make sure the zygote fails, as we have no
- // other recourse to make this error obvious.
- const char* error_string = dlerror();
- LOG(FATAL) << "Could not find selinux restorecon function: "
- << ((error_string != nullptr) ? error_string : "(unknown error)");
- UNREACHABLE();
- }
-
- using RestoreconFn = int (*)(const char*, unsigned int);
- constexpr unsigned int kRecursive = 4U;
-
- RestoreconFn restorecon_fn = reinterpret_cast<RestoreconFn>(restorecon_ptr);
- if (restorecon_fn(dalvik_cache_dir.c_str(), kRecursive) != 0) {
- LOG(ERROR) << "Failed to restorecon " << dalvik_cache_dir;
- return false;
- }
-
- return true;
-}
-
} // namespace impl
@@ -272,53 +163,6 @@
}
}
-static void TryMoveOTAArtifacts(const std::string& cache_filename, bool dalvik_cache_exists) {
- // We really assume here global means /data/dalvik-cache, and we'll inject 'ota.' Make sure
- // that's true.
- CHECK(StartsWith(cache_filename, "/data/dalvik-cache")) << cache_filename;
-
- // Inject ota subdirectory.
- std::string ota_filename(cache_filename);
- ota_filename = ota_filename.insert(strlen("/data/"), "ota/");
- CHECK(StartsWith(ota_filename, "/data/ota/dalvik-cache")) << ota_filename;
-
- // See if the file exists.
- if (OS::FileExists(ota_filename.c_str())) {
- VLOG(startup) << "OTA directory does exist, checking for artifacts";
-
- size_t last_slash = ota_filename.rfind('/');
- CHECK_NE(last_slash, std::string::npos);
- std::string ota_source_dir = ota_filename.substr(0, last_slash);
-
- // We need the dalvik cache now, really.
- if (dalvik_cache_exists) {
- size_t last_cache_slash = cache_filename.rfind('/');
- DCHECK_NE(last_cache_slash, std::string::npos);
- std::string dalvik_cache_target_dir = cache_filename.substr(0, last_cache_slash);
-
- // First clean the target cache.
- impl::DeleteDirectoryContents(dalvik_cache_target_dir.c_str(), false);
-
- // Now move things over.
- impl::MoveOTAArtifacts(ota_source_dir.c_str(), dalvik_cache_target_dir.c_str());
-
- // Last step: ensure the files have the right selinux label.
- if (!impl::RelabelOTAFiles(dalvik_cache_target_dir)) {
- // This isn't good. We potentially moved files, but they have the wrong label. Delete the
- // files.
- LOG(WARNING) << "Could not relabel files, must delete dalvik-cache.";
- impl::DeleteDirectoryContents(dalvik_cache_target_dir.c_str(), false);
- }
- }
-
- // Cleanup.
- impl::DeleteDirectoryContents(ota_source_dir.c_str(), true);
- impl::DeleteEmptyDirectoriesUpTo(ota_source_dir, "ota");
- } else {
- VLOG(startup) << "No OTA directory.";
- }
-}
-
} // namespace space
} // namespace gc
} // namespace art