summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apexd/apexd_loop.cpp14
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;