drgn/contrib/cgroup.py
Omar Sandoval a0a54edc1f Create contrib directory
It's come up several times that it'd be nice to have somewhere to dump
drgn scripts that people write while debugging without requiring them to
be cleaned up and scrutinized in code review. Serapheim Dimitropoulos
noted that several projects have a "contrib" directory for this purpose.
See [1]. Let's create one, document it, exclude it from pre-commit, and
move our (mostly unmaintained) examples there.

1: https://drewdevault.com/2020/06/06/Add-a-contrib-directory.html

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2022-11-16 13:17:50 -08:00

72 lines
1.9 KiB
Python
Executable File

#!/usr/bin/env drgn
# Copyright (c) Meta Platforms, Inc. and affiliates.
# SPDX-License-Identifier: LGPL-2.1-or-later
"""List the paths of all descendants of a cgroup v2"""
from contextlib import contextmanager
import os
import sys
from drgn import cast
from drgn.helpers.common.type import enum_type_to_class
from drgn.helpers.linux import (
cgroup_bpf_prog_for_each,
cgroup_path,
css_for_each_descendant_pre,
fget,
find_task,
)
BpfAttachType = enum_type_to_class(
prog.type("enum bpf_attach_type"),
"BpfAttachType",
exclude=("__MAX_BPF_ATTACH_TYPE",),
)
@contextmanager
def open_dir(*args, **kwds):
# Built-in open() context manager can't deal with directories.
fd = os.open(*args, **kwds)
try:
yield fd
finally:
os.close(fd)
def get_cgroup():
if len(sys.argv) == 1:
return prog["cgrp_dfl_root"].cgrp
task = find_task(prog, os.getpid())
with open_dir(sys.argv[1], os.O_RDONLY) as fd:
file_ = fget(task, fd)
kn = cast("struct kernfs_node *", file_.f_path.dentry.d_inode.i_private)
return cast("struct cgroup *", kn.priv)
def print_cgroup_bpf_progs(cgrp):
cgroup_printed = False
for attach_type in BpfAttachType:
attach_flags = cgrp.bpf.flags[attach_type.value].value_()
for prog in cgroup_bpf_prog_for_each(cgrp, attach_type.value):
prog_id = prog.aux.id.value_()
prog_name = prog.aux.name.string_().decode()
if not cgroup_printed:
print(cgroup_path(cgrp).decode())
cgroup_printed = True
print(
" {:<8} {:<30} {:<15} {:<15}".format(
prog_id, attach_type.name, attach_flags, prog_name
)
)
css = get_cgroup().self.address_of_()
for pos in css_for_each_descendant_pre(css):
if sys.argv[-1] == "bpf":
print_cgroup_bpf_progs(pos.cgroup)
else:
print(cgroup_path(pos.cgroup).decode())