Skip to content

Sort mounts with stable sort #240

Closed
Closed
@Epsilon314

Description

@Epsilon314

We got an unexpected change of the order of mounts after introducing cdi (indirectly through updating Nvidia container toolkit), which in specific cases lead to failed dind container creation. The change of mounts order is related to the way sortMounts works, as referred below:
https://github.com/cncf-tags/container-device-interface/blob/main/pkg/cdi/container-edits.go#L358

// sortMounts sorts the mounts in the given OCI Spec.
func sortMounts(specgen *ocigen.Generator) {
	mounts := specgen.Mounts()
	specgen.ClearMounts()
	sort.Sort(orderedMounts(mounts))
	specgen.Config.Mounts = mounts
}

// orderedMounts defines how to sort an OCI Spec Mount slice.
// This is the almost the same implementation sa used by CRI-O and Docker,
// with a minor tweak for stable sorting order (easier to test):
//
//	https://github.com/moby/moby/blob/17.05.x/daemon/volumes.go#L26
type orderedMounts []oci.Mount

// Len returns the number of mounts. Used in sorting.
func (m orderedMounts) Len() int {
	return len(m)
}

// Less returns true if the number of parts (a/b/c would be 3 parts) in the
// mount indexed by parameter 1 is less than that of the mount indexed by
// parameter 2. Used in sorting.
func (m orderedMounts) Less(i, j int) bool {
	ip, jp := m.parts(i), m.parts(j)
	if ip < jp {
		return true
	}
	if jp < ip {
		return false
	}
	return m[i].Destination < m[j].Destination
}
  1. Go1.19 changes sort.Sort from stable to unstable, and we can use sort.Stable instead (w.r.t https://github.com/containerd/containerd/blob/main/internal/cri/opts/spec_linux_opts.go#L68);
  2. We can change orderedMounts.Less method to only compare parts, so that the mount order submitted by container spec yaml will be kept, in case it matters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions