github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/pkg/mountinfo/types.go (about) 1 // Copyright 2016 The rkt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package mountinfo 16 17 // Mount contains information about a single mountpoint entry 18 type Mount struct { 19 ID int 20 Parent int 21 Major int 22 Minor int 23 Root string 24 MountPoint string 25 Opts map[string]struct{} 26 } 27 28 // FilterFunc is a functional type which returns true if the given Mount should be filtered, else false. 29 type FilterFunc func(m *Mount) bool 30 31 // NeedsRemountPrivate checks if this mountPoint needs to be remounted 32 // as private, in order for children to be properly unmounted without 33 // leaking to parents. 34 func (m *Mount) NeedsRemountPrivate() bool { 35 for _, key := range []string{ 36 "shared", 37 "master", 38 } { 39 if _, needsRemount := m.Opts[key]; needsRemount { 40 return true 41 } 42 } 43 return false 44 } 45 46 // Mounts represents a sortable set of mountpoint entries. 47 // It implements sort.Interface according to unmount order (children first). 48 type Mounts []*Mount 49 50 // Filter returns a filtered copy of Mounts 51 func (ms Mounts) Filter(f FilterFunc) Mounts { 52 filtered := make([]*Mount, 0, len(ms)) 53 54 for _, m := range ms { 55 if f(m) { 56 filtered = append(filtered, m) 57 } 58 } 59 60 return Mounts(filtered) 61 } 62 63 // Less ensures that mounts are sorted in an order we can unmount; descendant before ancestor. 64 // The requirement of transitivity for Less has to be fulfilled otherwise the sort algorithm will fail. 65 func (ms Mounts) Less(i, j int) (result bool) { return ms.mountDepth(i) >= ms.mountDepth(j) } 66 67 func (ms Mounts) Len() int { return len(ms) } 68 69 func (ms Mounts) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] } 70 71 // mountDepth determines and returns the number of ancestors of the mount at index i 72 func (ms Mounts) mountDepth(i int) int { 73 ancestorCount := 0 74 current := ms[i] 75 for found := true; found; { 76 found = false 77 for _, mnt := range ms { 78 if mnt.ID == current.Parent { 79 ancestorCount++ 80 current = mnt 81 found = true 82 break 83 } 84 } 85 } 86 return ancestorCount 87 }