@@ -48,73 +48,168 @@ def for_each_mount_impl(cls, task):
4848
4949 @classmethod
5050 def for_each_mount_nsproxy (cls , task ):
51+ """
52+ An implementation of for_each_mount that uses the task's
53+ nsproxy to locate the mount namespace. See for_each_mount
54+ for more details.
55+ """
5156 return list_for_each_entry (task ['nsproxy' ]['mnt_ns' ]['list' ],
5257 types .mount_type , 'mnt_list' )
5358
5459 @classmethod
55- def check_task_interface (cls , symval ):
60+ def _check_task_interface (cls , symval ):
5661 try :
5762 nsproxy = symvals .init_task ['nsproxy' ]
5863 cls .for_each_mount_impl = cls .for_each_mount_nsproxy
5964 except KeyError :
6065 print ("check_task_interface called but no init_task?" )
6166 pass
6267
63- def check_mount_type (gdbtype ):
68+ def _check_mount_type (gdbtype ):
6469 try :
6570 types .mount_type = gdb .lookup_type ('struct mount' )
6671 except gdb .error :
6772 # Older kernels didn't separate mount from vfsmount
6873 types .mount_type = types .vfsmount_type
6974
7075def for_each_mount (task = None ):
76+ """
77+ Iterate over each mountpoint in the namespace of the specified task
78+
79+ If no task is given, the init_task is used.
80+
81+ The type of the mount structure returned depends on whether
82+ 'struct mount' exists on the kernel version being debugged.
83+
84+ Args:
85+ task (gdb.Value<struct task_struct>, default=<symbol:init_task>):
86+ The task which contains the namespace to iterate.
87+
88+ Yields:
89+ gdb.Value<struct vfsmount or struct mount>:
90+ A mountpoint attached to the namespace.
91+
92+ """
7193 if task is None :
7294 task = symvals .init_task
7395 return Mount .for_each_mount_impl (task )
7496
75- def real_mount (vfsmnt ):
76- if (vfsmnt .type == types .mount_type or
77- vfsmnt .type == types .mount_type .pointer ()):
78- t = vfsmnt .type
79- if t .code == gdb .TYPE_CODE_PTR :
80- t = t .target ()
81- if t is not types .mount_type :
82- types .mount_type = t
83- return vfsmnt
84- return container_of (vfsmnt , types .mount_type , 'mnt' )
97+ def mount_flags (mnt : gdb .Value , show_hidden : bool = False ) -> str :
98+ """
99+ Returns the human-readable flags of the mount structure
100+
101+ Args:
102+ mnt (gdb.Value<struct vfsmount or struct mount>):
103+ The mount structure for which to return flags
85104
86- def mount_flags (mnt , show_hidden = False ):
105+ show_hidden (bool, default=False):
106+ Whether to return hidden flags
107+
108+ Returns:
109+ str: The mount flags in human-readable form
110+ """
87111 if struct_has_member (mnt , 'mnt' ):
88112 mnt = mnt ['mnt' ]
89113 if show_hidden :
90114 return decode_flags (mnt ['mnt_flags' ], MNT_FLAGS_HIDDEN , "," )
91115 return decode_flags (mnt ['mnt_flags' ], MNT_FLAGS , "," )
92116
93- def mount_super (mnt ):
117+ def mount_super (mnt : gdb .Value ) -> gdb .Value :
118+ """
119+ Returns the struct super_block associated with a mount
120+
121+ Args:
122+ mnt: gdb.Value<struct vfsmount or struct mount>:
123+ The mount structure for which to return the super_block
124+
125+ Returns:
126+ gdb.Value<struct super_block>:
127+ The super_block associated with the mount
128+ """
94129 try :
95130 sb = mnt ['mnt' ]['mnt_sb' ]
96131 except gdb .error :
97132 sb = mnt ['mnt_sb' ]
98133 return sb
99134
100- def mount_root (mnt ):
135+ def mount_root (mnt : gdb .Value ) -> gdb .Value :
136+ """
137+ Returns the struct dentry corresponding to the root of a mount
138+
139+ Args:
140+ mnt: gdb.Value<struct vfsmount or struct mount>:
141+ The mount structure for which to return the root dentry
142+
143+ Returns:
144+ gdb.Value<struct dentry>:
145+ The dentry that corresponds to the root of the mount
146+ """
101147 try :
102148 mnt = mnt ['mnt' ]
103149 except gdb .error :
104150 pass
105151
106152 return mnt ['mnt_root' ]
107153
108- def mount_fstype (mnt ):
154+ def mount_fstype (mnt : gdb .Value ) -> str :
155+ """
156+ Returns the file system type of the mount
157+
158+ Args:
159+ mnt (gdb.Value<struct vfsmount or struct mount>):
160+ The mount structure for which to return the file system tyoe
161+
162+ Returns:
163+ str: The file system type of the mount in string form
164+ """
109165 return super_fstype (mount_super (mnt ))
110166
111- def mount_device (mnt ):
167+ def mount_device (mnt : gdb .Value ) -> str :
168+ """
169+ Returns the device name that this mount is using
170+
171+ Args:
172+ gdb.Value<struct vfsmount or mount>:
173+ The mount structure for which to get the device name
174+
175+ Returns:
176+ str: The device name in string form
177+
178+ """
112179 devname = mnt ['mnt_devname' ].string ()
113180 if devname is None :
114181 devname = "none"
115182 return devname
116183
184+ def _real_mount (vfsmnt ):
185+ if (vfsmnt .type == types .mount_type or
186+ vfsmnt .type == types .mount_type .pointer ()):
187+ t = vfsmnt .type
188+ if t .code == gdb .TYPE_CODE_PTR :
189+ t = t .target ()
190+ if t is not types .mount_type :
191+ types .mount_type = t
192+ return vfsmnt
193+ return container_of (vfsmnt , types .mount_type , 'mnt' )
194+
117195def d_path (mnt , dentry , root = None ):
196+ """
197+ Returns a file system path described by a mount and dentry
198+
199+ Args:
200+ mnt (gdb.Value<struct vfsmount or struct mount>):
201+ The mount for the start of the path
202+
203+ dentry (gdb.Value<struct dentry>):
204+ The dentry for the start of the path
205+
206+ root (gdb.Value<struct vfsmount or struct mount>, default=None):
207+ The mount at which to stop resolution. If None,
208+ the current root of the namespace.
209+
210+ Returns:
211+ str: The path in string form
212+ """
118213 if root is None :
119214 root = symvals .init_task ['fs' ]['root' ]
120215
@@ -124,7 +219,7 @@ def d_path(mnt, dentry, root=None):
124219 if mnt .type .code != gdb .TYPE_CODE_PTR :
125220 mnt = mnt .address
126221
127- mount = real_mount (mnt )
222+ mount = _real_mount (mnt )
128223 if mount .type .code != gdb .TYPE_CODE_PTR :
129224 mount = mount .address
130225
@@ -157,5 +252,5 @@ def d_path(mnt, dentry, root=None):
157252 name = '/'
158253 return name
159254
160- type_cbs = TypeCallbacks ([ ('struct vfsmount' , check_mount_type ) ])
161- symbols_cbs = SymbolCallbacks ([ ('init_task' , Mount .check_task_interface ) ])
255+ type_cbs = TypeCallbacks ([ ('struct vfsmount' , _check_mount_type ) ])
256+ symbols_cbs = SymbolCallbacks ([ ('init_task' , Mount ._check_task_interface ) ])
0 commit comments