odrefresh: Check build-time userfaultfd GC flag.
This is a safety net to fix artifacts if build-time right userfaultfd GC
flag doesn't match the runtime one.
Bug: 242553398
Test: -
1. Build a system image with `m`.
2. Flash to a device.
3. See odrefresh not compiling anything on the first boot.
Test: -
1. Build a system image with `OVERRIDE_ENABLE_UFFD_GC=true m`
2. Flash to a device.
3. See odrefresh compiling everything on the first boot (because
aosp/2308662 has not landed yet).
Change-Id: If8cddabc8beac588ca1e75d01ee3846a2bbf56c8
diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc
index aec9636..1ac65e6 100644
--- a/odrefresh/odrefresh.cc
+++ b/odrefresh/odrefresh.cc
@@ -56,6 +56,7 @@
#include "android-base/file.h"
#include "android-base/logging.h"
#include "android-base/macros.h"
+#include "android-base/parsebool.h"
#include "android-base/parseint.h"
#include "android-base/properties.h"
#include "android-base/result.h"
@@ -76,6 +77,7 @@
#include "dex/art_dex_file_loader.h"
#include "dexoptanalyzer.h"
#include "exec_utils.h"
+#include "fmt/format.h"
#include "log/log.h"
#include "odr_artifacts.h"
#include "odr_common.h"
@@ -86,16 +88,21 @@
#include "odrefresh/odrefresh.h"
#include "palette/palette.h"
#include "palette/palette_types.h"
+#include "read_barrier_config.h"
namespace art {
namespace odrefresh {
+namespace {
+
namespace apex = com::android::apex;
namespace art_apex = com::android::art;
-using android::base::Result;
+using ::android::base::ParseBool;
+using ::android::base::ParseBoolResult;
+using ::android::base::Result;
-namespace {
+using ::fmt::literals::operator""_format; // NOLINT
// Name of cache info file in the ART Apex artifact cache.
constexpr const char* kCacheInfoFile = "cache-info.xml";
@@ -905,17 +912,35 @@
return true;
}
+WARN_UNUSED bool OnDeviceRefresh::CheckBuildUserfaultFdGc() const {
+ auto it = config_.GetSystemProperties().find("ro.dalvik.vm.enable_uffd_gc");
+ bool build_enable_uffd_gc = it != config_.GetSystemProperties().end() ?
+ ParseBool(it->second) == ParseBoolResult::kTrue :
+ false;
+ if (build_enable_uffd_gc != gUseUserfaultfd) {
+ // Normally, this should not happen. If this happens, the system image was probably built with a
+ // wrong PRODUCT_ENABLE_UFFD_GC flag.
+ LOG(WARNING) << "Userfaultfd GC check failed (build-time: {}, runtime: {})."_format(
+ build_enable_uffd_gc, gUseUserfaultfd);
+ return false;
+ }
+ return true;
+}
+
WARN_UNUSED bool OnDeviceRefresh::BootClasspathArtifactsOnSystemUsable(
const apex::ApexInfo& art_apex_info) const {
if (!art_apex_info.getIsFactory()) {
+ LOG(INFO) << "Updated ART APEX mounted";
return false;
}
- LOG(INFO) << "Factory ART APEX mounted.";
if (!CheckSystemPropertiesAreDefault()) {
return false;
}
- LOG(INFO) << "System properties are set to default values.";
+
+ if (!CheckBuildUserfaultFdGc()) {
+ return false;
+ }
return true;
}
@@ -925,14 +950,17 @@
if (std::any_of(apex_info_list.begin(),
apex_info_list.end(),
[](const apex::ApexInfo& apex_info) { return !apex_info.getIsFactory(); })) {
+ LOG(INFO) << "Updated APEXes mounted";
return false;
}
- LOG(INFO) << "Factory APEXes mounted.";
if (!CheckSystemPropertiesAreDefault()) {
return false;
}
- LOG(INFO) << "System properties are set to default values.";
+
+ if (!CheckBuildUserfaultFdGc()) {
+ return false;
+ }
return true;
}
diff --git a/odrefresh/odrefresh.h b/odrefresh/odrefresh.h
index b14aa41..ff3d660 100644
--- a/odrefresh/odrefresh.h
+++ b/odrefresh/odrefresh.h
@@ -150,6 +150,9 @@
WARN_UNUSED bool CheckSystemPropertiesHaveNotChanged(
const com::android::art::CacheInfo& cache_info) const;
+ // Returns true if the system image is built with the right userfaultfd GC flag.
+ WARN_UNUSED bool CheckBuildUserfaultFdGc() const;
+
// Returns true if boot classpath artifacts on /system are usable if they exist. Note that this
// function does not check file existence.
WARN_UNUSED bool BootClasspathArtifactsOnSystemUsable(