Parse mount options in any position, fork before mount by default

This commit is contained in:
Travis Burtrum 2022-08-04 00:57:54 -04:00
parent 93135ccdff
commit c0f4a33e86

View File

@ -3,8 +3,8 @@ use fuser::{
ReplyOpen, Request, ReplyOpen, Request,
}; };
use libc::{ use libc::{
c_int, EINVAL, EIO, ENOENT, EPERM, O_ACCMODE, O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, c_int, exit, fork, setsid, EINVAL, EIO, ENOENT, EPERM, O_ACCMODE, O_APPEND, O_CREAT, O_EXCL,
O_TRUNC, O_WRONLY, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY,
}; };
use log::{debug, error, warn}; use log::{debug, error, warn};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -591,16 +591,39 @@ impl Filesystem for CacheFs {
} }
} }
pub fn daemon() {
unsafe {
match fork() {
// child
0 => {
if setsid() == -1 {
error!("error executing setsid()");
exit(1);
}
}
-1 => {
error!("error executing fork()");
exit(1);
}
// parent
_ => exit(0),
}
}
}
fn main() { fn main() {
env_logger::init(); env_logger::init();
let mut args = env::args_os().skip(1); let mut args = env::args_os().skip(1);
if args.next() != Some(OsStr::from_bytes(b"-o").to_os_string()) {
panic!("-o must be second argument");
}
let mut cmd_opts = "ro".to_string(); let mut cmd_opts = "ro".to_string();
let mut cache_dir = "".to_string(); let mut cache_dir = "".to_string();
let mut default_permissions = true; let mut default_permissions = true;
let mut fork_daemon = true;
let mut count = 0;
let mut pos_args = [None, None];
while let Some(arg) = args.next() {
if arg == "-o" {
let opts = args.next().expect("found -o but missing opts"); let opts = args.next().expect("found -o but missing opts");
let opts = opts.to_str().expect("non-utf8 opts").split(','); let opts = opts.to_str().expect("non-utf8 opts").split(',');
for opt in opts { for opt in opts {
@ -615,6 +638,7 @@ fn main() {
match opt { match opt {
"ro" => (), "ro" => (),
"no_default_permissions" => default_permissions = false, "no_default_permissions" => default_permissions = false,
"no_daemon" | "no_fork" | "nodaemon" | "nofork" => fork_daemon = false,
"rw" => panic!("rw is not supported"), "rw" => panic!("rw is not supported"),
opt => { opt => {
cmd_opts.push(','); cmd_opts.push(',');
@ -631,9 +655,16 @@ fn main() {
if default_permissions && !cmd_opts.contains(",default_permissions,") { if default_permissions && !cmd_opts.contains(",default_permissions,") {
cmd_opts.push_str(",default_permissions"); cmd_opts.push_str(",default_permissions");
} }
} else if count < pos_args.len() {
pos_args[count] = Some(arg);
count += 1
} else {
panic!("too many arguments");
}
}
let remote_dir = PathBuf::from(args.next().expect("missing dir")); let remote_dir = PathBuf::from(pos_args[0].as_ref().expect("missing dir"));
let mountpoint = args.next().expect("missing mountpoint"); let mountpoint = pos_args[1].as_ref().expect("missing mountpoint");
let cache_dir = PathBuf::from(cache_dir); let cache_dir = PathBuf::from(cache_dir);
debug!( debug!(
@ -649,6 +680,10 @@ fn main() {
let cmd_opts = OsString::from(cmd_opts); let cmd_opts = OsString::from(cmd_opts);
let options = [OsStr::new("-o"), cmd_opts.as_os_str()]; let options = [OsStr::new("-o"), cmd_opts.as_os_str()];
if fork_daemon {
daemon();
}
#[allow(deprecated)] #[allow(deprecated)]
fuser::mount(cache, mountpoint, &options).expect("mount failed"); fuser::mount(cache, mountpoint, &options).expect("mount failed");
} }