cmd_mount: Change error message on -EBUSY to match util-linux

This causes xfstests generic/741 to pass

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2024-10-12 14:02:51 -04:00
parent 3666da87f2
commit b1e6d1ced2
2 changed files with 25 additions and 12 deletions

View File

@ -109,7 +109,7 @@ fn main() -> ExitCode {
ExitCode::SUCCESS ExitCode::SUCCESS
} }
"list" => commands::list(args[1..].to_vec()).report(), "list" => commands::list(args[1..].to_vec()).report(),
"mount" => commands::mount(args, symlink_cmd).report(), "mount" => commands::mount(args, symlink_cmd),
"subvolume" => commands::subvolume(args[1..].to_vec()).report(), "subvolume" => commands::subvolume(args[1..].to_vec()).report(),
_ => { _ => {
let r = handle_c_command(args, symlink_cmd); let r = handle_c_command(args, symlink_cmd);

View File

@ -20,20 +20,20 @@ use crate::{
fn mount_inner( fn mount_inner(
src: String, src: String,
target: impl AsRef<std::path::Path>, target: &std::path::Path,
fstype: &str, fstype: &str,
mut mountflags: libc::c_ulong, mut mountflags: libc::c_ulong,
data: Option<String>, data: Option<String>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
// bind the CStrings to keep them alive // bind the CStrings to keep them alive
let src = CString::new(src)?; let c_src = CString::new(src.clone())?;
let target = path_to_cstr(target); let c_target = path_to_cstr(target);
let data = data.map(CString::new).transpose()?; let data = data.map(CString::new).transpose()?;
let fstype = CString::new(fstype)?; let fstype = CString::new(fstype)?;
// convert to pointers for ffi // convert to pointers for ffi
let src = src.as_ptr(); let c_src = c_src.as_ptr();
let target = target.as_ptr(); let c_target = c_target.as_ptr();
let data_ptr = data.as_ref().map_or(ptr::null(), |data| data.as_ptr().cast()); let data_ptr = data.as_ref().map_or(ptr::null(), |data| data.as_ptr().cast());
let fstype = fstype.as_ptr(); let fstype = fstype.as_ptr();
@ -42,7 +42,7 @@ fn mount_inner(
ret = { ret = {
info!("mounting filesystem"); info!("mounting filesystem");
// REQUIRES: CAP_SYS_ADMIN // REQUIRES: CAP_SYS_ADMIN
unsafe { libc::mount(src, target, fstype, mountflags, data_ptr) } unsafe { libc::mount(c_src, c_target, fstype, mountflags, data_ptr) }
}; };
let err = errno::errno().0; let err = errno::errno().0;
@ -60,9 +60,19 @@ fn mount_inner(
drop(data); drop(data);
match ret { if ret != 0 {
0 => Ok(()), let err = errno::errno();
_ => Err(crate::ErrnoError(errno::errno()).into()), let e = crate::ErrnoError(err);
if err.0 == libc::EBUSY {
eprintln!("mount: {}: {} already mounted or mount point busy", target.to_string_lossy(), src);
} else {
eprintln!("mount: {}: {}", src, e);
}
Err(e.into())
} else {
Ok(())
} }
} }
@ -360,7 +370,7 @@ pub struct Cli {
verbose: u8, verbose: u8,
} }
pub fn mount(mut argv: Vec<String>, symlink_cmd: Option<&str>) -> Result<()> { pub fn mount(mut argv: Vec<String>, symlink_cmd: Option<&str>) -> std::process::ExitCode {
// If the bcachefs tool is being called as "bcachefs mount dev ..." (as opposed to via a // If the bcachefs tool is being called as "bcachefs mount dev ..." (as opposed to via a
// symlink like "/usr/sbin/mount.bcachefs dev ...", then we need to pop the 0th argument // symlink like "/usr/sbin/mount.bcachefs dev ...", then we need to pop the 0th argument
// ("bcachefs") since the CLI parser here expects the device at position 1. // ("bcachefs") since the CLI parser here expects the device at position 1.
@ -373,5 +383,8 @@ pub fn mount(mut argv: Vec<String>, symlink_cmd: Option<&str>) -> Result<()> {
// TODO: centralize this on the top level CLI // TODO: centralize this on the top level CLI
logging::setup(cli.verbose, cli.colorize); logging::setup(cli.verbose, cli.colorize);
cmd_mount_inner(&cli) match cmd_mount_inner(&cli) {
Ok(_) => std::process::ExitCode::SUCCESS,
Err(_) => std::process::ExitCode::FAILURE,
}
} }