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

Commit 1cee2ed2 authored by Konstantin Vyshetsky's avatar Konstantin Vyshetsky
Browse files

fastbootd: add support to reset fd by handle



There are cases where the flags the file descriptor was opened with need
to be modified. This CL adds functionality to reset the file descriptor
held by a PartitionHandle, reopening with new flags and repositioning
file offset to previous.

Bug: 225108941
Signed-off-by: default avatarKonstantin Vyshetsky <vkon@google.com>
Change-Id: I9adb0e7696bc6af74e14dd61a6cb0ef10b4c98c8
parent b3e18294
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -90,14 +90,7 @@ bool OpenPartition(FastbootDevice* device, const std::string& name, PartitionHan
        return false;
    }

    flags |= (O_EXCL | O_CLOEXEC | O_BINARY);
    unique_fd fd(TEMP_FAILURE_RETRY(open(handle->path().c_str(), flags)));
    if (fd < 0) {
        PLOG(ERROR) << "Failed to open block device: " << handle->path();
        return false;
    }
    handle->set_fd(std::move(fd));
    return true;
    return handle->Open(flags);
}

std::optional<std::string> FindPhysicalPartition(const std::string& name) {
+43 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
#include <optional>
#include <string>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <android/hardware/boot/1.0/IBootControl.h>
#include <fstab/fstab.h>
@@ -44,11 +46,51 @@ class PartitionHandle {
    }
    const std::string& path() const { return path_; }
    int fd() const { return fd_.get(); }
    void set_fd(android::base::unique_fd&& fd) { fd_ = std::move(fd); }
    bool Open(int flags) {
        flags |= (O_EXCL | O_CLOEXEC | O_BINARY);

        // Attempts to open a second device can fail with EBUSY if the device is already open.
        // Explicitly close any previously opened devices as unique_fd won't close them until
        // after the attempt to open.
        fd_.reset();

        fd_ = android::base::unique_fd(TEMP_FAILURE_RETRY(open(path_.c_str(), flags)));
        if (fd_ < 0) {
            PLOG(ERROR) << "Failed to open block device: " << path_;
            return false;
        }
        flags_ = flags;

        return true;
    }
    bool Reset(int flags) {
        if (fd_.ok() && (flags | O_EXCL | O_CLOEXEC | O_BINARY) == flags_) {
            return true;
        }

        off_t offset = fd_.ok() ? lseek(fd_.get(), 0, SEEK_CUR) : 0;
        if (offset < 0) {
            PLOG(ERROR) << "Failed lseek on block device: " << path_;
            return false;
        }

        sync();

        if (Open(flags) == false) {
            return false;
        }

        if (lseek(fd_.get(), offset, SEEK_SET) != offset) {
            PLOG(ERROR) << "Failed lseek on block device: " << path_;
            return false;
        }

        return true;
    }
  private:
    std::string path_;
    android::base::unique_fd fd_;
    int flags_;
    std::function<void()> closer_;
};