@@ -37,6 +37,7 @@ const POLL_EVENTS_CAPACITY: usize = 1024;
37
37
38
38
const FUSE_DEVICE : & str = "/dev/fuse" ;
39
39
const FUSE_FSTYPE : & str = "fuse" ;
40
+ const FUSERMOUNT_BIN : & str = "fusermount3" ;
40
41
41
42
const EXIT_FUSE_EVENT : Token = Token ( 0 ) ;
42
43
const FUSE_DEV_EVENT : Token = Token ( 1 ) ;
@@ -54,6 +55,8 @@ pub struct FuseSession {
54
55
wakers : Mutex < Vec < Arc < Waker > > > ,
55
56
auto_unmount : bool ,
56
57
target_mntns : Option < libc:: pid_t > ,
58
+ // fusermount binary, default to fusermount3
59
+ fusermount : String ,
57
60
}
58
61
59
62
impl FuseSession {
@@ -93,6 +96,7 @@ impl FuseSession {
93
96
wakers : Mutex :: new ( Vec :: new ( ) ) ,
94
97
auto_unmount,
95
98
target_mntns : None ,
99
+ fusermount : FUSERMOUNT_BIN . to_string ( ) ,
96
100
} )
97
101
}
98
102
@@ -102,6 +106,16 @@ impl FuseSession {
102
106
self . target_mntns = pid;
103
107
}
104
108
109
+ /// Set fusermount binary, default to fusermount3.
110
+ pub fn set_fusermount ( & mut self , bin : & str ) {
111
+ self . fusermount = bin. to_string ( ) ;
112
+ }
113
+
114
+ /// Get current fusermount binary.
115
+ pub fn get_fusermount ( & self ) -> & str {
116
+ self . fusermount . as_str ( )
117
+ }
118
+
105
119
/// Mount the fuse mountpoint, building connection with the in kernel fuse driver.
106
120
pub fn mount ( & mut self ) -> Result < ( ) > {
107
121
let mut flags = MsFlags :: MS_NOSUID | MsFlags :: MS_NODEV | MsFlags :: MS_NOATIME ;
@@ -115,6 +129,7 @@ impl FuseSession {
115
129
flags,
116
130
self . auto_unmount ,
117
131
self . target_mntns ,
132
+ & self . fusermount ,
118
133
) ?;
119
134
120
135
fcntl ( file. as_raw_fd ( ) , FcntlArg :: F_SETFL ( OFlag :: O_NONBLOCK ) )
@@ -138,10 +153,10 @@ impl FuseSession {
138
153
/// Destroy a fuse session.
139
154
pub fn umount ( & mut self ) -> Result < ( ) > {
140
155
// If we have a keep_alive socket, just drop it,
141
- // and let fusermount3 do the unmount.
156
+ // and let fusermount do the unmount.
142
157
if let ( None , Some ( file) ) = ( self . keep_alive . take ( ) , self . file . take ( ) ) {
143
158
if let Some ( mountpoint) = self . mountpoint . to_str ( ) {
144
- fuse_kern_umount ( mountpoint, file)
159
+ fuse_kern_umount ( mountpoint, file, self . fusermount . as_str ( ) )
145
160
} else {
146
161
Err ( SessionFailure ( "invalid mountpoint" . to_string ( ) ) )
147
162
}
@@ -356,6 +371,7 @@ fn fuse_kern_mount(
356
371
flags : MsFlags ,
357
372
auto_unmount : bool ,
358
373
target_mntns : Option < libc:: pid_t > ,
374
+ fusermount : & str ,
359
375
) -> Result < ( File , Option < UnixStream > ) > {
360
376
let file = OpenOptions :: new ( )
361
377
. create ( false )
@@ -390,7 +406,7 @@ fn fuse_kern_mount(
390
406
) ;
391
407
}
392
408
393
- // mount in another mntns requires mounting with fusermount3 , which is a new process, as
409
+ // mount in another mntns requires mounting with fusermount , which is a new process, as
394
410
// multithreaded program is not allowed to join to another mntns, and the process running fuse
395
411
// session might be multithreaded.
396
412
if auto_unmount || target_mntns. is_some ( ) {
@@ -402,6 +418,7 @@ fn fuse_kern_mount(
402
418
flags,
403
419
auto_unmount,
404
420
target_mntns,
421
+ fusermount,
405
422
)
406
423
} else {
407
424
match mount (
@@ -420,6 +437,7 @@ fn fuse_kern_mount(
420
437
flags,
421
438
auto_unmount,
422
439
target_mntns,
440
+ fusermount,
423
441
) ,
424
442
Err ( e) => Err ( SessionFailure ( format ! (
425
443
"failed to mount {mountpoint:?}: {e}"
@@ -450,6 +468,7 @@ fn msflags_to_string(flags: MsFlags) -> String {
450
468
}
451
469
452
470
/// Mount a fuse file system with fusermount
471
+ #[ allow( clippy:: too_many_arguments) ]
453
472
fn fuse_fusermount_mount (
454
473
mountpoint : & Path ,
455
474
fsname : & str ,
@@ -458,6 +477,7 @@ fn fuse_fusermount_mount(
458
477
flags : MsFlags ,
459
478
auto_unmount : bool ,
460
479
target_mntns : Option < libc:: pid_t > ,
480
+ fusermount : & str ,
461
481
) -> Result < ( File , Option < UnixStream > ) > {
462
482
let mut opts = vec ! [ format!( "fsname={fsname}" ) , opts, msflags_to_string( flags) ] ;
463
483
if !subtype. is_empty ( ) {
@@ -470,10 +490,10 @@ fn fuse_fusermount_mount(
470
490
471
491
let ( send, recv) = UnixStream :: pair ( ) . unwrap ( ) ;
472
492
473
- // Keep the sending socket around after exec to pass to fusermount3 .
474
- // When its partner recv closes, fusermount3 will unmount.
493
+ // Keep the sending socket around after exec to pass to fusermount .
494
+ // When its partner recv closes, fusermount will unmount.
475
495
// Remove the close-on-exec flag from the socket, so we can pass it to
476
- // fusermount3 .
496
+ // fusermount .
477
497
nix:: fcntl:: fcntl ( send. as_raw_fd ( ) , FcntlArg :: F_SETFD ( FdFlag :: empty ( ) ) )
478
498
. map_err ( |e| SessionFailure ( format ! ( "Failed to remove close-on-exec flag: {e}" ) ) ) ?;
479
499
@@ -483,10 +503,10 @@ fn fuse_fusermount_mount(
483
503
c. arg ( "-t" )
484
504
. arg ( format ! ( "{}" , pid) )
485
505
. arg ( "-m" )
486
- . arg ( "fusermount3" ) ;
506
+ . arg ( fusermount ) ;
487
507
c
488
508
}
489
- None => std:: process:: Command :: new ( "fusermount3" ) ,
509
+ None => std:: process:: Command :: new ( fusermount ) ,
490
510
} ;
491
511
// Old version of fusermount doesn't support long --options, yet.
492
512
let mut proc = cmd
@@ -507,7 +527,7 @@ fn fuse_fusermount_mount(
507
527
Some ( 0 ) => { }
508
528
exit_code => {
509
529
return Err ( SessionFailure ( format ! (
510
- "Unexpected exit code when running fusermount3 : {exit_code:?}"
530
+ "Unexpected exit code when running fusermount : {exit_code:?}"
511
531
) ) )
512
532
}
513
533
}
@@ -517,20 +537,20 @@ fn fuse_fusermount_mount(
517
537
match vmm_sys_util:: sock_ctrl_msg:: ScmSocket :: recv_with_fd ( & recv, & mut [ 0u8 ; 8 ] ) . map_err (
518
538
|e| {
519
539
SessionFailure ( format ! (
520
- "Unexpected error when receiving fuse file descriptor from fusermount3 : {}" ,
540
+ "Unexpected error when receiving fuse file descriptor from fusermount : {}" ,
521
541
e
522
542
) )
523
543
} ,
524
544
) ? {
525
545
( _recv_bytes, Some ( file) ) => Ok ( ( file, if auto_unmount { Some ( recv) } else { None } ) ) ,
526
546
( recv_bytes, None ) => Err ( SessionFailure ( format ! (
527
- "fusermount3 did not send a file descriptor. We received {recv_bytes} bytes."
547
+ "fusermount did not send a file descriptor. We received {recv_bytes} bytes."
528
548
) ) ) ,
529
549
}
530
550
}
531
551
532
552
/// Umount a fuse file system
533
- fn fuse_kern_umount ( mountpoint : & str , file : File ) -> Result < ( ) > {
553
+ fn fuse_kern_umount ( mountpoint : & str , file : File , fusermount : & str ) -> Result < ( ) > {
534
554
let mut fds = [ PollFd :: new ( file. as_raw_fd ( ) , PollFlags :: empty ( ) ) ] ;
535
555
536
556
if poll ( & mut fds, 0 ) . is_ok ( ) {
@@ -548,16 +568,16 @@ fn fuse_kern_umount(mountpoint: &str, file: File) -> Result<()> {
548
568
drop ( file) ;
549
569
match umount2 ( mountpoint, MntFlags :: MNT_DETACH ) {
550
570
Ok ( ( ) ) => Ok ( ( ) ) ,
551
- Err ( nix:: errno:: Errno :: EPERM ) => fuse_fusermount3_umount ( mountpoint) ,
571
+ Err ( nix:: errno:: Errno :: EPERM ) => fuse_fusermount_umount ( mountpoint, fusermount ) ,
552
572
Err ( e) => Err ( SessionFailure ( format ! (
553
573
"failed to umount {mountpoint}: {e}"
554
574
) ) ) ,
555
575
}
556
576
}
557
577
558
578
/// Umount a fuse file system
559
- fn fuse_fusermount3_umount ( mountpoint : & str ) -> Result < ( ) > {
560
- match std:: process:: Command :: new ( "fusermount3" )
579
+ fn fuse_fusermount_umount ( mountpoint : & str , fusermount : & str ) -> Result < ( ) > {
580
+ match std:: process:: Command :: new ( fusermount )
561
581
. arg ( "--unmount" )
562
582
. arg ( "--quiet" )
563
583
. arg ( "--lazy" )
@@ -569,7 +589,7 @@ fn fuse_fusermount3_umount(mountpoint: &str) -> Result<()> {
569
589
{
570
590
Some ( 0 ) => Ok ( ( ) ) ,
571
591
exit_code => Err ( SessionFailure ( format ! (
572
- "Unexpected exit code when unmounting via running fusermount3 : {exit_code:?}"
592
+ "Unexpected exit code when unmounting via running fusermount : {exit_code:?}"
573
593
) ) ) ,
574
594
}
575
595
}
@@ -598,6 +618,18 @@ mod tests {
598
618
let file = unsafe { File :: from_raw_fd ( fd) } ;
599
619
let _ = FuseChannel :: new ( file, 3 ) . unwrap ( ) ;
600
620
}
621
+
622
+ #[ test]
623
+ fn test_fusermount ( ) {
624
+ let dir = TempDir :: new ( ) . unwrap ( ) ;
625
+ let se = FuseSession :: new ( dir. as_path ( ) , "foo" , "bar" , true ) ;
626
+ assert ! ( se. is_ok( ) ) ;
627
+ let mut se = se. unwrap ( ) ;
628
+ assert_eq ! ( se. get_fusermount( ) , FUSERMOUNT_BIN ) ;
629
+
630
+ se. set_fusermount ( "fusermount" ) ;
631
+ assert_eq ! ( se. get_fusermount( ) , "fusermount" ) ;
632
+ }
601
633
}
602
634
603
635
#[ cfg( feature = "async_io" ) ]
0 commit comments