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

Interface with udev database for various fixes (but future work needed) #42

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

abbaad
Copy link

@abbaad abbaad commented Sep 22, 2024

Rather than attempting to parse /dev and /sys directly within smfc, we can outsource that task to udev (through pyudev). This allows us to simplify much of the logic and string parsing, making it less fragile and more robust.

This new strategy gives a convenient fix to #25.

Additionally: under linux (under the persistent storage naming rules present in most distributions AFAIK), the NVMe device by-id symlinks point to the block device (e.g., /dev/nvme0n1) rather than the controller (/dev/nvme0). However, the corresponding hwmon device is actually a child of the controller (thus a sibling to the block device in sysfs).

The original code has a bug where the symlink is assumed to be backwards (so it assumes the link points to /dev/nvme0 and concatenates the namespace within sysfs). This bug is also present in the unit tests in the test data created by the file test_00_data.py.

Properly parsing the string would require stripping the namespace (in 99% of cases, this is "n1") from the block device name. Instead, in this commit we use pyudev to query the udev database to find the sibling hwmon device. Unfortunately, the test file doesn't have such a simple fix, so someone will have to patch it more deeply.

Unfortunately, the unit tests will require a more extensive refactoring to be able to support pyudev, but these changes are not a part of this PR. If we want to keep the current strategy of creating a set of "test data" for the tests, then something like umockdev might be best. Otherwise, we could write Mocks for the expected function calls, but for that a wholesale restructuring of all the test data is probably required.

For now, this code continues to use the open and read paradigm on sysfs files, but a future refactor might instead use the pythonic interface from pyudev (e.g., hwmon_dev.attributes.get('temp1_input')).

Rather than attempting to parse `/dev` and `/sys` directly within smfc,
we can outsource that task to `udev` (through [pyudev][1]). This allows
us to simplify much of the logic and string parsing, making it less
fragile and more robust.

Unfortunately, the unit tests will require a more extensive refactoring
to be able to support pyudev, but these changes are not a part of this
commit. If we want to keep the current strategy of creating a set of
"test data" for the tests, then something like [umockdev][2] might be
best. Otherwise, we could write `Mock`s for the expected function calls,
but for that a wholesale restructuring of all the test data is probably
required.

[1]: http://pyudev.readthedocs.org/
[2]: https://github.com/martinpitt/umockdev
Under linux (under the persistent storage naming rules present in most
distributions AFAIK), the NVMe device by-id symlinks point to the block
device (e.g., `/dev/nvme0n1`) rather than the controller (`/dev/nvme0`).
However, the corresponding `hwmon` device is actually a child of the
controller (thus a sibling to the block device in sysfs).

The original code has a bug where the symlink is assumed to be backwards
(so it assumes the link points to `/dev/nvme0` and concatenates the
namespace within sysfs). This bug is also present in the unit tests in
the test data created by the file `test_00_data.py`.

Properly parsing the string would require stripping the namespace (in
99% of cases, this is `"n1"`) from the block device name. Instead, in
this commit we use pyudev to query the udev database to find the sibling
`hwmon` device. Unfortunately, the test file doesn't have such a simple
fix, so someone will have to patch it more deeply.
This fixes petersulyok#25 by using the pyudev interface. The unit
tests still need to be fixed for consistency.
Remove old code which has become redundant with pyudev interface.
@petersulyok
Copy link
Owner

Hi @abbaad, thanks for this pr, this is impressive. Let me have some time to understand how pyudev is working, and what this dependency means for the project.

@petersulyok
Copy link
Owner

Hi @abbaad, I think I got point behind pyudev and I have only one issue. This code seems not to work for me on a coretemp module (added in Fix: implement AMD CPU autoconfiguration):

for module in ['coretemp', 'k10temp']:
   hwmon_path = [self.get_tempinput(dev) for dev in self.udev_context.list_devices(DRIVER=module)]
   if hwmon_path:
      break
if not hwmon_path:
   self.log.msg(Log.LOG_ERROR, 'No explicit hwmon_path was configured, and automatic detection failed to find any devices using the coretemp or k10temp modules')

hwmon_path is always empty. Any idea on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants