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

Commit acda4251 authored by Tom Cherry's avatar Tom Cherry Committed by Automerger Merge Worker
Browse files

Merge "Ueventd: Fix a corner case in ReadUevent() that triggers duplicate...

Merge "Ueventd: Fix a corner case in ReadUevent() that triggers duplicate firmware loading." am: e1227011 am: 578bfe94

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1366617

Change-Id: Ib5c868d1da20fdcb8b0b0642eba7c707abb1ea1e
parents 5c9dbc71 578bfe94
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -95,20 +95,18 @@ UeventListener::UeventListener(size_t uevent_socket_rcvbuf_size) {
    fcntl(device_fd_, F_SETFL, O_NONBLOCK);
}

bool UeventListener::ReadUevent(Uevent* uevent) const {
ReadUeventResult UeventListener::ReadUevent(Uevent* uevent) const {
    char msg[UEVENT_MSG_LEN + 2];
    int n = uevent_kernel_multicast_recv(device_fd_, msg, UEVENT_MSG_LEN);
    if (n <= 0) {
        if (errno != EAGAIN && errno != EWOULDBLOCK) {
            PLOG(ERROR) << "Error reading from Uevent Fd";
        }
        return false;
        return ReadUeventResult::kFailed;
    }
    if (n >= UEVENT_MSG_LEN) {
        LOG(ERROR) << "Uevent overflowed buffer, discarding";
        // Return true here even if we discard as we may have more uevents pending and we
        // want to keep processing them.
        return true;
        return ReadUeventResult::kInvalid;
    }

    msg[n] = '\0';
@@ -116,7 +114,7 @@ bool UeventListener::ReadUevent(Uevent* uevent) const {

    ParseEvent(msg, uevent);

    return true;
    return ReadUeventResult::kSuccess;
}

// RegenerateUevents*() walks parts of the /sys tree and pokes the uevent files to cause the kernel
@@ -137,7 +135,10 @@ ListenerAction UeventListener::RegenerateUeventsForDir(DIR* d,
        close(fd);

        Uevent uevent;
        while (ReadUevent(&uevent)) {
        ReadUeventResult result;
        while ((result = ReadUevent(&uevent)) != ReadUeventResult::kFailed) {
            // Skip processing the uevent if it is invalid.
            if (result == ReadUeventResult::kInvalid) continue;
            if (callback(uevent) == ListenerAction::kStop) return ListenerAction::kStop;
        }
    }
@@ -212,7 +213,10 @@ void UeventListener::Poll(const ListenerCallback& callback,
            // We're non-blocking, so if we receive a poll event keep processing until
            // we have exhausted all uevent messages.
            Uevent uevent;
            while (ReadUevent(&uevent)) {
            ReadUeventResult result;
            while ((result = ReadUevent(&uevent)) != ReadUeventResult::kFailed) {
                // Skip processing the uevent if it is invalid.
                if (result == ReadUeventResult::kInvalid) continue;
                if (callback(uevent) == ListenerAction::kStop) return;
            }
        }
+7 −1
Original line number Diff line number Diff line
@@ -37,6 +37,12 @@ enum class ListenerAction {
    kContinue,  // Continue regenerating uevents as we haven't seen the one(s) we're interested in.
};

enum class ReadUeventResult {
    kSuccess = 0,  // Uevent was successfully read.
    kFailed,       // Uevent reading has failed.
    kInvalid,      // An Invalid Uevent was read (like say, the msg received is >= UEVENT_MSG_LEN).
};

using ListenerCallback = std::function<ListenerAction(const Uevent&)>;

class UeventListener {
@@ -50,7 +56,7 @@ class UeventListener {
              const std::optional<std::chrono::milliseconds> relative_timeout = {}) const;

  private:
    bool ReadUevent(Uevent* uevent) const;
    ReadUeventResult ReadUevent(Uevent* uevent) const;
    ListenerAction RegenerateUeventsForDir(DIR* d, const ListenerCallback& callback) const;

    android::base::unique_fd device_fd_;