Skip to content

Commit 45567a7

Browse files
committed
crash.subsytem.filesystem.mount: add API documentation
This commit adds documentation for the mount API and makes private some methods/functions that are meant to be internal. Signed-off-by: Jeff Mahoney <jeffm@suse.com>
1 parent 2e8ee75 commit 45567a7

1 file changed

Lines changed: 115 additions & 20 deletions

File tree

‎crash/subsystem/filesystem/mount.py‎

Lines changed: 115 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

7075
def 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+
117195
def 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

Comments
 (0)