Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sysfs helpers #443

Open
5 tasks
osandov opened this issue Oct 11, 2024 · 0 comments
Open
5 tasks

Add sysfs helpers #443

osandov opened this issue Oct 11, 2024 · 0 comments
Labels
good first issue Good for newcomers help wanted Seeking volunteers

Comments

@osandov
Copy link
Owner

osandov commented Oct 11, 2024

Background

When debugging anything related to a device driver, the first step is often finding the struct device that represents the device in the kernel. One way to find a device is by its sysfs path. However, drgn doesn't currently have an easy way to do that. You can kind of do it with something like:

>>> path = path_lookup("/sys/devices/pci0000:00/0000:00:06.0/0000:04:00.0/nvme/nvme0/nvme0n1")
>>> kn = cast("struct kernfs_node *", path.dentry.d_inode.i_private)
>>> kobject = cast("struct kobject *", kn.priv)
>>> device = container_of(kobject, "struct device", "kobj")

But this has a few issues:

  • Clearly it's not convenient at all.
  • path_lookup() walks the dentry cache, which may not be populated for a particular path depending on memory pressure.
  • path_lookup() doesn't resolve symlinks (yet, see Handle symlinks in path_lookup() #216), so you have to use the canonical path instead of a more convenient symlink like /sys/block/nvme0n1.

Instead, we should improve our kernfs helpers and provide sysfs-specific helpers on top of those. This can be broken down into multiple smaller features.

kernfs

sysfs is actually an instance of kernfs, which is generic infrastructure for pseudo file systems. A kernfs filesystem comprises a tree of struct kernfs_node, each of which represents a file or directory.

We already have a few basic helpers for inspecting kernfs: https://drgn.readthedocs.io/en/latest/helpers.html#kernfs. I would like two extensions to those:

  • Add a kernfs_children() helper that returns an iterator over the children of a directory in kernfs. Children are represented by struct kernfs_node::dir::children.
  • Extend the kernfs_walk() helper to follow symlinks. These are represented by struct kernfs_node::symlink::target_kn. We should probably also have a follow_symlinks parameter that controls what we do if the last component of a path is a symlink, similar to the Python os module.

sysfs

Once we have the kernfs changes, we can add sysfs-specific helpers that use the new kernfs features.

  • Add a sysfs_lookup_node() helper that returns the struct kernfs_node * at a given path.
  • Add a sysfs_lookup() helper that returns the actual object (e.g., struct device *, struct bus *, etc.) represented by a given path.
  • Add a sysfs_listdir() helper that lists the names of the children of a sysfs directory at a given path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Seeking volunteers
Projects
None yet
Development

No branches or pull requests

1 participant