diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp index 355b7a1f1..70399942e 100644 --- a/fs_mgr/liblp/Android.bp +++ b/fs_mgr/liblp/Android.bp @@ -43,6 +43,11 @@ cc_library { windows: { enabled: true, }, + android: { + shared_libs: [ + "libcutils", + ], + }, }, export_include_dirs: ["include"], } diff --git a/fs_mgr/liblp/images.cpp b/fs_mgr/liblp/images.cpp index 5a498f975..56b535353 100644 --- a/fs_mgr/liblp/images.cpp +++ b/fs_mgr/liblp/images.cpp @@ -68,7 +68,7 @@ std::unique_ptr ReadFromImageBlob(const void* data, size_t bytes) { } std::unique_ptr ReadFromImageFile(const std::string& image_file) { - unique_fd fd(open(image_file.c_str(), O_RDONLY | O_CLOEXEC)); + unique_fd fd = GetControlFileOrOpen(image_file.c_str(), O_RDONLY | O_CLOEXEC); if (fd < 0) { PERROR << __PRETTY_FUNCTION__ << " open failed: " << image_file; return nullptr; @@ -408,7 +408,7 @@ bool SparseBuilder::CheckExtentOrdering() { } int SparseBuilder::OpenImageFile(const std::string& file) { - android::base::unique_fd source_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC)); + android::base::unique_fd source_fd = GetControlFileOrOpen(file.c_str(), O_RDONLY | O_CLOEXEC); if (source_fd < 0) { PERROR << "open image file failed: " << file; return -1; diff --git a/fs_mgr/liblp/partition_opener.cpp b/fs_mgr/liblp/partition_opener.cpp index 898f24127..bb8ec9cb8 100644 --- a/fs_mgr/liblp/partition_opener.cpp +++ b/fs_mgr/liblp/partition_opener.cpp @@ -45,7 +45,7 @@ std::string GetPartitionAbsolutePath(const std::string& path) { bool GetBlockDeviceInfo(const std::string& block_device, BlockDeviceInfo* device_info) { #if defined(__linux__) - unique_fd fd(open(block_device.c_str(), O_RDONLY)); + unique_fd fd = GetControlFileOrOpen(block_device.c_str(), O_RDONLY); if (fd < 0) { PERROR << __PRETTY_FUNCTION__ << "open '" << block_device << "' failed"; return false; @@ -85,7 +85,7 @@ bool GetBlockDeviceInfo(const std::string& block_device, BlockDeviceInfo* device unique_fd PartitionOpener::Open(const std::string& partition_name, int flags) const { std::string path = GetPartitionAbsolutePath(partition_name); - return unique_fd{open(path.c_str(), flags | O_CLOEXEC)}; + return GetControlFileOrOpen(path.c_str(), flags | O_CLOEXEC); } bool PartitionOpener::GetInfo(const std::string& partition_name, BlockDeviceInfo* info) const { diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp index ecf94a4c7..72a3c57ca 100644 --- a/fs_mgr/liblp/utility.cpp +++ b/fs_mgr/liblp/utility.cpp @@ -28,6 +28,10 @@ #include #include +#ifdef __ANDROID__ +#include +#endif + #include "utility.h" namespace android { @@ -171,5 +175,19 @@ bool SetBlockReadonly(int fd, bool readonly) { #endif } +base::unique_fd GetControlFileOrOpen(const char* path, int flags) { +#if defined(__ANDROID__) + int fd = android_get_control_file(path); + if (fd >= 0) { + int newfd = TEMP_FAILURE_RETRY(dup(fd)); + if (newfd >= 0) { + return base::unique_fd(newfd); + } + PERROR << "Cannot dup fd for already controlled file: " << path << ", reopening..."; + } +#endif + return base::unique_fd(open(path, flags)); +} + } // namespace fs_mgr } // namespace android diff --git a/fs_mgr/liblp/utility.h b/fs_mgr/liblp/utility.h index e8b2ca970..96f17174a 100644 --- a/fs_mgr/liblp/utility.h +++ b/fs_mgr/liblp/utility.h @@ -22,6 +22,7 @@ #include #include +#include #include "liblp/liblp.h" @@ -92,6 +93,8 @@ bool UpdatePartitionGroupName(LpMetadataPartitionGroup* group, const std::string // Call BLKROSET ioctl on fd so that fd is readonly / read-writable. bool SetBlockReadonly(int fd, bool readonly); +::android::base::unique_fd GetControlFileOrOpen(const char* path, int flags); + } // namespace fs_mgr } // namespace android