@@ -576,113 +576,94 @@ func validateGIDMappings(spec *rspec.Spec) error {
576576 return validateIDMappings (spec .Linux .GIDMappings , "/proc/self/gid_map" , "linux.gidMappings" )
577577}
578578
579- func mountMatch (configMount rspec.Mount , sysMount rspec.Mount ) error {
580- if filepath .Clean (configMount .Destination ) != sysMount .Destination {
581- return fmt .Errorf ("mount destination expected: %v, actual: %v" , configMount .Destination , sysMount .Destination )
579+ func mountMatch (configMount rspec.Mount , sysMount * mount.Info ) error {
580+ sys := rspec.Mount {
581+ Destination : sysMount .Mountpoint ,
582+ Type : sysMount .Fstype ,
583+ Source : sysMount .Source ,
582584 }
583585
584- if configMount .Type != sysMount . Type {
585- return fmt .Errorf ("mount %v type expected: %v, actual: %v" , configMount .Destination , configMount . Type , sysMount . Type )
586+ if filepath . Clean ( configMount .Destination ) != sys . Destination {
587+ return fmt .Errorf ("mount destination expected: %v, actual: %v" , configMount .Destination , sys . Destination )
586588 }
587589
588- if filepath .Clean (configMount .Source ) != sysMount .Source {
589- return fmt .Errorf ("mount %v source expected: %v, actual: %v" , configMount .Destination , configMount .Source , sysMount .Source )
590+ if configMount .Type != sys .Type {
591+ return fmt .Errorf ("mount %v type expected: %v, actual: %v" , configMount .Destination , configMount .Type , sys .Type )
592+ }
593+
594+ if filepath .Clean (configMount .Source ) != sys .Source {
595+ return fmt .Errorf ("mount %v source expected: %v, actual: %v" , configMount .Destination , configMount .Source , sys .Source )
590596 }
591597
592598 return nil
593599}
594600
595- func validateMountsExist (spec * rspec.Spec ) error {
601+ func validateMounts (spec * rspec.Spec ) error {
602+ if runtime .GOOS == "windows" {
603+ logrus .Warnf ("mounts validation not yet implemented for OS %q" , runtime .GOOS )
604+ return nil
605+ }
606+
596607 mountInfos , err := mount .GetMounts ()
597608 if err != nil {
598609 return err
599610 }
600611
601- mountsMap := make (map [string ][]rspec.Mount )
602- for _ , mountInfo := range mountInfos {
603- m := rspec.Mount {
604- Destination : mountInfo .Mountpoint ,
605- Type : mountInfo .Fstype ,
606- Source : mountInfo .Source ,
607- }
608- mountsMap [mountInfo .Mountpoint ] = append (mountsMap [mountInfo .Mountpoint ], m )
609- }
610-
611- for _ , configMount := range spec .Mounts {
612+ var mountErrs error
613+ var configSys = make (map [int ]int )
614+ var consumedSys = make (map [int ]bool )
615+ highestMatchedConfig := - 1
616+ var j = 0
617+ for i , configMount := range spec .Mounts {
612618 if configMount .Type == "bind" || configMount .Type == "rbind" {
613619 // TODO: add bind or rbind check.
614620 continue
615621 }
616622
617623 found := false
618- for _ , sysMount := range mountsMap [ filepath . Clean ( configMount . Destination ) ] {
624+ for k , sysMount := range mountInfos [ j : ] {
619625 if err := mountMatch (configMount , sysMount ); err == nil {
620626 found = true
627+ j += k + 1
628+ configSys [i ] = j - 1
629+ consumedSys [j - 1 ] = true
630+ if jMax , ok := configSys [highestMatchedConfig ]; ! ok || jMax < j - 1 {
631+ highestMatchedConfig = i
632+ }
621633 break
622634 }
623635 }
624636 if ! found {
625- return fmt .Errorf ("Expected mount %v does not exist" , configMount )
626- }
627- }
628-
629- return nil
630- }
631-
632- func validateMountsOrder (spec * rspec.Spec ) error {
633- if runtime .GOOS == "windows" {
634- logrus .Warnf ("mounts order validation not yet implemented for OS %q" , runtime .GOOS )
635- return nil
636- }
637-
638- mountInfos , err := mount .GetMounts ()
639- if err != nil {
640- return err
641- }
642-
643- type mountOrder struct {
644- Order int
645- Root string
646- Dest string
647- Source string
648- }
649- mountsMap := make (map [string ][]mountOrder )
650- for i , mountInfo := range mountInfos {
651- m := mountOrder {
652- Order : i ,
653- Root : mountInfo .Root ,
654- Dest : mountInfo .Mountpoint ,
655- Source : mountInfo .Source ,
656- }
657- mountsMap [mountInfo .Mountpoint ] = append (mountsMap [mountInfo .Mountpoint ], m )
658- }
659- current := - 1
660- for i , configMount := range spec .Mounts {
661- mounts := mountsMap [configMount .Destination ]
662- if len (mounts ) == 0 {
663- return fmt .Errorf ("Mounts[%d] %s is not mounted in order" , i , configMount .Destination )
664- }
665- for j , mount := range mounts {
666- source := mount .Source
667- for _ , option := range configMount .Options {
668- if option == "bind" || option == "rbind" {
669- source = mount .Root
670- break
637+ if j > 0 {
638+ for k , sysMount := range mountInfos [:j - 1 ] {
639+ if _ , ok := consumedSys [k ]; ok {
640+ continue
641+ }
642+ if err := mountMatch (configMount , sysMount ); err == nil {
643+ found = true
644+ configSys [i ] = k
645+ break
646+ }
671647 }
672648 }
673- if source == configMount .Source {
674- if current > mount .Order {
675- return fmt .Errorf ("Mounts[%d] %s is not mounted in order" , i , configMount .Destination )
676- }
677- current = mount .Order
678- // in order to deal with dup mount elements
679- mountsMap [configMount .Destination ] = append (mountsMap [configMount .Destination ][:j ], mountsMap [configMount .Destination ][j + 1 :]... )
680- break
649+ if found {
650+ mountErrs = multierror .Append (
651+ mountErrs ,
652+ fmt .Errorf (
653+ "mounts[%d] %v is system mount %d, while mounts[%d] %v is system mount %d" ,
654+ i ,
655+ configMount ,
656+ configSys [i ],
657+ highestMatchedConfig ,
658+ spec .Mounts [highestMatchedConfig ],
659+ configSys [highestMatchedConfig ]))
660+ } else {
661+ mountErrs = multierror .Append (mountErrs , fmt .Errorf ("mounts[%d] %v does not exist" , i , configMount ))
681662 }
682663 }
683664 }
684665
685- return nil
666+ return mountErrs
686667}
687668
688669func run (context * cli.Context ) error {
@@ -711,13 +692,9 @@ func run(context *cli.Context) error {
711692 description : "hostname" ,
712693 },
713694 {
714- test : validateMountsExist ,
695+ test : validateMounts ,
715696 description : "mounts" ,
716697 },
717- {
718- test : validateMountsOrder ,
719- description : "mounts order" ,
720- },
721698 }
722699
723700 linuxValidations := []validation {
0 commit comments