From a212760ec69c7daabacdc9da37ba71b3558e6361 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 15 May 2020 06:14:31 +0000 Subject: [PATCH] libdm: Fallback to legacy ueventd logic if running on an older system. When delivering single-stage, non-AB OTAs, the updater binary is built on a newer OS than recovery is compiled with. libdm relies on newer ueventd behavior which therefore breaks this model. As a workaround, we allow libdm to fallback to the old ueventd logic if the following conditions hold true: (1) we're in recovery, (2) the device is not an AB device, and (3) the release is <= 10. Since the old ueventd behavior can lead to races in libdm, this fallback should stay as narrow as possible. Bug: 156536673 Bug: 155202260 Test: manual test Change-Id: I7f9da49e4ba8dfe165e0923d9918827d51d090cd --- fs_mgr/libdm/dm.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp index 673e145f1..791268849 100644 --- a/fs_mgr/libdm/dm.cpp +++ b/fs_mgr/libdm/dm.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -140,6 +141,10 @@ static std::string GenerateUuid() { return std::string{uuid_chars}; } +static bool IsRecovery() { + return access("/system/bin/recovery", F_OK) == 0; +} + bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table, std::string* path, const std::chrono::milliseconds& timeout_ms) { std::string uuid = GenerateUuid(); @@ -160,6 +165,16 @@ bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table, s if (timeout_ms <= std::chrono::milliseconds::zero()) { return true; } + + if (IsRecovery()) { + bool non_ab_device = android::base::GetProperty("ro.build.ab_update", "").empty(); + int sdk = android::base::GetIntProperty("ro.build.version.sdk", 0); + if (non_ab_device && sdk && sdk <= 29) { + LOG(INFO) << "Detected ueventd incompatibility, reverting to legacy libdm behavior."; + unique_path = *path; + } + } + if (!WaitForFile(unique_path, timeout_ms)) { LOG(ERROR) << "Failed waiting for device path: " << unique_path; DeleteDevice(name);