tetragon

Форк
0
/
mountinfo.go 
143 строки · 3.9 Кб
1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright Authors of Cilium
3

4
package mountinfo
5

6
import (
7
	"bufio"
8
	"fmt"
9
	"io"
10
	"os"
11
	"strconv"
12
	"strings"
13
)
14

15
const (
16
	// FilesystemType names for filesystem which are used in /proc/pid/mountinfo
17
	FilesystemTypeBPFFS   = "bpf"
18
	FilesystemTypeCgroup2 = "cgroup2"
19
	FilesystemTypeDebugFS = "debugfs"
20

21
	mountInfoFilepath = "/proc/self/mountinfo"
22
)
23

24
// MountInfo is a struct representing information from /proc/pid/mountinfo. More
25
// information about file syntax:
26
// https://www.kernel.org/doc/Documentation/filesystems/proc.txt
27
type MountInfo struct {
28
	MountID        int64
29
	ParentID       int64
30
	StDev          string
31
	Root           string
32
	MountPoint     string
33
	MountOptions   string
34
	OptionalFields []string
35
	FilesystemType string
36
	MountSource    string
37
	SuperOptions   string
38
}
39

40
// parseMountInfoFile returns a slice of *MountInfo with information parsed from
41
// the given reader
42
func parseMountInfoFile(r io.Reader) ([]*MountInfo, error) {
43
	var result []*MountInfo
44

45
	scanner := bufio.NewScanner(r)
46
	scanner.Split(bufio.ScanLines)
47

48
	for scanner.Scan() {
49
		mountInfoRaw := scanner.Text()
50

51
		// Optional fields (which are on the 7th position) are separated
52
		// from the rest of fields by "-" character. The number of
53
		// optional fields can be greater or equal to 1.
54
		mountInfoSeparated := strings.Split(mountInfoRaw, " - ")
55
		if len(mountInfoSeparated) != 2 {
56
			return nil, fmt.Errorf("invalid mountinfo entry which has more that one '-' separator: %s", mountInfoRaw)
57
		}
58

59
		// Extract fields from both sides of mountinfo
60
		mountInfoLeft := strings.Split(strings.TrimSpace(mountInfoSeparated[0]), " ")
61
		mountInfoRight := strings.Split(strings.TrimSpace(mountInfoSeparated[1]), " ")
62

63
		// Before '-' separator there should be 6 fields and unknown
64
		// number of optional fields
65
		if len(mountInfoLeft) < 6 {
66
			return nil, fmt.Errorf("invalid mountinfo entry: %s", mountInfoRaw)
67
		}
68
		// After '-' separator there should be 3 fields
69
		if len(mountInfoRight) != 3 {
70
			return nil, fmt.Errorf("invalid mountinfo entry: %s", mountInfoRaw)
71
		}
72

73
		mountID, err := strconv.ParseInt(mountInfoLeft[0], 10, 64)
74
		if err != nil {
75
			return nil, err
76
		}
77

78
		parentID, err := strconv.ParseInt(mountInfoLeft[1], 10, 64)
79
		if err != nil {
80
			return nil, err
81
		}
82

83
		// Extract optional fields, which start from 7th position
84
		var optionalFields []string
85
		for i := 6; i < len(mountInfoLeft); i++ {
86
			optionalFields = append(optionalFields, mountInfoLeft[i])
87
		}
88

89
		result = append(result, &MountInfo{
90
			MountID:        mountID,
91
			ParentID:       parentID,
92
			StDev:          mountInfoLeft[2],
93
			Root:           mountInfoLeft[3],
94
			MountPoint:     mountInfoLeft[4],
95
			MountOptions:   mountInfoLeft[5],
96
			OptionalFields: optionalFields,
97
			FilesystemType: mountInfoRight[0],
98
			MountSource:    mountInfoRight[1],
99
			SuperOptions:   mountInfoRight[2],
100
		})
101
	}
102

103
	return result, nil
104
}
105

106
// GetMountInfo returns a slice of *MountInfo with information parsed from
107
// /proc/self/mountinfo
108
func GetMountInfo() ([]*MountInfo, error) {
109
	fMounts, err := os.Open(mountInfoFilepath)
110
	if err != nil {
111
		return nil, fmt.Errorf("failed to open mount information at %s: %s", mountInfoFilepath, err)
112
	}
113
	defer fMounts.Close()
114

115
	return parseMountInfoFile(fMounts)
116
}
117

118
func isMountFS(mountInfos []*MountInfo, mntType string, mapRoot string) (bool, bool) {
119
	var mapRootMountInfo *MountInfo
120

121
	for _, mountInfo := range mountInfos {
122
		if mountInfo.MountPoint == mapRoot {
123
			mapRootMountInfo = mountInfo
124
			break
125
		}
126
	}
127

128
	if mapRootMountInfo == nil {
129
		return false, false
130
	}
131

132
	if mapRootMountInfo.FilesystemType == mntType {
133
		return true, true
134
	}
135
	return true, false
136
}
137

138
// IsMountFS returns two boolean values:checks whether the current mapRoot:
139
// - whether the current mapRoot has any mount
140
// - whether that mount's filesystem is of type mntType
141
func IsMountFS(infos []*MountInfo, mntType string, mapRoot string) (bool, bool) {
142
	return isMountFS(infos, mntType, mapRoot)
143
}
144

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.