Skip to content

Commit

Permalink
corelens: add support for multiple kmods in skip_unless_have_kmods
Browse files Browse the repository at this point in the history
skip_unless_have_kmods can now take a list of modules as strings. Skip
if any of the modules in the list are not present.

Orabug: 37389765
Signed-off-by: Richard Li <[email protected]>
  • Loading branch information
richl9 authored and brenns10 committed Dec 17, 2024
1 parent 9e32869 commit 0a08b41
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 22 deletions.
39 changes: 21 additions & 18 deletions drgn_tools/corelens.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ def add_args(self, parser: argparse.ArgumentParser) -> None:
pass

@property
def skip_unless_have_kmod(self) -> Optional[str]:
def skip_unless_have_kmods(self) -> Optional[List[str]]:
"""
If specified, skip this when the kmod is not present in the kernel
If specified, skip this when the kmods are not present in the kernel
This field, when specified, is a string naming a kernel module (referred
This field, when specified, is a list of strings naming kernel modules (referred
to as kmod in these docs to avoid confusing with "corelens module").
This kmod is expected to signify the presence of the subsystem that this
module is dealing with. If the kmod is not loaded in the kernel, then
this module is skipped by corelens. If the kmod is loaded, but no
This kmod(s) is expected to signify the presence of the subsystem that this
module is dealing with. If the kmod(s) is not loaded in the kernel, then
this module is skipped by corelens. If the kmod(s) is loaded, but no
debuginfo is present, the module is skipped and an error is raised.
"""
return None
Expand All @@ -116,7 +116,7 @@ def debuginfo_kmods(self) -> List[str]:
This field, when specified, is a list of strings. Each string could be a
kmod name, or a :mod:`fnmatch` pattern which matches several kmods.
Unlike :attr:`skip_unless_have_kmod`, we don't require that the kmods
Unlike :attr:`skip_unless_have_kmods`, we don't require that the kmods
here are loaded. Instead, we just require that *if* the modules are
loaded, they must have debuginfo present.
Expand Down Expand Up @@ -198,10 +198,11 @@ def _notes(self) -> List[str]:
notes.append("Requires DWARF debuginfo.")
if not self.live_ok:
notes.append("Live kernel not supported.")
if self.skip_unless_have_kmod:
if self.skip_unless_have_kmods:
notes.append(
f'Skipped unless "{self.skip_unless_have_kmod}" '
"kernel module is loaded."
"Skipped unless '{}' kernel module(s) are loaded.".format(
", ".join(self.skip_unless_have_kmods)
)
)
if self.run_when == "verbose":
notes.append("Detailed module (runs with -A)")
Expand Down Expand Up @@ -460,13 +461,14 @@ def _check_module_debuginfo(
for mod, args in candidate_modules:
# Corelens modules that depend on a particular subsystem module being
# present, should should be skipped if it is not present.
if mod.skip_unless_have_kmod is not None and (
mod.skip_unless_have_kmod not in all_kmod_names
if mod.skip_unless_have_kmods is not None and (
not all(m in all_kmod_names for m in mod.skip_unless_have_kmods)
):
if warn_not_present:
warnings.append(
f"{mod.name} skipped because '{mod.skip_unless_have_kmod}'"
" was not loaded in the kernel"
"{} skipped because '{}' was (were) not (all) loaded in the kernel".format(
mod.name, ", ".join(mod.skip_unless_have_kmods)
)
)
continue

Expand All @@ -493,12 +495,13 @@ def _check_module_debuginfo(
modules_to_run.append((mod, args))
continue

if mod.skip_unless_have_kmod is not None and (
mod.skip_unless_have_kmod not in loaded_kmods
if mod.skip_unless_have_kmods is not None and (
not all(m in loaded_kmods for m in mod.skip_unless_have_kmods)
):
errors.append(
f"{mod.name} skipped because '{mod.skip_unless_have_kmod}'"
" did not have debuginfo loaded"
"{} skipped because '{}' did not have (all) debuginfo loaded".format(
mod.name, ", ".join(mod.skip_unless_have_kmods)
)
)
continue
skip = False
Expand Down
2 changes: 1 addition & 1 deletion drgn_tools/dm.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ class Dm(CorelensModule):
"""Display info about device mapper devices"""

name = "dm"
skip_unless_have_kmod = "dm_mod"
skip_unless_have_kmods = ["dm_mod"]

def run(self, prog: Program, args: argparse.Namespace) -> None:
show_dm(prog)
Expand Down
2 changes: 1 addition & 1 deletion drgn_tools/ext4_dirlock.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class Ext4DirLock(CorelensModule):
"""Scan processes hung by ext4 directory inode lock"""

name = "ext4_dirlock_scan"
skip_unless_have_kmod = "ext4"
skip_unless_have_kmods = ["ext4"]

def add_args(self, parser: argparse.ArgumentParser) -> None:
parser.add_argument(
Expand Down
2 changes: 1 addition & 1 deletion drgn_tools/nfs_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@ class NfsShow(CorelensModule):
name = "nfsshow"

# there's no point in running unless the nfs module is loaded
skip_unless_have_kmod = "nfs"
skip_unless_have_kmods = ["nfs"]

# we need sunrpc, and all nfs related debuginfo loaded
debuginfo_kmods = ["sunrpc", "nfs", "nfs*"]
Expand Down
2 changes: 1 addition & 1 deletion drgn_tools/rds.py
Original file line number Diff line number Diff line change
Expand Up @@ -1540,7 +1540,7 @@ class Rds(CorelensModule):
"""Print info about RDS devices, sockets, connections, and stats"""

name = "rds"
skip_unless_have_kmod = "rds"
skip_unless_have_kmods = ["rds"]

# We access information from the following modules #
debuginfo_kmods = ["mlx5_core", "mlx4_core", "mlx5_ib", "mlx4_ib"]
Expand Down

0 comments on commit 0a08b41

Please sign in to comment.