@@ -577,17 +577,17 @@ func validateGIDMappings(spec *rspec.Spec) error {
577
577
return validateIDMappings (spec .Linux .GIDMappings , "/proc/self/gid_map" , "linux.gidMappings" )
578
578
}
579
579
580
- func mountMatch (specMount rspec.Mount , sysMount rspec.Mount ) error {
581
- if filepath .Clean (specMount .Destination ) != sysMount .Destination {
582
- return fmt .Errorf ("mount destination expected: %v, actual: %v" , specMount .Destination , sysMount .Destination )
580
+ func mountMatch (configMount rspec.Mount , sysMount rspec.Mount ) error {
581
+ if filepath .Clean (configMount .Destination ) != sysMount .Destination {
582
+ return fmt .Errorf ("mount destination expected: %v, actual: %v" , configMount .Destination , sysMount .Destination )
583
583
}
584
584
585
- if specMount .Type != sysMount .Type {
586
- return fmt .Errorf ("mount %v type expected: %v, actual: %v" , specMount .Destination , specMount .Type , sysMount .Type )
585
+ if configMount .Type != sysMount .Type {
586
+ return fmt .Errorf ("mount %v type expected: %v, actual: %v" , configMount .Destination , configMount .Type , sysMount .Type )
587
587
}
588
588
589
- if filepath .Clean (specMount .Source ) != sysMount .Source {
590
- return fmt .Errorf ("mount %v source expected: %v, actual: %v" , specMount .Destination , specMount .Source , sysMount .Source )
589
+ if filepath .Clean (configMount .Source ) != sysMount .Source {
590
+ return fmt .Errorf ("mount %v source expected: %v, actual: %v" , configMount .Destination , configMount .Source , sysMount .Source )
591
591
}
592
592
593
593
return nil
@@ -609,21 +609,77 @@ func validateMountsExist(spec *rspec.Spec) error {
609
609
mountsMap [mountInfo .Mountpoint ] = append (mountsMap [mountInfo .Mountpoint ], m )
610
610
}
611
611
612
- for _ , specMount := range spec .Mounts {
613
- if specMount .Type == "bind" || specMount .Type == "rbind" {
612
+ for _ , configMount := range spec .Mounts {
613
+ if configMount .Type == "bind" || configMount .Type == "rbind" {
614
614
// TODO: add bind or rbind check.
615
615
continue
616
616
}
617
617
618
618
found := false
619
- for _ , sysMount := range mountsMap [filepath .Clean (specMount .Destination )] {
620
- if err := mountMatch (specMount , sysMount ); err == nil {
619
+ for _ , sysMount := range mountsMap [filepath .Clean (configMount .Destination )] {
620
+ if err := mountMatch (configMount , sysMount ); err == nil {
621
621
found = true
622
622
break
623
623
}
624
624
}
625
625
if ! found {
626
- return fmt .Errorf ("Expected mount %v does not exist" , specMount )
626
+ return fmt .Errorf ("Expected mount %v does not exist" , configMount )
627
+ }
628
+ }
629
+
630
+ return nil
631
+ }
632
+
633
+ func validateMountsOrder (spec * rspec.Spec ) error {
634
+ if runtime .GOOS == "windows" {
635
+ logrus .Warnf ("mounts order validation not yet implemented for OS %q" , runtime .GOOS )
636
+ return nil
637
+ }
638
+
639
+ mountInfos , err := mount .GetMounts ()
640
+ if err != nil {
641
+ return err
642
+ }
643
+
644
+ type mountOrder struct {
645
+ Order int
646
+ Root string
647
+ Dest string
648
+ Source string
649
+ }
650
+ mountsMap := make (map [string ][]mountOrder )
651
+ for i , mountInfo := range mountInfos {
652
+ m := mountOrder {
653
+ Order : i ,
654
+ Root : mountInfo .Root ,
655
+ Dest : mountInfo .Mountpoint ,
656
+ Source : mountInfo .Source ,
657
+ }
658
+ mountsMap [mountInfo .Mountpoint ] = append (mountsMap [mountInfo .Mountpoint ], m )
659
+ }
660
+ current := - 1
661
+ for i , configMount := range spec .Mounts {
662
+ mounts := mountsMap [configMount .Destination ]
663
+ if len (mounts ) == 0 {
664
+ return fmt .Errorf ("Mounts[%d] %s is not mounted in order" , i , configMount .Destination )
665
+ }
666
+ for j , mount := range mounts {
667
+ source := mount .Source
668
+ for _ , option := range configMount .Options {
669
+ if option == "bind" || option == "rbind" {
670
+ source = mount .Root
671
+ break
672
+ }
673
+ }
674
+ if source == configMount .Source {
675
+ if current > mount .Order {
676
+ return fmt .Errorf ("Mounts[%d] %s is not mounted in order" , i , configMount .Destination )
677
+ }
678
+ current = mount .Order
679
+ // in order to deal with dup mount elements
680
+ mountsMap [configMount .Destination ] = append (mountsMap [configMount .Destination ][:j ], mountsMap [configMount .Destination ][j + 1 :]... )
681
+ break
682
+ }
627
683
}
628
684
}
629
685
@@ -659,6 +715,10 @@ func run(context *cli.Context) error {
659
715
test : validateMountsExist ,
660
716
description : "mounts" ,
661
717
},
718
+ {
719
+ test : validateMountsOrder ,
720
+ description : "mounts order" ,
721
+ },
662
722
}
663
723
664
724
linuxValidations := []validation {
0 commit comments