1
1
use crate :: { error:: DeviceError , filesystem_ops:: FileSystem } ;
2
2
use csi_driver:: filesystem:: FileSystem as Fs ;
3
+ use utils:: csi_plugin_name;
3
4
4
5
use serde_json:: Value ;
5
- use std:: { collections:: HashMap , process :: Command , str:: FromStr , string:: String , vec:: Vec } ;
6
+ use std:: { collections:: HashMap , str:: FromStr , string:: String , vec:: Vec } ;
6
7
use tracing:: { error, warn} ;
7
- use utils:: csi_plugin_name;
8
8
9
9
// Keys of interest we expect to find in the JSON output generated
10
10
// by findmnt.
@@ -145,8 +145,12 @@ const FIND_MNT_ARGS: [&str; 3] = ["-J", "-o", "SOURCE,TARGET,FSTYPE"];
145
145
146
146
/// Execute the Linux utility findmnt, collect the json output,
147
147
/// invoke the filter function and return the filtered results.
148
- fn findmnt ( params : Filter ) -> Result < Vec < HashMap < String , String > > , DeviceError > {
149
- let output = Command :: new ( FIND_MNT ) . args ( FIND_MNT_ARGS ) . output ( ) ?;
148
+ async fn findmnt ( params : Filter < ' _ > ) -> Result < Vec < HashMap < String , String > > , DeviceError > {
149
+ let output = tokio:: process:: Command :: new ( FIND_MNT )
150
+ . args ( FIND_MNT_ARGS )
151
+ . output ( )
152
+ . await ?;
153
+
150
154
if output. status . success ( ) {
151
155
let json_str = String :: from_utf8 ( output. stdout ) ?;
152
156
let json: Value = serde_json:: from_str ( & json_str) ?;
@@ -161,12 +165,12 @@ fn findmnt(params: Filter) -> Result<Vec<HashMap<String, String>>, DeviceError>
161
165
/// Use the Linux utility findmnt to find the name of the device mounted at a
162
166
/// directory or block special file, if any.
163
167
/// mount_path is the path a device is mounted on.
164
- pub ( crate ) fn get_devicepath ( mount_path : & str ) -> Result < Option < String > , DeviceError > {
168
+ pub ( crate ) async fn get_devicepath ( mount_path : & str ) -> Result < Option < String > , DeviceError > {
165
169
let tgt_filter = Filter {
166
170
key : TARGET_KEY ,
167
171
value : mount_path,
168
172
} ;
169
- let sources = findmnt ( tgt_filter) ?;
173
+ let sources = findmnt ( tgt_filter) . await ?;
170
174
{
171
175
match sources. len ( ) {
172
176
0 => Ok ( None ) ,
@@ -194,12 +198,12 @@ pub(crate) fn get_devicepath(mount_path: &str) -> Result<Option<String>, DeviceE
194
198
/// Use the Linux utility findmnt to find the mount paths for a block device,
195
199
/// if any.
196
200
/// device_path is the path to the device for example "/dev/sda1"
197
- pub ( crate ) fn get_mountpaths ( device_path : & str ) -> Result < Vec < DeviceMount > , DeviceError > {
201
+ pub ( crate ) async fn get_mountpaths ( device_path : & str ) -> Result < Vec < DeviceMount > , DeviceError > {
198
202
let dev_filter = Filter {
199
203
key : SOURCE_KEY ,
200
204
value : device_path,
201
205
} ;
202
- match findmnt ( dev_filter) {
206
+ match findmnt ( dev_filter) . await {
203
207
Ok ( results) => {
204
208
let mut mountpaths: Vec < DeviceMount > = Vec :: new ( ) ;
205
209
for entry in results {
@@ -249,8 +253,18 @@ struct FilterCsiMounts<'a> {
249
253
}
250
254
251
255
/// Finds CSI mount points using `findmnt` and filters based on the given criteria.
252
- fn find_csi_mount ( filter : FilterCsiMounts ) -> Result < Vec < HashMap < String , String > > , DeviceError > {
253
- let output = Command :: new ( FIND_MNT ) . args ( FIND_MNT_ARGS ) . output ( ) ?;
256
+ async fn find_csi_mount (
257
+ filter : FilterCsiMounts < ' _ > ,
258
+ path_prefix : Option < & str > ,
259
+ ) -> Result < Vec < HashMap < String , String > > , DeviceError > {
260
+ let mut command = tokio:: process:: Command :: new ( FIND_MNT ) ;
261
+ command. args ( FIND_MNT_ARGS ) ;
262
+
263
+ if let Some ( path_prefix) = path_prefix {
264
+ command. args ( [ "-R" , path_prefix] ) ;
265
+ }
266
+
267
+ let output = command. output ( ) . await ?;
254
268
255
269
if !output. status . success ( ) {
256
270
return Err ( DeviceError :: new ( String :: from_utf8 ( output. stderr ) ?. as_str ( ) ) ) ;
@@ -321,14 +335,17 @@ fn read_vol_data_json(path: &str) -> Result<serde_json::Map<String, Value>, Devi
321
335
}
322
336
323
337
/// Retrieves mount paths for a given CSI volume ID by parsing the metadata file.
324
- pub ( crate ) async fn get_csi_mountpaths ( volume_id : & str ) -> Result < Vec < DeviceMount > , DeviceError > {
338
+ pub ( crate ) async fn get_csi_mountpaths (
339
+ volume_id : & str ,
340
+ path_prefix : Option < & str > ,
341
+ ) -> Result < Vec < DeviceMount > , DeviceError > {
325
342
let filter = FilterCsiMounts {
326
343
driver : & csi_plugin_name ( ) ,
327
344
volume_id,
328
345
file_name : METADATA_FILE ,
329
346
device_pattern : DEVICE_PATTERN ,
330
347
} ;
331
- match find_csi_mount ( filter) {
348
+ match find_csi_mount ( filter, path_prefix ) . await {
332
349
Ok ( results) => {
333
350
let mut mountpaths: Vec < DeviceMount > = Vec :: new ( ) ;
334
351
for entry in results {
0 commit comments