For example, consider the following device:
- syspath: /sys/bus/mdio_bus/drivers/Qualcomm Atheros AR8031!AR8033
- subsystem: "drivers"
- driver subsystem: "mdio_bus"
- sysname: "Qualcomm Atheros AR8031/AR8033" <-- '!' is replaced with '/'
When sd_device_new_from_subsystem_sysname() is called to get the device,
the arguments to sd_device_new_from_subsystem_sysname() should be
- subsystem: "drivers"
- sysname (concatenated with driver subsystem): "mdio_bus:Qualcomm Atheros AR8031/AR8033"
In that case, we need to pass to device_new_from_path_join() the following:
- subsystem: "drivers"
- driver subsystem: "mdio_bus"
- sysname: "Qualcomm Atheros AR8031/AR8033"
- a: "/sys/bus"
- b: "drivers"
- c: "mdio_bus"
- d: "Qualcomm Atheros AR8031!AR8033"
Here, the important point is that the `sysname` argument and the
last argument `d` are differnt: the `sysname` argument needs to match
the sysname obtained by `sd_device_get_sysname()`, but `d` must be
the last path component of the syspath.
Previously, we passed a wrong sysname to device_new_from_path_join().
This fixes the issue.
Fixes a bug in cd7c71154c (v257).
The test "hangs" and times out on some arm64 machines. It actually works as
expected, but the machine has 2016 children under /sys/devices/system/memory/,
and the tests do a double loop over this, which is slow enough to hit the 120 s
limit. Add a limit on the number of iterations.
Another option would be to exclude "memory" subsystem. But we may have other
subsystems which have the same problem in the future, so I think it'll be more
robust to not try to limit the fix to a specific subsystem.
- drop unnecessary one line function dump_device_action_table(),
- make parse_device_action() log about invalid action string,
- rename output argument of parse_device_action().
Previously, if e.g. DRIVER=foo is specified in uevent file, the value is
only saved as property, but was not set to sd_device.driver.
That was inconsistent to the case when a device is created through
netlink uevent.
Let's always set when we get e.g. sd_device.driver when DRIVER=foo
from both uevent file and netlink uevent.
This makes sd_device_get_sysattr_value()/sd_device_set_sysattr_value()
refuse to read/write files outside of sysfs for safety.
Also this makes
- use chase() to resolve and open the symlink in path to sysfs attribute,
- use delete_trailing_chars(),
- include error code in cache entry, so we can cache more error cases,
- refuse caching value written to uevent file of any devices, i.e.
sd_device_set_sysattr_value(dev, "../uevent", "add") will also not
cache the value "add".
Even though udevadm accepts relative syspath, previously, udevadm
could not use relative path to device node:
===
$ cd /dev
$ udevadm info sda
Bad argument "sda", expected an absolute path in /dev/ or /sys/ or a unit name: Invalid argument
$ udevadm info /usr/../dev/sda
Unknown device "/usr/../dev/sda": No such device
===
With this change, both the above cases work fine.
Note, still sd_device_new_from_devname() requires absolute path starts
with /dev/, for safety.
Devices under /sys/firmware/ do not have subsystems. Hence, the
validation in sd_device_new_from_subsystem_sysname() ->
device_new_from_path_join() always failed.
Fixes a bug introduced by cd7c71154c (v257).
Fixes#35861.
This commit add the `-i` option to `udevadm trigger` that force it to
match parent devices even if they're excluded from filters.
The rationale is that some embedded devices have a huge number of
platform devices ( ~ 4k for MX8 ) they are there because they're defined
in the device tree but there isn't any action or udev rules associated
with them.
So at boot a significant time is spend triggering and processing rules
for devices that don't produce any effect and we would like to filter
them by calling:
```
udevadm trigger --type=device --action=add -s block -s tty
```
instead of the normal
```
udevadm trigger --type=device --action=add
```
so we can use filter to filter out only subsystems for we we know that
we have rules in place that do something useful.
On the other side action / rules are not triggered until the parent is
triggered ( which is part of another subsystem), so the additional option
will allows udev to complete the coldplug with only the devices we care.
Example on iMX8:
.Without the new option
```
root@dev:~# udevadm trigger --dry-run -s block --action=add -v
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0boot0
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0boot1
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p1
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p2
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p3
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p4
```
.With the new option
```
root@dev:~# udevadm trigger --dry-run -i -s block --action=add -v
/sys/devices/platform
/sys/devices/platform/bus@5b000000
/sys/devices/platform/bus@5b000000/5b010000.mmc
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0boot0
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0boot1
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p1
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p2
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p3
/sys/devices/platform/bus@5b000000/5b010000.mmc/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p4
```
Boot time reduction with this is place is ~ 1 second.
Follow-up for bab889c51e (#33032).
Currently, they unconditionally returns EPOLLIN and USEC_INFINITY, respectively.
Just for consistency with sd-bus, sd-journal, sd-varlink, and so on. All
they have _get_fd(), _get_events(), and _get_timeout().
Closes#34094.
As workarounded by fc0cbed2db, the pair of
subsystem and sysname is not unique. For examples,
- /sys/bus/gpio and /sys/class/gpio, both have gpiochip%N. However, these point to different devpaths.
- /sys/bus/mdio_bus and /sys/class/mdio_bus,
- /sys/bus/mei and /sys/class/mei,
- /sys/bus/typec and /sys/class/typec, and so on.
Let's refuse to provide sd_device object in such cases.
To create the sd_device object of a driver, the function
sd_device_new_from_subsystem_sysname() requires "drivers" for subsystem
and e.g. "pci:iwlwifi" for sysname. Similarly, sd_device_new_from_device_id()
also requires driver subsystem. However, we have never provided a
way to get the driver subsystem ("pci" for the previous example) from
an existing sd_device object.
Let's introduce a way to get driver subsystem.
This partially reverts the commit 730b76bd2c.
Before the commit, the function returned 0 on success, but the commit
made the function always return 1, as if device->devtype is NULL, the
function returns -ENOENT in the above.
Fortunately, udev_device_get_devtype() does not propagate any
non-negative value from sd_device_get_devtype(). Hence, hopefully we can
safely revert the change.