Skip to content

Commit 06bd267

Browse files
author
Zhou Hao
authored
Merge pull request #456 from wking/combine-mount-order-and-existence-checks
cmd/runtimetest/main.go: Unify validateMountsExist and validateMountsOrder
2 parents d6e5f82 + bcb5379 commit 06bd267

File tree

1 file changed

+54
-80
lines changed

1 file changed

+54
-80
lines changed

Diff for: cmd/runtimetest/main.go

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

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)
580+
func mountMatch(configMount rspec.Mount, sysMount *mount.Info) error {
581+
sys := rspec.Mount{
582+
Destination: sysMount.Mountpoint,
583+
Type: sysMount.Fstype,
584+
Source: sysMount.Source,
583585
}
584586

585-
if configMount.Type != sysMount.Type {
586-
return fmt.Errorf("mount %v type expected: %v, actual: %v", configMount.Destination, configMount.Type, sysMount.Type)
587+
if filepath.Clean(configMount.Destination) != sys.Destination {
588+
return fmt.Errorf("mount destination expected: %v, actual: %v", configMount.Destination, sys.Destination)
587589
}
588590

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+
if configMount.Type != sys.Type {
592+
return fmt.Errorf("mount %v type expected: %v, actual: %v", configMount.Destination, configMount.Type, sys.Type)
593+
}
594+
595+
if filepath.Clean(configMount.Source) != sys.Source {
596+
return fmt.Errorf("mount %v source expected: %v, actual: %v", configMount.Destination, configMount.Source, sys.Source)
591597
}
592598

593599
return nil
594600
}
595601

596-
func validateMountsExist(spec *rspec.Spec) error {
602+
func validateMounts(spec *rspec.Spec) error {
603+
if runtime.GOOS == "windows" {
604+
logrus.Warnf("mounts validation not yet implemented for OS %q", runtime.GOOS)
605+
return nil
606+
}
607+
597608
mountInfos, err := mount.GetMounts()
598609
if err != nil {
599610
return err
600611
}
601612

602-
mountsMap := make(map[string][]rspec.Mount)
603-
for _, mountInfo := range mountInfos {
604-
m := rspec.Mount{
605-
Destination: mountInfo.Mountpoint,
606-
Type: mountInfo.Fstype,
607-
Source: mountInfo.Source,
608-
}
609-
mountsMap[mountInfo.Mountpoint] = append(mountsMap[mountInfo.Mountpoint], m)
610-
}
611-
612-
for _, configMount := range spec.Mounts {
613+
var mountErrs error
614+
var consumedSys = make(map[int]bool)
615+
highestMatchedConfig := -1
616+
highestMatchedSystem := -1
617+
var j = 0
618+
for i, configMount := range spec.Mounts {
613619
if configMount.Type == "bind" || configMount.Type == "rbind" {
614620
// TODO: add bind or rbind check.
615621
continue
616622
}
617623

618624
found := false
619-
for _, sysMount := range mountsMap[filepath.Clean(configMount.Destination)] {
625+
for k, sysMount := range mountInfos[j:] {
620626
if err := mountMatch(configMount, sysMount); err == nil {
621627
found = true
628+
j += k + 1
629+
consumedSys[j-1] = true
630+
if j > highestMatchedSystem {
631+
highestMatchedSystem = j - 1
632+
highestMatchedConfig = i
633+
}
622634
break
623635
}
624636
}
625637
if !found {
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
638+
if j > 0 {
639+
for k, sysMount := range mountInfos[:j-1] {
640+
if _, ok := consumedSys[k]; ok {
641+
continue
642+
}
643+
if err := mountMatch(configMount, sysMount); err == nil {
644+
found = true
645+
break
646+
}
672647
}
673648
}
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
649+
if found {
650+
mountErrs = multierror.Append(
651+
mountErrs,
652+
fmt.Errorf(
653+
"mounts[%d] %v mounted before mounts[%d] %v",
654+
i,
655+
configMount,
656+
highestMatchedConfig,
657+
spec.Mounts[highestMatchedConfig]))
658+
} else {
659+
mountErrs = multierror.Append(mountErrs, fmt.Errorf("mounts[%d] %v does not exist", i, configMount))
682660
}
683661
}
684662
}
685663

686-
return nil
664+
return mountErrs
687665
}
688666

689667
func run(context *cli.Context) error {
@@ -712,13 +690,9 @@ func run(context *cli.Context) error {
712690
description: "hostname",
713691
},
714692
{
715-
test: validateMountsExist,
693+
test: validateMounts,
716694
description: "mounts",
717695
},
718-
{
719-
test: validateMountsOrder,
720-
description: "mounts order",
721-
},
722696
}
723697

724698
linuxValidations := []validation{

0 commit comments

Comments
 (0)