Bug 1267584 - device.attributes.values likely to raise a KeyError
device.attributes.values likely to raise a KeyError
Status: NEW
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: python-pyudev (Show other bugs)
All Unspecified
unspecified Severity medium
: rc
: ---
Assigned To: Jaroslav Škarvada
: Reopened
Depends On:
  Show dependency treegraph
Reported: 2015-09-30 09:23 EDT by mulhern
Modified: 2018-06-04 09:05 EDT (History)
5 users (show)

See Also:
Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: 1265315
Last Closed: 2015-10-02 12:15:56 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

  None (edit)
Description mulhern 2015-09-30 09:23:39 EDT
+++ This bug was initially created as a clone of Bug #1265315 +++

Description of problem:

udev_device_get_sysattr_list_entry returns a list of attribute, value pairs.
The values are NULL, the attributes are said to be "available".

From the docs:
 Retrieve the list of available sysattrs, with value being empty; This just return all available sysfs attributes for a particular device without reading their values. 

I dunno what "available" is supposed to mean, but if these attributes are
further looked up by "udev_device_get_sysattr_value" they may have no value,
i.e., this method may return NULL. (This is not the same as having a value
like the empty string, which fits the specification just fine.)

Version-Release number of selected component (if applicable):


How reproducible:

Consistently, for a given device.

Steps to Reproduce:
1. Loop over all devices returned by udevadm.
2. List the attributes using udev_device_get_sysattr_list_entry().
3. Look up the listed attributes using udev_device_get_sysattr_value(). Observe that some of these attributes are NULL.

Actual results:

Some "available" attributes have no values. Generally speaking, these attributes seem to be symlinks to directories. It is not true that all attributes that correspond to symlinks to directories have no value, only some.

Expected results:

"Available" attributes should have a value or documentation should define clearly that "available" means fits some criteria which does not necessarily include actually having a value.

Additional info:

It is normal to think of attribute name/value pairs as being like keys in a map.
If they are not, that is, if a key can simultaneously be in the map and not be
in the map, that should get better documentation then by the single word "available".

Also, in documentation, the ';' is followed by a capital letter, should be lowercase.

--- Additional comment from mulhern on 2015-09-22 12:11:50 EDT ---

Output of new.c on my Fedora desktop. This is just an example, similar things
happen on my RHEL 7.2 box.

[mulhern@localhost reproducers]$ ./a.out
Correct behavior, values are not obtained.
adr: (null)
path: (null)
subsystem: (null)
uevent: (null)
physical_node: (null)

Incorrect behavior; physical_node should have a value.
adr: 0x00000000
path: \_SB_.PCI0.EHC2.HUBN
subsystem: acpi
physical_node: (null)

correct behavior, value of non-existant attribute is null.
bogus: (null)

Should be like the first.
adr: (null)
path: (null)
subsystem: (null)
uevent: (null)
physical_node: (null)

--- Additional comment from mulhern on 2015-09-23 15:35 EDT ---

--- Additional comment from mulhern on 2015-09-23 17:03:36 EDT ---

The attached file printed SURPRISE a few times on both systems, indicating that some of the attributes with no value were not symlinked directories. What characteristics they do have I do not know.


Since attributes inherits from Mapping, values method is defined by the Mapping class using in, like, "[s[key] for key in s]". Due to the libudev inconsistency described in #1265315, this is likely to raise an error when key is both in, in the second use of 'in', but not in in the first use of 'in'.
Comment 2 mulhern 2015-09-30 10:03:08 EDT
items(), iteritems(), and itervalues() all have the same problem, since they have the same dependency.

Basically, it would be good to know what the intention of libudev actually is before making a move on this bug.

But to avoid all these methods raising a KeyError, the only real option at this time is to have __getitem__() raise a KeyError when the item is not among the keys, but return None when it is among the keys but lookup fails. If that is the correct thing to do, then it is at least quite straightforward.
Comment 3 Kay Sievers 2015-10-02 08:31:34 EDT
> udev_device_get_sysattr_list_entry returns a list of attribute, value pairs.
> The values are NULL, the attributes are said to be "available".

It only returns a list of file names, like "ls". You cannot use the values in this list, they are not set.

> but if these attributes are further looked up by
> "udev_device_get_sysattr_value" they may have no value

The same way as "cat" of the file name returned by "ls" may result in
an error, no value, for whatever reason.

"physical_node" is a pointer to a device, not an attribute, trying to read it as an attribute value returns NULL. This this the expected behavior.

Note: Please be very careful by blindly reading all things available in /sys,
some attributes change the behavior of the system, just by reading the values.
/sys is not for poking around, without knowing what it does. Privileged
programs can cause harm here, just by opening and reading random files.
Comment 4 mulhern 2015-10-02 10:05:58 EDT
The other option is not to make Attributes a subclass of Mapping. That is an idea worth investigating, since the mapping is in general partial (see Comment #3).
Comment 5 mulhern 2015-10-02 12:09:25 EDT
This should be deferred until 7.3. It turns out that it is more of a design flaw than a simple fix, so it will require a change in the Attributes class, rather than just a simple two line change in a single method. At the same time, it seems that users of the library are not using it in a way that triggers the bug.
They are using it more like the underlying libudev library was intended to be used, apparently.
Comment 7 RHEL Product and Program Management 2015-10-02 12:15:56 EDT
Development Management has reviewed and declined this request.
You may appeal this decision by reopening this request.
Comment 8 mulhern 2015-11-18 15:52:15 EST
There is still a problem, because the two methods that this class depends on don't seem to have a very easy to discover relationship. So, it seems like this Attributes class should stop having any notion of keys at all until that gets worked out.
Comment 9 mulhern 2015-11-25 13:23:32 EST
The relationship was easy to discover, but not really deep or meaningful, see related bug.
Comment 10 mulhern 2015-12-02 13:47:16 EST
This is fixed in pyudev version 0.18.
Comment 11 mulhern 2015-12-03 14:28:28 EST
I think my responsibility ends now that it is fixed upstream.
Comment 12 mulhern 2015-12-11 11:09:14 EST
The fix results in some issues with Attributes.tostring() method, so I'm reassigning.
Comment 13 mulhern 2015-12-18 14:00:23 EST
Fixed in version 0.18.1.
Comment 14 Fedora Update System 2015-12-22 10:57:44 EST
python-pyudev-0.18.1-1.fc23 has been submitted as an update to Fedora 23. https://bodhi.fedoraproject.org/updates/FEDORA-2015-7eb77298d4
Comment 15 Fedora Update System 2015-12-22 19:09:58 EST
python-pyudev-0.18.1-1.fc23 has been pushed to the Fedora 23 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2015-7eb77298d4
Comment 16 mulhern 2015-12-22 20:35:04 EST
Whoops, an unintended effect of filling in some bodhi field.
Comment 17 Fedora Update System 2015-12-28 17:54:25 EST
python-pyudev-0.18.1-1.fc23 has been pushed to the Fedora 23 stable repository. If problems still persist, please make note of it in this bug report.

Note You need to log in before you can comment on or make changes to this bug.