Skip to content

Commit bddc043

Browse files
author
Zhou Hao
authored
Merge pull request #444 from Mashimiao/mount-order
runtimetest: add mounts order validation
2 parents e285bae + 3abb7af commit bddc043

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
@@ -576,17 +576,17 @@ func validateGIDMappings(spec *rspec.Spec) error {
576576
return validateIDMappings(spec.Linux.GIDMappings, "/proc/self/gid_map", "linux.gidMappings")
577577
}
578578

579-
func mountMatch(specMount rspec.Mount, sysMount rspec.Mount) error {
580-
if filepath.Clean(specMount.Destination) != sysMount.Destination {
581-
return fmt.Errorf("mount destination expected: %v, actual: %v", specMount.Destination, sysMount.Destination)
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)
582582
}
583583

584-
if specMount.Type != sysMount.Type {
585-
return fmt.Errorf("mount %v type expected: %v, actual: %v", specMount.Destination, specMount.Type, sysMount.Type)
584+
if configMount.Type != sysMount.Type {
585+
return fmt.Errorf("mount %v type expected: %v, actual: %v", configMount.Destination, configMount.Type, sysMount.Type)
586586
}
587587

588-
if filepath.Clean(specMount.Source) != sysMount.Source {
589-
return fmt.Errorf("mount %v source expected: %v, actual: %v", specMount.Destination, specMount.Source, sysMount.Source)
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)
590590
}
591591

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

611-
for _, specMount := range spec.Mounts {
612-
if specMount.Type == "bind" || specMount.Type == "rbind" {
611+
for _, configMount := range spec.Mounts {
612+
if configMount.Type == "bind" || configMount.Type == "rbind" {
613613
// TODO: add bind or rbind check.
614614
continue
615615
}
616616

617617
found := false
618-
for _, sysMount := range mountsMap[filepath.Clean(specMount.Destination)] {
619-
if err := mountMatch(specMount, sysMount); err == nil {
618+
for _, sysMount := range mountsMap[filepath.Clean(configMount.Destination)] {
619+
if err := mountMatch(configMount, sysMount); err == nil {
620620
found = true
621621
break
622622
}
623623
}
624624
if !found {
625-
return fmt.Errorf("Expected mount %v does not exist", specMount)
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
671+
}
672+
}
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
681+
}
626682
}
627683
}
628684

@@ -658,6 +714,10 @@ func run(context *cli.Context) error {
658714
test: validateMountsExist,
659715
description: "mounts",
660716
},
717+
{
718+
test: validateMountsOrder,
719+
description: "mounts order",
720+
},
661721
}
662722

663723
linuxValidations := []validation{

0 commit comments

Comments
 (0)