diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-07-20 11:33:46 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-07-20 11:33:46 -0400 |
commit | 59ccde4a2f3285533ebaff034cdbe5ea4b9c233a (patch) | |
tree | f08f544add3f6433d51a379c84deb484ee773583 /src | |
parent | 60ff4f2f3c3da34746f0993d4e6f1de79979f580 (diff) |
mount: Fall back to read-only on -EROFS
this is the mount helper's job, and since we're the mount helper...
fixes: xfstests generic/050
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'src')
-rw-r--r-- | src/commands/mount.rs | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/commands/mount.rs b/src/commands/mount.rs index 20b692bc..0f39214c 100644 --- a/src/commands/mount.rs +++ b/src/commands/mount.rs @@ -23,7 +23,7 @@ fn mount_inner( src: String, target: impl AsRef<std::path::Path>, fstype: &str, - mountflags: libc::c_ulong, + mut mountflags: libc::c_ulong, data: Option<String>, ) -> anyhow::Result<()> { // bind the CStrings to keep them alive @@ -38,11 +38,23 @@ fn mount_inner( let data = data.map_or(ptr::null(), |data| data.as_ptr().cast()); let fstype = fstype.as_ptr(); - let ret = { - info!("mounting filesystem"); - // REQUIRES: CAP_SYS_ADMIN - unsafe { libc::mount(src, target, fstype, mountflags, data) } - }; + let mut ret; + loop { + ret = { + info!("mounting filesystem"); + // REQUIRES: CAP_SYS_ADMIN + unsafe { libc::mount(src, target, fstype, mountflags, data) } + }; + + let err = errno::errno().0; + + if ret == 0 || (err != libc::EACCES && err != libc::EROFS) || (mountflags & libc::MS_RDONLY) != 0 { + break; + } + + println!("mount: device write-protected, mounting read-only"); + mountflags |= libc::MS_RDONLY; + } match ret { 0 => Ok(()), _ => Err(crate::ErrnoError(errno::errno()).into()), |