Parse mount options in any position, fork before mount by default
This commit is contained in:
parent
93135ccdff
commit
c0f4a33e86
103
src/main.rs
103
src/main.rs
@ -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,49 +591,80 @@ 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 opts = args.next().expect("found -o but missing opts");
|
let mut fork_daemon = true;
|
||||||
let opts = opts.to_str().expect("non-utf8 opts").split(',');
|
|
||||||
for opt in opts {
|
let mut count = 0;
|
||||||
if opt.starts_with("cache_dir=") {
|
let mut pos_args = [None, None];
|
||||||
let mut split_opt = opt.splitn(2, '=');
|
|
||||||
if let Some(dir) = split_opt.nth(1) {
|
while let Some(arg) = args.next() {
|
||||||
cache_dir.clear();
|
if arg == "-o" {
|
||||||
cache_dir.push_str(dir);
|
let opts = args.next().expect("found -o but missing opts");
|
||||||
|
let opts = opts.to_str().expect("non-utf8 opts").split(',');
|
||||||
|
for opt in opts {
|
||||||
|
if opt.starts_with("cache_dir=") {
|
||||||
|
let mut split_opt = opt.splitn(2, '=');
|
||||||
|
if let Some(dir) = split_opt.nth(1) {
|
||||||
|
cache_dir.clear();
|
||||||
|
cache_dir.push_str(dir);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
match opt {
|
||||||
|
"ro" => (),
|
||||||
|
"no_default_permissions" => default_permissions = false,
|
||||||
|
"no_daemon" | "no_fork" | "nodaemon" | "nofork" => fork_daemon = false,
|
||||||
|
"rw" => panic!("rw is not supported"),
|
||||||
|
opt => {
|
||||||
|
cmd_opts.push(',');
|
||||||
|
cmd_opts.push_str(opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
if cache_dir.is_empty() {
|
||||||
}
|
panic!("must supply cache_dir=/path/to/cache to -o")
|
||||||
match opt {
|
|
||||||
"ro" => (),
|
|
||||||
"no_default_permissions" => default_permissions = false,
|
|
||||||
"rw" => panic!("rw is not supported"),
|
|
||||||
opt => {
|
|
||||||
cmd_opts.push(',');
|
|
||||||
cmd_opts.push_str(opt);
|
|
||||||
}
|
}
|
||||||
|
if !cmd_opts.contains(",fsname=") {
|
||||||
|
cmd_opts.push_str(",fsname=cachefs");
|
||||||
|
}
|
||||||
|
if default_permissions && !cmd_opts.contains(",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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cache_dir.is_empty() {
|
|
||||||
panic!("must supply cache_dir=/path/to/cache to -o")
|
|
||||||
}
|
|
||||||
if !cmd_opts.contains(",fsname=") {
|
|
||||||
cmd_opts.push_str(",fsname=cachefs");
|
|
||||||
}
|
|
||||||
if default_permissions && !cmd_opts.contains(",default_permissions,") {
|
|
||||||
cmd_opts.push_str(",default_permissions");
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user