@@ -32,11 +32,10 @@ import (
3232 "k8s.io/klog/v2"
3333)
3434
35- func parseMount (s string ) * MountEntry {
35+ func parseMount (s string , xxHash uint64 ) * MountEntry {
3636 // Refer https://man7.org/linux/man-pages/man5/proc_pid_mountinfo.5.html
3737 // to know about this logic.
3838 s = strings .TrimSpace (s )
39- xxHash := xxhash .Sum64String (s )
4039 tokens := strings .Fields (s )
4140 if len (tokens ) < 8 {
4241 return nil
@@ -70,12 +69,22 @@ func parseMount(s string) *MountEntry {
7069 return & mount
7170}
7271
73- func parseMountInfo (r io.Reader ) (* MountInfo , error ) {
74- infoMap := map [uint64 ]* MountEntry {}
75- mountPointMap := map [string ][]uint64 {}
76- mountSourceMap := map [string ][]uint64 {}
77- majorMinorMap := map [string ][]uint64 {}
78- rootMap := map [string ][]uint64 {}
72+ func parseMountInfo (r io.Reader , info * MountInfo ) (* MountInfo , error ) {
73+ if info == nil {
74+ info = & MountInfo {
75+ infoMap : map [uint64 ]* MountEntry {},
76+ mountPointMap : map [string ][]uint64 {},
77+ mountSourceMap : map [string ][]uint64 {},
78+ majorMinorMap : map [string ][]uint64 {},
79+ rootMap : map [string ][]uint64 {},
80+ }
81+ }
82+
83+ infoMap := info .infoMap
84+ mountPointMap := info .mountPointMap
85+ mountSourceMap := info .mountSourceMap
86+ majorMinorMap := info .majorMinorMap
87+ rootMap := info .rootMap
7988
8089 reader := bufio .NewReader (r )
8190
@@ -88,7 +97,12 @@ func parseMountInfo(r io.Reader) (*MountInfo, error) {
8897 return nil , err
8998 }
9099
91- mount := parseMount (s )
100+ xxHash := xxhash .Sum64String (s )
101+ if _ , found := infoMap [xxHash ]; found {
102+ continue
103+ }
104+
105+ mount := parseMount (s , xxHash )
92106 if mount == nil {
93107 continue
94108 }
@@ -100,23 +114,41 @@ func parseMountInfo(r io.Reader) (*MountInfo, error) {
100114 rootMap [mount .Root ] = append (rootMap [mount .Root ], mount .xxHash )
101115 }
102116
103- return & MountInfo {
104- infoMap : infoMap ,
105- mountPointMap : mountPointMap ,
106- mountSourceMap : mountSourceMap ,
107- majorMinorMap : majorMinorMap ,
108- rootMap : rootMap ,
109- }, nil
117+ return info , nil
110118}
111119
112120func newMountInfo () (* MountInfo , error ) {
113- file , err := os .Open ("/proc/self/mountinfo" )
121+ parseSelfInfo := func () (* MountInfo , error ) {
122+ file , err := os .Open ("/proc/self/mountinfo" )
123+ if err != nil {
124+ return nil , err
125+ }
126+
127+ defer file .Close ()
128+ return parseMountInfo (file , nil )
129+ }
130+
131+ parseRootInfo := func (info * MountInfo ) (* MountInfo , error ) {
132+ file , err := os .Open ("/proc/1/mountinfo" )
133+ if err != nil {
134+ switch {
135+ case errors .Is (err , os .ErrInvalid ), errors .Is (err , os .ErrPermission ), errors .Is (err , os .ErrExist ), errors .Is (err , os .ErrNotExist ), errors .Is (err , os .ErrClosed ):
136+ default :
137+ klog .ErrorS (err , "unable to read /proc/1/mountinfo; open an issue in SUBNET with this log" )
138+ }
139+ return info , nil
140+ }
141+
142+ defer file .Close ()
143+ return parseMountInfo (file , info )
144+ }
145+
146+ info , err := parseSelfInfo ()
114147 if err != nil {
115148 return nil , err
116149 }
117150
118- defer file .Close ()
119- return parseMountInfo (file )
151+ return parseRootInfo (info )
120152}
121153
122154var mountFlagMap = map [string ]uintptr {
0 commit comments