Skip to content

Commit 60ac70d

Browse files
fix(mount): apply to shortest mount root
1 parent 604c391 commit 60ac70d

File tree

1 file changed

+28
-13
lines changed

1 file changed

+28
-13
lines changed

pkg/mount/mount.go

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bufio"
55
"os"
66
"path/filepath"
7+
"slices"
78
"strings"
89
"syscall"
910

@@ -217,11 +218,11 @@ func IsFileSystemSupported(fsType string) (bool, error) {
217218
// - int: The inode number of the matching mountpoint.
218219
// - error: Any error encountered while reading the /proc/mounts file.
219220
func SearchMountpointFromHost(fstype string, search string) (string, int, error) {
221+
const mountRootIndex = 3
220222
const mountpointIndex = 4
221-
const fsTypeIndex = 8
222223

223-
mp := ""
224-
inode := 0
224+
mp := "" // matched mountpoint search var
225+
inode := 0 // matched mountpoint's inode
225226

226227
file, err := os.Open(procMounts)
227228
if err != nil {
@@ -236,15 +237,26 @@ func SearchMountpointFromHost(fstype string, search string) (string, int, error)
236237
scanner := bufio.NewScanner(file)
237238
for scanner.Scan() {
238239
line := strings.Split(scanner.Text(), " ")
239-
if len(line) <= fsTypeIndex {
240-
continue // Skip lines that do not have enough fields
241-
}
242-
243-
mountpoint := line[mountpointIndex]
244-
currFstype := line[fsTypeIndex]
245240

246-
// Check if the current line matches the desired filesystem type and contains the search string.
247-
if fstype == currFstype && strings.Contains(mountpoint, search) {
241+
// fstype field is located right after "-"
242+
// before - there are optional fields, which makes the location of
243+
// the fstype field indeterminate
244+
sepIndex := slices.Index(line, "-")
245+
fsTypeIndex := sepIndex + 1
246+
247+
root := line[mountRootIndex] // current search mountpoint root
248+
mountpoint := line[mountpointIndex] // current search mountpoint path
249+
currFstype := line[fsTypeIndex] // current search mountpoint fs type
250+
251+
// First check for the following 3 conditions:
252+
// 1. The fs type is the one we search for
253+
// 2. The mountpoint contains the path we are searching
254+
// 3. The root path in the mounted filesystem is that of the host.
255+
// This means, that the root of the mounted filesystem is /.
256+
// For example, if we are searching for a mountpoint with cpuset we want
257+
// to be sure that it is not actually <some_other_dir>/.../.../...cpuset,
258+
// but strictly originating in the root fs.
259+
if fstype == currFstype && strings.Contains(mountpoint, search) && root == "/" {
248260
// Try to get the inode number of the current mountpoint.
249261
var stat syscall.Stat_t
250262
if err := syscall.Stat(mountpoint, &stat); err != nil {
@@ -253,9 +265,12 @@ func SearchMountpointFromHost(fstype string, search string) (string, int, error)
253265
}
254266
currInode := int(stat.Ino)
255267

256-
// Update the result if this is the first match or if the current mountpoint is older or shorter in path length.
268+
// Update the result if either apply:
269+
// 1. this is the first match
270+
// 2. the current mountpoint inode is lower than the currently matching mountpoint
271+
// 2. the current mountpoint shares an inode but its root has a shorter path
257272
if inode == 0 || currInode < inode ||
258-
(currInode == inode && len(mountpoint) < len(mp)) {
273+
(currInode == inode && len(mp) < len(mountpoint)) {
259274
mp = mountpoint
260275
inode = currInode
261276
}

0 commit comments

Comments
 (0)