@@ -483,13 +483,36 @@ func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
483483 }()
484484
485485 workDir := path .Join (dir , "work" )
486- opts := fmt .Sprintf ("lowerdir=%s,upperdir=%s,workdir=%s" , string (lowers ), path .Join (id , "diff" ), path .Join (id , "work" ))
487- mountLabel = label .FormatMountLabel (opts , mountLabel )
488- if len (mountLabel ) > syscall .Getpagesize () {
489- return "" , fmt .Errorf ("cannot mount layer, mount label too large %d" , len (mountLabel ))
486+ splitLowers := strings .Split (string (lowers ), ":" )
487+ absLowers := make ([]string , len (splitLowers ))
488+ for i , s := range splitLowers {
489+ absLowers [i ] = path .Join (d .home , s )
490+ }
491+ opts := fmt .Sprintf ("lowerdir=%s,upperdir=%s,workdir=%s" , strings .Join (absLowers , ":" ), path .Join (dir , "diff" ), path .Join (dir , "work" ))
492+ mountData := label .FormatMountLabel (opts , mountLabel )
493+ mount := syscall .Mount
494+ mountTarget := mergedDir
495+
496+ pageSize := syscall .Getpagesize ()
497+
498+ // Use relative paths and mountFrom when the mount data has exceeded
499+ // the page size. The mount syscall fails if the mount data cannot
500+ // fit within a page and relative links make the mount data much
501+ // smaller at the expense of requiring a fork exec to chroot.
502+ if len (mountData ) > pageSize {
503+ opts = fmt .Sprintf ("lowerdir=%s,upperdir=%s,workdir=%s" , string (lowers ), path .Join (id , "diff" ), path .Join (id , "work" ))
504+ mountData = label .FormatMountLabel (opts , mountLabel )
505+ if len (mountData ) > pageSize {
506+ return "" , fmt .Errorf ("cannot mount layer, mount label too large %d" , len (mountData ))
507+ }
508+
509+ mount = func (source string , target string , mType string , flags uintptr , label string ) error {
510+ return mountFrom (d .home , source , target , mType , flags , label )
511+ }
512+ mountTarget = path .Join (id , "merged" )
490513 }
491514
492- if err := mountFrom ( d . home , "overlay" , path . Join ( id , "merged" ), "overlay" , mountLabel ); err != nil {
515+ if err := mount ( "overlay" , mountTarget , "overlay" , 0 , mountData ); err != nil {
493516 return "" , fmt .Errorf ("error creating overlay mount to %s: %v" , mergedDir , err )
494517 }
495518
0 commit comments