diff options
Diffstat (limited to 'apexd/apexd_loop.cpp')
-rw-r--r-- | apexd/apexd_loop.cpp | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/apexd/apexd_loop.cpp b/apexd/apexd_loop.cpp index 5ca096b..d97ab34 100644 --- a/apexd/apexd_loop.cpp +++ b/apexd/apexd_loop.cpp @@ -26,6 +26,7 @@ #include <linux/loop.h> #include <sys/ioctl.h> #include <sys/stat.h> +#include <sys/statfs.h> #include <sys/types.h> #include <unistd.h> @@ -169,7 +170,18 @@ Result<void> configureLoopDevice(const int device_fd, const std::string& target, */ unique_fd target_fd(open(target.c_str(), O_RDONLY | O_CLOEXEC | O_DIRECT)); if (target_fd.get() == -1) { - return ErrnoError() << "Failed to open " << target; + struct statfs stbuf; + int saved_errno = errno; + // let's give another try with buffered I/O for EROFS + if (statfs(target.c_str(), &stbuf) != 0 || + stbuf.f_type != EROFS_SUPER_MAGIC_V1) { + return Error(saved_errno) << "Failed to open " << target; + } + LOG(WARNING) << "Fallback to buffered I/O for " << target; + target_fd.reset(open(target.c_str(), O_RDONLY | O_CLOEXEC)); + if (target_fd.get() == -1) { + return ErrnoError() << "Failed to open " << target; + } } struct loop_info64 li; |