@@ -12,6 +12,7 @@ use crate::task::Task;
1212
1313#[ derive( Deserialize , Debug ) ]
1414#[ serde( rename_all = "kebab-case" ) ]
15+ #[ allow( dead_code) ]
1516pub ( crate ) struct Filesystem {
1617 // Note if you add an entry to this list, you need to change the --output invocation below too
1718 pub ( crate ) source : String ,
@@ -21,14 +22,15 @@ pub(crate) struct Filesystem {
2122 pub ( crate ) fstype : String ,
2223 pub ( crate ) options : String ,
2324 pub ( crate ) uuid : Option < String > ,
25+ pub ( crate ) children : Option < Vec < Filesystem > > ,
2426}
2527
2628#[ derive( Deserialize , Debug ) ]
2729pub ( crate ) struct Findmnt {
2830 pub ( crate ) filesystems : Vec < Filesystem > ,
2931}
3032
31- fn run_findmnt ( args : & [ & str ] , path : & str ) -> Result < Filesystem > {
33+ fn run_findmnt ( args : & [ & str ] , path : & str ) -> Result < Findmnt > {
3234 let o: Findmnt = Command :: new ( "findmnt" )
3335 . args ( [
3436 "-J" ,
@@ -40,6 +42,12 @@ fn run_findmnt(args: &[&str], path: &str) -> Result<Filesystem> {
4042 . arg ( path)
4143 . log_debug ( )
4244 . run_and_parse_json ( ) ?;
45+ Ok ( o)
46+ }
47+
48+ // Retrieve a mounted filesystem from a device given a matching path
49+ fn findmnt_filesystem ( args : & [ & str ] , path : & str ) -> Result < Filesystem > {
50+ let o = run_findmnt ( args, path) ?;
4351 o. filesystems
4452 . into_iter ( )
4553 . next ( )
@@ -50,13 +58,40 @@ fn run_findmnt(args: &[&str], path: &str) -> Result<Filesystem> {
5058/// Inspect a target which must be a mountpoint root - it is an error
5159/// if the target is not the mount root.
5260pub ( crate ) fn inspect_filesystem ( path : & Utf8Path ) -> Result < Filesystem > {
53- run_findmnt ( & [ "--mountpoint" ] , path. as_str ( ) )
61+ findmnt_filesystem ( & [ "--mountpoint" ] , path. as_str ( ) )
5462}
5563
5664#[ context( "Inspecting filesystem by UUID {uuid}" ) ]
5765/// Inspect a filesystem by partition UUID
5866pub ( crate ) fn inspect_filesystem_by_uuid ( uuid : & str ) -> Result < Filesystem > {
59- run_findmnt ( & [ "--source" ] , & ( format ! ( "UUID={uuid}" ) ) )
67+ findmnt_filesystem ( & [ "--source" ] , & ( format ! ( "UUID={uuid}" ) ) )
68+ }
69+
70+ // Check if a specified device contains an already mounted filesystem
71+ // in the root mount namespace
72+ pub ( crate ) fn is_mounted_in_pid1_mountns ( path : & str ) -> Result < bool > {
73+ let o = run_findmnt ( & [ "-N" ] , "1" ) ?;
74+
75+ let mounted = o. filesystems . iter ( ) . any ( |fs| is_source_mounted ( path, fs) ) ;
76+
77+ Ok ( mounted)
78+ }
79+
80+ // Recursively check a given filesystem to see if it contains an already mounted source
81+ pub ( crate ) fn is_source_mounted ( path : & str , mounted_fs : & Filesystem ) -> bool {
82+ if mounted_fs. source . contains ( path) {
83+ return true ;
84+ }
85+
86+ if let Some ( ref children) = mounted_fs. children {
87+ for child in children {
88+ if is_source_mounted ( path, child) {
89+ return true ;
90+ }
91+ }
92+ }
93+
94+ false
6095}
6196
6297/// Mount a device to the target path.
0 commit comments