@@ -1052,13 +1052,18 @@ const OVERLAY_ARGS_INDEX: &str = "index";
10521052const OVERLAY_ARGS_INDEX_ON : & str = "index=on" ;
10531053const OVERLAY_ARGS_METACOPY : & str = "metacopy" ;
10541054const OVERLAY_ARGS_METACOPY_ON : & str = "metacopy=on" ;
1055+ pub ( crate ) const OVERLAY_ARGS_LOWERDIR_APPEND : & str = "lowerdir+" ;
1056+ const OVERLAY_ARGS_LOWERDIR_APPEND_ASSIGN : & str = "lowerdir+=" ;
1057+ const OVERLAY_ARGS_LOWERDIR_ASSIGN : & str = "lowerdir=" ;
10551058
10561059/// A struct for holding the options that will be included
10571060/// in the overlayfs mount command when mounting an environment.
10581061#[ derive( Default ) ]
10591062pub ( crate ) struct OverlayMountOptions {
10601063 /// Specifies that the overlay file system is mounted as read-only
10611064 pub read_only : bool ,
1065+ /// The lowerdir+ mount option will be used to append layers when true.
1066+ pub lowerdir_append : bool ,
10621067 /// When true, inodes are indexed in the mount so that
10631068 /// files which share the same inode (hardlinks) are broken
10641069 /// in the final mount and changes to one file don't affect
@@ -1089,11 +1094,22 @@ impl OverlayMountOptions {
10891094 fn new ( rt : & runtime:: Runtime ) -> Self {
10901095 Self {
10911096 read_only : !rt. status . editable ,
1097+ lowerdir_append : true ,
10921098 break_hardlinks : true ,
10931099 metadata_copy_up : true ,
10941100 }
10951101 }
10961102
1103+ /// Update state variables to match the features supported by the current overlay version.
1104+ fn query ( mut self ) -> Self {
1105+ let params = runtime:: overlayfs:: overlayfs_available_options ( ) ;
1106+ if self . lowerdir_append && !params. contains ( OVERLAY_ARGS_LOWERDIR_APPEND ) {
1107+ self . lowerdir_append = false ;
1108+ }
1109+
1110+ self
1111+ }
1112+
10971113 /// Return the options that should be included in the mount request.
10981114 pub fn to_options ( & self ) -> Vec < & ' static str > {
10991115 let params = runtime:: overlayfs:: overlayfs_available_options ( ) ;
@@ -1130,7 +1146,7 @@ pub(crate) fn get_overlay_args<P: AsRef<Path>>(
11301146 // Allocate a large buffer up front to avoid resizing/copying.
11311147 let mut args = String :: with_capacity ( 4096 ) ;
11321148
1133- let mount_options = OverlayMountOptions :: new ( rt) ;
1149+ let mount_options = OverlayMountOptions :: new ( rt) . query ( ) ;
11341150 for option in mount_options. to_options ( ) {
11351151 args. push_str ( option) ;
11361152 args. push ( ',' ) ;
@@ -1142,19 +1158,19 @@ pub(crate) fn get_overlay_args<P: AsRef<Path>>(
11421158 // the rightmost on the command line is the bottom layer, and the
11431159 // leftmost is on the top). For more details see:
11441160 // https://docs.kernel.org/filesystems/overlayfs.html#multiple-lower-layers
1145- if cfg ! ( feature = "legacy-mount-options" ) {
1146- args. push_str ( "lowerdir=" ) ;
1161+ if mount_options. lowerdir_append {
11471162 for path in layer_dirs. iter ( ) . rev ( ) {
1163+ args. push_str ( OVERLAY_ARGS_LOWERDIR_APPEND_ASSIGN ) ;
11481164 args. push_str ( & path. as_ref ( ) . to_string_lossy ( ) ) ;
1149- args. push ( ': ' ) ;
1165+ args. push ( ', ' ) ;
11501166 }
1167+ args. push_str ( OVERLAY_ARGS_LOWERDIR_APPEND_ASSIGN ) ;
11511168 } else {
1169+ args. push_str ( OVERLAY_ARGS_LOWERDIR_ASSIGN ) ;
11521170 for path in layer_dirs. iter ( ) . rev ( ) {
1153- args. push_str ( "lowerdir+=" ) ;
11541171 args. push_str ( & path. as_ref ( ) . to_string_lossy ( ) ) ;
1155- args. push ( ', ' ) ;
1172+ args. push ( ': ' ) ;
11561173 }
1157- args. push_str ( "lowerdir+=" ) ;
11581174 }
11591175 args. push_str ( & rt. config . lower_dir . to_string_lossy ( ) ) ;
11601176
0 commit comments