Skip to content

Commit 700989c

Browse files
authored
feat: add --fuse-fd flag for pre-opened /dev/fuse file descriptor (#85)
## Summary - Add `--fuse-fd=N` CLI flag to hf-mount-fuse - When set, uses `fuser::Session::from_fd()` instead of `Session::new()`, skipping the kernel mount - Enables the CSI sidecar injection pattern: privileged CSI driver does the kernel mount, passes fd via SCM_RIGHTS to an unprivileged sidecar running hf-mount Companion PR: huggingface/hf-csi-driver#19
1 parent 5244d3a commit 700989c

3 files changed

Lines changed: 39 additions & 12 deletions

File tree

src/bin/hf-mount-fuse.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ fn main() {
1818
&s.runtime,
1919
daemon_guard.as_mut(),
2020
s.fuse_owner_only,
21+
s.fuse_fd,
2122
) {
2223
std::process::exit(1);
2324
}

src/fuse.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::ffi::OsStr;
2+
use std::os::fd::FromRawFd;
23
use std::path::Path;
34
use std::sync::Arc;
45
use std::time::{Duration, SystemTime};
@@ -510,6 +511,7 @@ pub fn mount_fuse(
510511
runtime: &tokio::runtime::Runtime,
511512
daemon_guard: Option<&mut DaemonGuard>,
512513
fuse_owner_only: bool,
514+
fuse_fd: Option<i32>,
513515
) -> bool {
514516
let adapter = FuseAdapter::new(
515517
runtime.handle().clone(),
@@ -557,19 +559,33 @@ pub fn mount_fuse(
557559
config.n_threads = Some(max_threads);
558560
}
559561

560-
let session = match fuser::Session::new(adapter, mount_point, &config) {
561-
Ok(s) => s,
562-
Err(e) => {
563-
if e.kind() == std::io::ErrorKind::PermissionDenied {
564-
error!(
565-
"Permission denied: mounting a FUSE filesystem requires root privileges. \
566-
Try running with: sudo {}",
567-
std::env::args().collect::<Vec<_>>().join(" ")
568-
);
569-
} else {
570-
error!("FUSE session failed: {}", e);
562+
let session = if let Some(raw_fd) = fuse_fd {
563+
// Use a pre-opened /dev/fuse fd (sidecar mode). The kernel FUSE mount
564+
// was already performed by the CSI driver; we just run the userspace daemon.
565+
let owned_fd = unsafe { std::os::fd::OwnedFd::from_raw_fd(raw_fd) };
566+
info!("Using pre-opened FUSE fd={}", raw_fd);
567+
match fuser::Session::from_fd(adapter, owned_fd, config.acl, config) {
568+
Ok(s) => s,
569+
Err(e) => {
570+
error!("FUSE session from fd={} failed: {}", raw_fd, e);
571+
return false;
572+
}
573+
}
574+
} else {
575+
match fuser::Session::new(adapter, mount_point, &config) {
576+
Ok(s) => s,
577+
Err(e) => {
578+
if e.kind() == std::io::ErrorKind::PermissionDenied {
579+
error!(
580+
"Permission denied: mounting a FUSE filesystem requires root privileges. \
581+
Try running with: sudo {}",
582+
std::env::args().collect::<Vec<_>>().join(" ")
583+
);
584+
} else {
585+
error!("FUSE session failed: {}", e);
586+
}
587+
return false;
571588
}
572-
return false;
573589
}
574590
};
575591
let notifier = session.notifier();

src/setup.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@ pub struct MountOptions {
150150
/// When not set, requires `user_allow_other` in /etc/fuse.conf on Linux.
151151
#[arg(long, default_value_t = false)]
152152
pub fuse_owner_only: bool,
153+
154+
/// Use a pre-opened /dev/fuse file descriptor instead of opening /dev/fuse
155+
/// and performing the kernel mount. The kernel FUSE mount must already be
156+
/// established on this fd by the caller (e.g. a CSI driver).
157+
/// When set, the mount_point argument is ignored for mounting but still
158+
/// used for logging.
159+
#[arg(long)]
160+
pub fuse_fd: Option<i32>,
153161
}
154162

155163
/// CLI args for the foreground FUSE/NFS binaries.
@@ -175,6 +183,7 @@ pub struct MountSetup {
175183
pub max_threads: usize,
176184
pub metadata_ttl_ms: u64,
177185
pub fuse_owner_only: bool,
186+
pub fuse_fd: Option<i32>,
178187
}
179188

180189
// ── Tracing + env vars (no threads) ──────────────────────────────────
@@ -405,6 +414,7 @@ pub fn build(source: Source, options: MountOptions, is_nfs: bool) -> MountSetup
405414
max_threads: options.max_threads,
406415
metadata_ttl_ms: options.metadata_ttl_ms,
407416
fuse_owner_only: options.fuse_owner_only,
417+
fuse_fd: options.fuse_fd,
408418
}
409419
}
410420

0 commit comments

Comments
 (0)