@@ -6,6 +6,7 @@ use std::fs::create_dir_all;
66use std:: fs:: File ;
77use std:: io:: Read ;
88use std:: os:: unix:: fs:: PermissionsExt ;
9+ use std:: path:: Path ;
910use std:: path:: PathBuf ;
1011use std:: process:: Command ;
1112
@@ -16,6 +17,7 @@ use tracing;
1617use tracing:: instrument;
1718
1819use crate :: error:: Error ;
20+ use fstab:: FsTab ;
1921
2022#[ derive( Debug , Default , Deserialize , PartialEq , Clone ) ]
2123pub struct Environment {
@@ -75,20 +77,27 @@ pub const PATH_MOUNT_DEVICE: &str = "/dev/sr0";
7577pub const PATH_MOUNT_POINT : & str = "/run/azure-init/media/" ;
7678
7779const CDROM_VALID_FS : & [ & str ] = & [ "iso9660" , "udf" ] ;
80+ const MTAB_PATH : & str = "/etc/mtab" ;
7881
7982// Get a mounted device with any filesystem for CDROM
8083#[ instrument]
81- pub fn get_mount_device ( ) -> Result < Vec < String > , Error > {
82- let mut list_devices: Vec < String > = Vec :: new ( ) ;
84+ pub fn get_mount_device ( path : Option < & Path > ) -> Result < Vec < String > , Error > {
85+ let fstab = FsTab :: new ( path. unwrap_or_else ( || Path :: new ( MTAB_PATH ) ) ) ;
86+ let entries = fstab. get_entries ( ) ?;
8387
84- while let Some ( device) = block_utils:: get_mounted_devices ( ) ?
88+ // Retrieve the names of all devices that have cdrom-type filesystem (e.g., udf)
89+ let cdrom_devices = entries
8590 . into_iter ( )
86- . find ( |dev| CDROM_VALID_FS . contains ( & dev. fs_type . to_str ( ) ) )
87- {
88- list_devices. push ( device. name ) ;
89- }
90-
91- Ok ( list_devices)
91+ . filter_map ( |entry| {
92+ if CDROM_VALID_FS . contains ( & entry. vfs_type . as_str ( ) ) {
93+ Some ( entry. fs_spec )
94+ } else {
95+ None
96+ }
97+ } )
98+ . collect ( ) ;
99+
100+ Ok ( cdrom_devices)
92101}
93102
94103// Some zero-sized structs that just provide states for our state machine
@@ -222,6 +231,9 @@ pub fn mount_parse_ovf_env(dev: String) -> Result<Environment, Error> {
222231#[ cfg( test) ]
223232mod tests {
224233 use super :: * ;
234+ use crate :: error:: Error ;
235+ use std:: io:: Write ;
236+ use tempfile:: NamedTempFile ;
225237
226238 #[ test]
227239 fn test_get_ovf_env_none_missing ( ) {
@@ -406,4 +418,80 @@ mod tests {
406418 _ => panic ! ( "Non-empty passwords aren't allowed" ) ,
407419 } ;
408420 }
421+
422+ #[ test]
423+ fn test_get_mount_device_with_cdrom_entries ( ) {
424+ let mut temp_file =
425+ NamedTempFile :: new ( ) . expect ( "Failed to create temporary file" ) ;
426+ let mount_table = r#"
427+ /dev/sr0 /mnt/cdrom iso9660 ro,user,noauto 0 0
428+ /dev/sr1 /mnt/cdrom2 udf ro,user,noauto 0 0
429+ "# ;
430+ temp_file
431+ . write_all ( mount_table. as_bytes ( ) )
432+ . expect ( "Failed to write to temporary file" ) ;
433+ let temp_path = temp_file. into_temp_path ( ) ;
434+ let result = get_mount_device ( Some ( temp_path. as_ref ( ) ) ) ;
435+
436+ let list_devices = result. unwrap ( ) ;
437+ assert_eq ! (
438+ list_devices,
439+ vec![ "/dev/sr0" . to_string( ) , "/dev/sr1" . to_string( ) ]
440+ ) ;
441+ }
442+
443+ #[ test]
444+ fn test_get_mount_device_without_cdrom_entries ( ) {
445+ let mut temp_file =
446+ NamedTempFile :: new ( ) . expect ( "Failed to create temporary file" ) ;
447+ let mount_table = r#"
448+ /dev/sda1 / ext4 defaults 0 0
449+ /dev/sda2 /home ext4 defaults 0 0
450+ "# ;
451+ temp_file
452+ . write_all ( mount_table. as_bytes ( ) )
453+ . expect ( "Failed to write to temporary file" ) ;
454+ let temp_path = temp_file. into_temp_path ( ) ;
455+ let result = get_mount_device ( Some ( temp_path. as_ref ( ) ) ) ;
456+
457+ let list_devices = result. unwrap ( ) ;
458+ assert ! ( list_devices. is_empty( ) ) ;
459+ }
460+
461+ #[ test]
462+ fn test_get_mount_device_with_mixed_entries ( ) {
463+ let mut temp_file =
464+ NamedTempFile :: new ( ) . expect ( "Failed to create temporary file" ) ;
465+ let mount_table = r#"
466+ /dev/sr0 /mnt/cdrom iso9660 ro,user,noauto 0 0
467+ /dev/sda1 / ext4 defaults 0 0
468+ /dev/sr1 /mnt/cdrom2 udf ro,user,noauto 0 0
469+ "# ;
470+ temp_file
471+ . write_all ( mount_table. as_bytes ( ) )
472+ . expect ( "Failed to write to temporary file" ) ;
473+ let temp_path = temp_file. into_temp_path ( ) ;
474+ let result = get_mount_device ( Some ( temp_path. as_ref ( ) ) ) ;
475+
476+ let list_devices = result. unwrap ( ) ;
477+ assert_eq ! (
478+ list_devices,
479+ vec![ "/dev/sr0" . to_string( ) , "/dev/sr1" . to_string( ) ]
480+ ) ;
481+ }
482+
483+ #[ test]
484+ fn test_get_mount_device_with_empty_table ( ) {
485+ let mut temp_file =
486+ NamedTempFile :: new ( ) . expect ( "Failed to create temporary file" ) ;
487+ let mount_table = "" ;
488+ temp_file
489+ . write_all ( mount_table. as_bytes ( ) )
490+ . expect ( "Failed to write to temporary file" ) ;
491+ let temp_path = temp_file. into_temp_path ( ) ;
492+ let result = get_mount_device ( Some ( temp_path. as_ref ( ) ) ) ;
493+
494+ let list_devices = result. unwrap ( ) ;
495+ assert ! ( list_devices. is_empty( ) ) ;
496+ }
409497}
0 commit comments