Skip to content

Commit 3abb7af

Browse files
author
Ma Shimiao
committed
runtimetest: add mounts order validation
Signed-off-by: Ma Shimiao <[email protected]>
1 parent 9e0e42d commit 3abb7af

File tree

1 file changed

+72
-12
lines changed

1 file changed

+72
-12
lines changed

cmd/runtimetest/main.go

+72-12
Original file line numberDiff line numberDiff line change
@@ -577,17 +577,17 @@ func validateGIDMappings(spec *rspec.Spec) error {
577577
return validateIDMappings(spec.Linux.GIDMappings, "/proc/self/gid_map", "linux.gidMappings")
578578
}
579579

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)
583583
}
584584

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)
587587
}
588588

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)
591591
}
592592

593593
return nil
@@ -609,21 +609,77 @@ func validateMountsExist(spec *rspec.Spec) error {
609609
mountsMap[mountInfo.Mountpoint] = append(mountsMap[mountInfo.Mountpoint], m)
610610
}
611611

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" {
614614
// TODO: add bind or rbind check.
615615
continue
616616
}
617617

618618
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 {
621621
found = true
622622
break
623623
}
624624
}
625625
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+
}
627683
}
628684
}
629685

@@ -659,6 +715,10 @@ func run(context *cli.Context) error {
659715
test: validateMountsExist,
660716
description: "mounts",
661717
},
718+
{
719+
test: validateMountsOrder,
720+
description: "mounts order",
721+
},
662722
}
663723

664724
linuxValidations := []validation{

0 commit comments

Comments
 (0)