@@ -12,6 +12,7 @@ import (
1212 "github.com/containerd/containerd/mount"
1313 "github.com/containerd/containerd/pkg/userns"
1414 "github.com/docker/docker/daemon/graphdriver/overlayutils"
15+ "github.com/docker/docker/pkg/parsers/kernel"
1516 "github.com/docker/docker/pkg/system"
1617 "github.com/pkg/errors"
1718 "golang.org/x/sys/unix"
@@ -22,11 +23,23 @@ import (
2223// directory or the kernel enable CONFIG_OVERLAY_FS_REDIRECT_DIR.
2324// When these exist naive diff should be used.
2425//
25- // When running in a user namespace, returns errRunningInUserNS
26- // immediately.
26+ // When running in a user namespace before kernel 5.11, returns
27+ // errRunningInUserNS immediately. In kernel 5.11 and later, we
28+ // check support as usual with some user namespace differences.
2729func doesSupportNativeDiff (d string ) error {
30+ userxattr := false
2831 if userns .RunningInUserNS () {
29- return errors .New ("running in a user namespace" )
32+ if ! kernel .CheckKernelVersion (5 , 11 , 0 ) {
33+ return errors .New ("running in a user namespace" )
34+ }
35+
36+ needed , err := overlayutils .NeedsUserXAttr (d )
37+ if err != nil {
38+ return err
39+ }
40+ if needed {
41+ userxattr = true
42+ }
3043 }
3144
3245 td , err := os .MkdirTemp (d , "opaque-bug-check" )
@@ -60,11 +73,16 @@ func doesSupportNativeDiff(d string) error {
6073 }
6174
6275 // Mark l2/d as opaque
63- if err := system .Lsetxattr (filepath .Join (td , "l2" , "d" ), "trusted.overlay. opaque" , []byte ("y" ), 0 ); err != nil {
76+ if err := system .Lsetxattr (filepath .Join (td , "l2" , "d" ), overlayutils . GetOverlayXattr ( " opaque") , []byte ("y" ), 0 ); err != nil {
6477 return errors .Wrap (err , "failed to set opaque flag on middle layer" )
6578 }
6679
67- opts := fmt .Sprintf ("lowerdir=%s:%s,upperdir=%s,workdir=%s" , path .Join (td , "l2" ), path .Join (td , "l1" ), path .Join (td , "l3" ), path .Join (td , workDirName ))
80+ mountFlags := "lowerdir=%s:%s,upperdir=%s,workdir=%s"
81+ if userxattr {
82+ mountFlags = mountFlags + ",userxattr"
83+ }
84+
85+ opts := fmt .Sprintf (mountFlags , path .Join (td , "l2" ), path .Join (td , "l1" ), path .Join (td , "l3" ), path .Join (td , workDirName ))
6886 if err := unix .Mount ("overlay" , filepath .Join (td , mergedDirName ), "overlay" , 0 , opts ); err != nil {
6987 return errors .Wrap (err , "failed to mount overlay" )
7088 }
@@ -80,7 +98,7 @@ func doesSupportNativeDiff(d string) error {
8098 }
8199
82100 // Check l3/d does not have opaque flag
83- xattrOpaque , err := system .Lgetxattr (filepath .Join (td , "l3" , "d" ), "trusted.overlay. opaque" )
101+ xattrOpaque , err := system .Lgetxattr (filepath .Join (td , "l3" , "d" ), overlayutils . GetOverlayXattr ( " opaque") )
84102 if err != nil {
85103 return errors .Wrap (err , "failed to read opaque flag on upper layer" )
86104 }
@@ -97,7 +115,7 @@ func doesSupportNativeDiff(d string) error {
97115 return errors .Wrap (err , "failed to rename dir in merged directory" )
98116 }
99117 // get the xattr of "d2"
100- xattrRedirect , err := system .Lgetxattr (filepath .Join (td , "l3" , "d2" ), "trusted.overlay. redirect" )
118+ xattrRedirect , err := system .Lgetxattr (filepath .Join (td , "l3" , "d2" ), overlayutils . GetOverlayXattr ( " redirect") )
101119 if err != nil {
102120 return errors .Wrap (err , "failed to read redirect flag on upper layer" )
103121 }
0 commit comments