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: Konstantin Vyshetsky <vkon@google.com> Change-Id: I9adb0e7696bc6af74e14dd61a6cb0ef10b4c98c8
This commit is contained in:
parent
b3e1829421
commit
1cee2ed239
2 changed files with 44 additions and 9 deletions
|
@ -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) {
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue