Skip to content

Commit 9479c29

Browse files
authored
Add FS handler for mountinfo (#757)
Add FS function handlers for parsing `mountinfo` data. Signed-off-by: SuperQ <superq@gmail.com>
1 parent 25803af commit 9479c29

File tree

3 files changed

+217
-0
lines changed

3 files changed

+217
-0
lines changed

mountinfo.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,21 @@ func GetProcMounts(pid int) ([]*MountInfo, error) {
177177
}
178178
return parseMountInfo(data)
179179
}
180+
181+
// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`.
182+
func (fs FS) GetMounts() ([]*MountInfo, error) {
183+
data, err := util.ReadFileNoStat(fs.proc.Path("self/mountinfo"))
184+
if err != nil {
185+
return nil, err
186+
}
187+
return parseMountInfo(data)
188+
}
189+
190+
// GetProcMounts retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.
191+
func (fs FS) GetProcMounts(pid int) ([]*MountInfo, error) {
192+
data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid)))
193+
if err != nil {
194+
return nil, err
195+
}
196+
return parseMountInfo(data)
197+
}

mountinfo_test.go

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ package procfs
1515
import (
1616
"reflect"
1717
"testing"
18+
19+
"github.com/google/go-cmp/cmp"
1820
)
1921

2022
func TestMountInfo(t *testing.T) {
@@ -182,3 +184,188 @@ func TestMountInfo(t *testing.T) {
182184
}
183185
}
184186
}
187+
188+
func TestFSMountInfo(t *testing.T) {
189+
fs, err := NewFS(procTestFixtures)
190+
if err != nil {
191+
t.Fatalf("failed to open procfs: %v", err)
192+
}
193+
194+
want := []*MountInfo{
195+
{
196+
MountID: 1,
197+
ParentID: 1,
198+
MajorMinorVer: "0:5",
199+
Root: "/",
200+
Options: map[string]string{"/root": ""},
201+
OptionalFields: map[string]string{"shared": "8"},
202+
FSType: "rootfs",
203+
Source: "rootfs",
204+
SuperOptions: map[string]string{"rw": ""},
205+
},
206+
{
207+
MountID: 16,
208+
ParentID: 21,
209+
MajorMinorVer: "0:16",
210+
Root: "/",
211+
MountPoint: "/sys",
212+
Options: map[string]string{"nodev": "", "noexec": "", "nosuid": "", "relatime": "", "rw": ""},
213+
OptionalFields: map[string]string{"shared": "7"},
214+
FSType: "sysfs",
215+
Source: "sysfs",
216+
SuperOptions: map[string]string{"rw": ""},
217+
},
218+
{
219+
MountID: 17,
220+
ParentID: 21,
221+
MajorMinorVer: "0:4",
222+
Root: "/",
223+
MountPoint: "/proc",
224+
Options: map[string]string{"nodev": "", "noexec": "", "nosuid": "", "relatime": "", "rw": ""},
225+
OptionalFields: map[string]string{"shared": "12"},
226+
FSType: "proc",
227+
Source: "proc",
228+
SuperOptions: map[string]string{"rw": ""},
229+
},
230+
{
231+
MountID: 21,
232+
MajorMinorVer: "8:1",
233+
Root: "/",
234+
MountPoint: "/",
235+
Options: map[string]string{"relatime": "", "rw": ""},
236+
OptionalFields: map[string]string{"shared": "1"},
237+
FSType: "ext4",
238+
Source: "/dev/sda1",
239+
SuperOptions: map[string]string{"data": "ordered", "errors": "remount-ro", "rw": ""},
240+
},
241+
{
242+
MountID: 194,
243+
ParentID: 21,
244+
MajorMinorVer: "0:42",
245+
Root: "/",
246+
MountPoint: "/mnt/nfs/test",
247+
Options: map[string]string{"rw": ""},
248+
OptionalFields: map[string]string{"shared": "144"},
249+
FSType: "nfs4",
250+
Source: "192.168.1.1:/srv/test",
251+
SuperOptions: map[string]string{
252+
"acdirmax": "60",
253+
"acdirmin": "30",
254+
"acregmax": "60",
255+
"acregmin": "3",
256+
"addr": "192.168.1.1",
257+
"clientaddr": "192.168.1.5",
258+
"hard": "",
259+
"local_lock": "none",
260+
"namlen": "255",
261+
"port": "0",
262+
"proto": "tcp",
263+
"retrans": "2",
264+
"rsize": "1048576",
265+
"rw": "",
266+
"sec": "sys",
267+
"timeo": "600",
268+
"vers": "4.0",
269+
"wsize": "1048576",
270+
},
271+
},
272+
{
273+
MountID: 177,
274+
ParentID: 21,
275+
MajorMinorVer: "0:42",
276+
Root: "/",
277+
MountPoint: "/mnt/nfs/test",
278+
Options: map[string]string{"rw": ""},
279+
OptionalFields: map[string]string{"shared": "130"},
280+
FSType: "nfs4",
281+
Source: "192.168.1.1:/srv/test",
282+
SuperOptions: map[string]string{
283+
"acdirmax": "60",
284+
"acdirmin": "30",
285+
"acregmax": "60",
286+
"acregmin": "3",
287+
"addr": "192.168.1.1",
288+
"clientaddr": "192.168.1.5",
289+
"hard": "",
290+
"local_lock": "none",
291+
"namlen": "255",
292+
"port": "0",
293+
"proto": "tcp",
294+
"retrans": "2",
295+
"rsize": "1048576",
296+
"rw": "",
297+
"sec": "sys",
298+
"timeo": "600",
299+
"vers": "4.0",
300+
"wsize": "1048576",
301+
},
302+
},
303+
{
304+
MountID: 1398,
305+
ParentID: 798,
306+
MajorMinorVer: "0:44",
307+
Root: "/",
308+
MountPoint: "/mnt/nfs/test",
309+
Options: map[string]string{"relatime": "", "rw": ""},
310+
OptionalFields: map[string]string{"shared": "1154"},
311+
FSType: "nfs",
312+
Source: "192.168.1.1:/srv/test",
313+
SuperOptions: map[string]string{
314+
"addr": "192.168.1.1",
315+
"hard": "",
316+
"local_lock": "none",
317+
"mountaddr": "192.168.1.1",
318+
"mountport": "49602",
319+
"mountproto": "udp",
320+
"mountvers": "3",
321+
"namlen": "255",
322+
"proto": "udp",
323+
"retrans": "3",
324+
"rsize": "32768",
325+
"rw": "",
326+
"sec": "sys",
327+
"timeo": "11",
328+
"vers": "3",
329+
"wsize": "32768",
330+
},
331+
},
332+
{
333+
MountID: 1128,
334+
ParentID: 67,
335+
MajorMinorVer: "253:0",
336+
Root: "/var/lib/containers/storage/overlay",
337+
MountPoint: "/var/lib/containers/storage/overlay",
338+
Options: map[string]string{"relatime": "", "rw": ""},
339+
OptionalFields: map[string]string{},
340+
FSType: "xfs",
341+
Source: "/dev/mapper/rhel-root",
342+
SuperOptions: map[string]string{
343+
"attr2": "",
344+
"inode64": "",
345+
"logbsize": "32k",
346+
"logbufs": "8",
347+
"noquota": "",
348+
"rw": "",
349+
"seclabel": "",
350+
},
351+
},
352+
}
353+
354+
got, err := fs.GetMounts()
355+
if err != nil {
356+
t.Fatal(err)
357+
}
358+
359+
if diff := cmp.Diff(want, got); diff != "" {
360+
t.Fatalf("unexpected mountpoints (-want +got):\n%s", diff)
361+
}
362+
363+
got, err = fs.GetProcMounts(26231)
364+
if err != nil {
365+
t.Fatal(err)
366+
}
367+
368+
if diff := cmp.Diff(want, got); diff != "" {
369+
t.Fatalf("unexpected mountpoints (-want +got):\n%s", diff)
370+
}
371+
}

testdata/fixtures.ttar

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,18 @@ Max realtime priority 0 0
174174
Max realtime timeout unlimited unlimited us
175175
Mode: 644
176176
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
177+
Path: fixtures/proc/26231/mountinfo
178+
Lines: 8
179+
1 1 0:5 / /root rw,nosuid shared:8 - rootfs rootfs rw
180+
16 21 0:16 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw
181+
17 21 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw
182+
21 0 8:1 / / rw,relatime shared:1 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
183+
194 21 0:42 / /mnt/nfs/test rw shared:144 - nfs4 192.168.1.1:/srv/test rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,addr=192.168.1.1,local_lock=none
184+
177 21 0:42 / /mnt/nfs/test rw shared:130 - nfs4 192.168.1.1:/srv/test rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,addr=192.168.1.1,local_lock=none
185+
1398 798 0:44 / /mnt/nfs/test rw,relatime shared:1154 - nfs 192.168.1.1:/srv/test rw,vers=3,rsize=32768,wsize=32768,namlen=255,hard,proto=udp,timeo=11,retrans=3,sec=sys,mountaddr=192.168.1.1,mountvers=3,mountport=49602,mountproto=udp,local_lock=none,addr=192.168.1.1
186+
1128 67 253:0 /var/lib/containers/storage/overlay /var/lib/containers/storage/overlay rw,relatime - xfs /dev/mapper/rhel-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
187+
Mode: 664
188+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
177189
Path: fixtures/proc/26231/mountstats
178190
Lines: 20
179191
device rootfs mounted on / with fstype rootfs

0 commit comments

Comments
 (0)