Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2cc8cb2 authored by David Anderson's avatar David Anderson
Browse files

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
parent 6030f2f0
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <uuid/uuid.h>

@@ -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);