4
4
"bufio"
5
5
"os"
6
6
"path/filepath"
7
+ "slices"
7
8
"strings"
8
9
"syscall"
9
10
@@ -217,11 +218,11 @@ func IsFileSystemSupported(fsType string) (bool, error) {
217
218
// - int: The inode number of the matching mountpoint.
218
219
// - error: Any error encountered while reading the /proc/mounts file.
219
220
func SearchMountpointFromHost (fstype string , search string ) (string , int , error ) {
221
+ const mountRootIndex = 3
220
222
const mountpointIndex = 4
221
- const fsTypeIndex = 8
222
223
223
- mp := ""
224
- inode := 0
224
+ mp := "" // matched mountpoint search var
225
+ inode := 0 // matched mountpoint's inode
225
226
226
227
file , err := os .Open (procMounts )
227
228
if err != nil {
@@ -236,15 +237,26 @@ func SearchMountpointFromHost(fstype string, search string) (string, int, error)
236
237
scanner := bufio .NewScanner (file )
237
238
for scanner .Scan () {
238
239
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 ]
245
240
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 == "/" {
248
260
// Try to get the inode number of the current mountpoint.
249
261
var stat syscall.Stat_t
250
262
if err := syscall .Stat (mountpoint , & stat ); err != nil {
@@ -253,9 +265,12 @@ func SearchMountpointFromHost(fstype string, search string) (string, int, error)
253
265
}
254
266
currInode := int (stat .Ino )
255
267
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
257
272
if inode == 0 || currInode < inode ||
258
- (currInode == inode && len (mountpoint ) < len (mp )) {
273
+ (currInode == inode && len (mp ) < len (mountpoint )) {
259
274
mp = mountpoint
260
275
inode = currInode
261
276
}
0 commit comments