diff --git a/src/bin/pxar.rs b/src/bin/pxar.rs index 0f80d94d..56f31df4 100644 --- a/src/bin/pxar.rs +++ b/src/bin/pxar.rs @@ -226,6 +226,7 @@ fn mount_archive( let archive = tools::required_string_param(¶m, "archive")?; let mountpoint = tools::required_string_param(¶m, "mountpoint")?; let verbose = param["verbose"].as_bool().unwrap_or(false); + let no_mt = param["no-mt"].as_bool().unwrap_or(false); let archive = Path::new(archive); let mountpoint = Path::new(mountpoint); @@ -233,7 +234,7 @@ fn mount_archive( let mut session = pxar::fuse::Session::new(&archive, &options, verbose) .map_err(|err| format_err!("pxar mount failed: {}", err))?; session.mount(&mountpoint)?; - session.run_loop()?; + session.run_loop(!no_mt)?; Ok(Value::Null) } @@ -295,7 +296,8 @@ fn main() { ObjectSchema::new("Mount the archive as filesystem via FUSE.") .required("archive", StringSchema::new("Archive name.")) .required("mountpoint", StringSchema::new("Mountpoint for the filesystem root.")) - .optional("verbose", BooleanSchema::new("Verbose output, keeps process running in foreground.").default(false)) + .optional("verbose", BooleanSchema::new("Verbose output, keeps process running in foreground (for debugging).").default(false)) + .optional("no-mt", BooleanSchema::new("Run in single threaded mode (for debugging).").default(false)) )) .arg_param(vec!["archive", "mountpoint"]) .completion_cb("archive", tools::complete_file_name) diff --git a/src/pxar/fuse.rs b/src/pxar/fuse.rs index 110cde77..bc91ab6d 100644 --- a/src/pxar/fuse.rs +++ b/src/pxar/fuse.rs @@ -46,6 +46,7 @@ extern "C" { fn fuse_session_mount(session: ConstPtr, mountpoint: StrPtr) -> c_int; fn fuse_session_unmount(session: ConstPtr); fn fuse_session_loop(session: ConstPtr) -> c_int; + fn fuse_session_loop_mt_31(session: ConstPtr, clone_fd: c_int) -> c_int; fn fuse_session_destroy(session: ConstPtr); // fn fuse_reply_attr(req: Request, attr: *const libc::stat, timeout: f64) -> c_int; fn fuse_reply_err(req: Request, errno: c_int) -> c_int; @@ -212,11 +213,18 @@ impl Session { } /// Execute session loop which handles requests from kernel. - pub fn run_loop(&mut self) -> Result<(), Error> { + /// + /// The multi_threaded flag controls if the session loop runs in + /// singlethreaded or multithreaded. + /// Singlethreaded mode is intended for debugging. + pub fn run_loop(&mut self, multi_threaded: bool) -> Result<(), Error> { if self.verbose { println!("Executing fuse session loop"); } - let result = unsafe { fuse_session_loop(self.ptr) }; + let result = match multi_threaded { + true => unsafe { fuse_session_loop_mt_31(self.ptr, 1) }, + false => unsafe { fuse_session_loop(self.ptr) }, + }; if result < 0 { bail!("fuse session loop exited with - {}", result); }