@@ -1036,13 +1036,16 @@ const OVERLAY_ARGS_INDEX: &str = "index";
1036
1036
const OVERLAY_ARGS_INDEX_ON : & str = "index=on" ;
1037
1037
const OVERLAY_ARGS_METACOPY : & str = "metacopy" ;
1038
1038
const OVERLAY_ARGS_METACOPY_ON : & str = "metacopy=on" ;
1039
+ pub ( crate ) const OVERLAY_ARGS_LOWERDIR_APPEND : & str = "lowerdir+" ;
1039
1040
1040
1041
/// A struct for holding the options that will be included
1041
1042
/// in the overlayfs mount command when mounting an environment.
1042
1043
#[ derive( Default ) ]
1043
1044
pub ( crate ) struct OverlayMountOptions {
1044
1045
/// Specifies that the overlay file system is mounted as read-only
1045
1046
pub read_only : bool ,
1047
+ /// The lowerdir+ mount option will be used to append layers when true.
1048
+ pub lowerdir_append : bool ,
1046
1049
/// When true, inodes are indexed in the mount so that
1047
1050
/// files which share the same inode (hardlinks) are broken
1048
1051
/// in the final mount and changes to one file don't affect
@@ -1073,11 +1076,22 @@ impl OverlayMountOptions {
1073
1076
fn new ( rt : & runtime:: Runtime ) -> Self {
1074
1077
Self {
1075
1078
read_only : !rt. status . editable ,
1079
+ lowerdir_append : true ,
1076
1080
break_hardlinks : true ,
1077
1081
metadata_copy_up : true ,
1078
1082
}
1079
1083
}
1080
1084
1085
+ /// Update state variables to match the features supported by the current overlay version.
1086
+ fn query ( mut self ) -> Self {
1087
+ let params = runtime:: overlayfs:: overlayfs_available_options ( ) ;
1088
+ if self . lowerdir_append && !params. contains ( OVERLAY_ARGS_LOWERDIR_APPEND ) {
1089
+ self . lowerdir_append = false ;
1090
+ }
1091
+
1092
+ self
1093
+ }
1094
+
1081
1095
/// Return the options that should be included in the mount request.
1082
1096
pub fn to_options ( & self ) -> Vec < & ' static str > {
1083
1097
let params = runtime:: overlayfs:: overlayfs_available_options ( ) ;
@@ -1114,7 +1128,7 @@ pub(crate) fn get_overlay_args<P: AsRef<Path>>(
1114
1128
// Allocate a large buffer up front to avoid resizing/copying.
1115
1129
let mut args = String :: with_capacity ( 4096 ) ;
1116
1130
1117
- let mount_options = OverlayMountOptions :: new ( rt) ;
1131
+ let mount_options = OverlayMountOptions :: new ( rt) . query ( ) ;
1118
1132
for option in mount_options. to_options ( ) {
1119
1133
args. push_str ( option) ;
1120
1134
args. push ( ',' ) ;
@@ -1126,19 +1140,19 @@ pub(crate) fn get_overlay_args<P: AsRef<Path>>(
1126
1140
// the rightmost on the command line is the bottom layer, and the
1127
1141
// leftmost is on the top). For more details see:
1128
1142
// https://docs.kernel.org/filesystems/overlayfs.html#multiple-lower-layers
1129
- if cfg ! ( feature = "legacy-mount-options" ) {
1130
- args. push_str ( "lowerdir=" ) ;
1143
+ if mount_options. lowerdir_append {
1131
1144
for path in layer_dirs. iter ( ) . rev ( ) {
1145
+ args. push_str ( "lowerdir+=" ) ;
1132
1146
args. push_str ( & path. as_ref ( ) . to_string_lossy ( ) ) ;
1133
- args. push ( ': ' ) ;
1147
+ args. push ( ', ' ) ;
1134
1148
}
1149
+ args. push_str ( "lowerdir+=" ) ;
1135
1150
} else {
1151
+ args. push_str ( "lowerdir=" ) ;
1136
1152
for path in layer_dirs. iter ( ) . rev ( ) {
1137
- args. push_str ( "lowerdir+=" ) ;
1138
1153
args. push_str ( & path. as_ref ( ) . to_string_lossy ( ) ) ;
1139
- args. push ( ', ' ) ;
1154
+ args. push ( ': ' ) ;
1140
1155
}
1141
- args. push_str ( "lowerdir+=" ) ;
1142
1156
}
1143
1157
args. push_str ( & rt. config . lower_dir . to_string_lossy ( ) ) ;
1144
1158
0 commit comments