/
deleted_mount.go
131 lines (113 loc) · 2.72 KB
/
deleted_mount.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// +build linux
package mount
import (
"fmt"
"regexp"
"strings"
"github.com/sirupsen/logrus"
)
const (
// AllDevices designates all devices that show up as source.
AllDevices = "AllDevices"
)
// deletedMounter loads mounts that show up as deleted in the mount table.
type deletedMounter struct {
*deviceMounter
}
// NewDeletedMounter returns a new deletedMounter
func NewDeletedMounter(
rootSubstring string,
mountImpl MountImpl,
) (*deletedMounter, error) {
devMounter, err := NewDeviceMounter([]*regexp.Regexp{regexp.MustCompile("/dev/")}, mountImpl, nil, "")
if err != nil {
return nil, err
}
deletedMounts := make(DeviceMap)
for k, v := range devMounter.mounts {
if matchDeleted(rootSubstring, k) {
deletedMounts[k] = v
} else {
for _, p := range v.Mountpoint {
if matchDeleted(rootSubstring, p.Root) {
addMountpoint(deletedMounts, k, p)
}
}
}
}
devMounter.mounts = deletedMounts
return &deletedMounter{deviceMounter: devMounter}, nil
}
func matchDeleted(rootSubstring, source string) bool {
return strings.Contains(source, "deleted") &&
(len(rootSubstring) == 0 || strings.Contains(source, rootSubstring))
}
func addMountpoint(dm DeviceMap, root string, mp *PathInfo) {
info, ok := dm[root]
if !ok {
info = &Info{
Device: root,
Mountpoint: make([]*PathInfo, 0),
}
dm[root] = info
}
info.Mountpoint = append(info.Mountpoint, mp)
}
// Unmount all deleted mounts.
func (m *deletedMounter) Unmount(
sourcePath string,
path string,
flags int,
timeout int,
opts map[string]string,
) error {
if sourcePath != AllDevices {
return fmt.Errorf("DeletedMounter accepts only %v as sourcePath",
AllDevices)
}
m.Lock()
defer m.Unlock()
failedUnmounts := make(DeviceMap)
for k, v := range m.mounts {
for _, p := range v.Mountpoint {
logrus.Warnf("Unmounting deleted mount path %v->%v", k, p)
if err := m.mountImpl.Unmount(p.Path, flags, timeout); err != nil {
logrus.Warnf("Failed to unmount mount path %v->%v", k, p)
addMountpoint(failedUnmounts, k, p)
}
}
}
m.mounts = failedUnmounts
if len(m.mounts) > 0 {
return fmt.Errorf("Not all paths could be unmounted")
}
return nil
}
func (m *deletedMounter) Mounts(sourcePath string) []string {
m.Lock()
defer m.Unlock()
if sourcePath != AllDevices {
logrus.Warnf("DeletedMounter accepts only %v as sourcePath",
AllDevices)
return nil
}
paths := make([]string, 0)
for _, v := range m.mounts {
for _, p := range v.Mountpoint {
paths = append(paths, p.Path)
}
}
return paths
}
func (m *deletedMounter) Mount(
minor int,
device string,
path string,
fs string,
flags uintptr,
data string,
timeout int,
opts map[string]string,
) error {
return fmt.Errorf("deletedMounter.Mount is not supported")
}