Commit Graph

161 Commits

Author SHA1 Message Date
Yu Watanabe
fb53ee0a64 tree-wide: use device_in_subsystem() and device_is_devtype() 2023-12-23 03:52:21 +09:00
Yu Watanabe
7ec5ce5673 udev: update devlink with the newer device node even when priority is equivalent
Several udev rules depends on the previous behavior, i.e. that udev
replaces the devlink with the newer device node when the priority is
equivalent. Let's relax the optimization done by
331aa7aa15.

Follow-up for 331aa7aa15.

Note, the offending commit drops O(N) of file reads per uevent, and this
commit does not change the computational order. So, hopefully the
performance impact of this change is small enough.

Fixes #28141.
2023-11-01 19:46:03 +09:00
Zbigniew Jędrzejewski-Szmek
660087dc9c tree-wide: add path_simplify_alloc() and use it
path_simplify_full()/path_simplify() are changed to allow a NULL path, for
which a NULL is returned. Generally, callers have already asserted before that
the argument is nonnull. This way path_simplify_full()/path_simplify() and
path_simplify_alloc() behave consistently.

In sd-device.c, logging in device_set_syspath() is intentionally dropped: other
branches don't log.

In mount-tool.c, logging in parse_argv() is changed to log the user-specified
value, not the simplified string. In an error message, we should show the
actual argument we got, not some transformed version.
2023-09-22 08:13:34 +02:00
Daan De Meyer
a1af83728f device-util: Declare iterator variables inline 2023-07-12 20:05:18 +02:00
Frantisek Sumsal
9a27ef092e tree-wide: fix a couple of typos
As reported by Fossies.org.
2023-06-15 20:52:45 +02:00
Yu Watanabe
331aa7aa15 udev-node: optimize device node symlink creation
If multiple devices requested the same device node symlink with the same
priority, then previously we read O(N^2) of files saved in
/run/udev/links.

This makes if the requested symlink already exists with equal or higher
priority, then the symlink is kept, and skip to read all existing files,
except for one related to the current device node, in /run/udev/links.
Hence, the total amount of file read becomes O(N).

This improves performance of testcase_simultaneous_events_2 added by the
previous commit about 30%.
Before (32.8 sec):
```
 ## 3 iterations start: 11:13:44.690953163
 ## 3 iterations end: 11:14:17.493974927
```
After (23.8 sec):
```
 ## 3 iterations start: 11:17:53.869938387
 ## 3 iterations end: 11:18:17.624268345
```

This is based on the idea and analysis by Franck Bui.

Replaces #25839.

Co-authored-by: Franck Bui <fbui@suse.com>
2023-06-13 22:51:00 +02:00
Daan De Meyer
0690160e2c label: Rename to label-util.h 2023-05-30 14:50:56 +02:00
Yu Watanabe
135e5a201a udev-node: make stack_directory_read_one() accept NULL for devnode
No functional change, as currently the function is always called with
non-NULL argument. Just a preparation for #26048 or #25839.
2023-02-20 19:40:31 +09:00
Yu Watanabe
c207a57227 udev-node: drop unnecessary initialization
The priority of device node symlink can be negative. So the
initialization is confusing.

Fortunately, this changes no functionality, as we only compare the
priorities of symlinks only when we parsed at least one device node and
its priority.
2023-02-20 10:54:48 +01:00
Franck Bui
6d90488acb udev: simplify a bit stack_directory_find_prioritized_devnode()
And make the new format the one we expect as it should replace the old one
pretty quickly.
2023-01-13 12:06:00 +09:00
Franck Bui
e8a54a4e75 udev: return ENODEV if link_directory_read_one() can't find the devnode
That's usually the errno code we return when a device cannot be found because
it's been unplugged.
2023-01-13 11:22:31 +09:00
Franck Bui
72a459adc4 udev: let stack_directory_open() convert a slink into a dirname itself
We likely always want to open the directory via a slink.

There's currently only one caller so it doesn't make any difference in practice
but I think it's still nicer.

No functional change.
2023-01-13 11:16:14 +09:00
Franck Bui
c9032f910c udev: merge link_directory_lock() into link_directory_open()
These 2 operations are inseparable.
2023-01-13 11:16:10 +09:00
Zbigniew Jędrzejewski-Szmek
254d1313ae tree-wide: use -EBADF for fd initialization
-1 was used everywhere, but -EBADF or -EBADFD started being used in various
places. Let's make things consistent in the new style.

Note that there are two candidates:
EBADF 9 Bad file descriptor
EBADFD 77 File descriptor in bad state

Since we're initializating the fd, we're just assigning a value that means
"no fd yet", so it's just a bad file descriptor, and the first errno fits
better. If instead we had a valid file descriptor that became invalid because
of some operation or state change, the other errno would fit better.

In some places, initialization is dropped if unnecessary.
2022-12-19 15:00:57 +01:00
Yu Watanabe
5b4671ec47 Merge pull request #24646 from yuwata/udev-node-symlink_atomic
udev: introduce symlink_atomic_full() and use it
2022-09-19 05:25:58 +09:00
Yu Watanabe
6d42138593 udev-node: use symlink_atomic_full_label() to create devlink
If the filename of a device symlink is too long, then the temporary
filename may become invalid, and we fail to create symlink.

The function `tempfn_random()` used in symlink_atomic_full() generates
a safe temporary filename.

Note that, thanks to the PR #23043, now only one worker can handle
the same symlink simultaneously. Hence, the device ID based temporary
filename is not necessary.
2022-09-18 23:23:23 +09:00
Yu Watanabe
69928b4f15 udev-node: do not create symlink to a non-existing device node
Previously, the stack directory contains empty regular files named with
device ID, and we create sd_device object from the device name.
Hence, we implicitly checked the existence of the device node.

However, now the files in the stack directory are symlink, and we
retrieve the path to the device node and its priority from the symlink.
Hence, the existence of the device node is not checked.
Let's check if the device node is still exist.
2022-09-16 23:08:07 +09:00
Yu Watanabe
13271e2dde udev-node: split out stack_directory_read_one()
No functional changes, just refactoring.
2022-09-16 23:07:31 +09:00
Yu Watanabe
1055172804 udev: cleanup stack directory /run/udev/links when all workers exited
By the previous commit, the stack directories are not removed even if
it is empty. To reduce the inode usage of /run, let's cleanup the
directories.
2022-09-03 05:01:52 +09:00
Yu Watanabe
57a272902a udev: use flock() when updating device node symlinks
By locking the stack directory, we can safely determine the device node
with the highest priority for a symlink. So, the multiple try-and-wait
loops can be dropped, and the code becomes quite simple.
2022-09-03 05:01:52 +09:00
Yu Watanabe
541a463fd5 udev: make node_symlink() accept NULL devname 2022-09-03 05:01:52 +09:00
Yu Watanabe
d6595c5ced udev: use path_make_relative_parent() 2022-09-03 05:01:52 +09:00
Yu Watanabe
6b01e2905c udev: rename link_find_prioritized() and variables
Also shorten code a bit.

Just for consistency with other part and readability of the code.
2022-09-03 05:01:52 +09:00
Yu Watanabe
faadf97500 udev: use readlinkat_malloc()
And try to read it only when the file is symlink.
2022-09-03 05:01:52 +09:00
Yu Watanabe
a28d67a903 udev: do not remove stack directory even if it is empty
Then, we can always assume the directory exists, and the code become
slightly simpler.

Note, unused directories are removed by the main udevd process in a
later commit.
2022-09-03 05:01:51 +09:00
Yu Watanabe
7e7c36fbbb udev: split link_update() and introduce stack_directory_get_name()
No functionality is changed.
2022-09-03 05:01:51 +09:00
Yu Watanabe
b9168275c3 udev: move udev_node_escape_path()
No functionality is changed.
2022-09-03 05:01:51 +09:00
Lennart Poettering
03bc11d1c4 mac: rework labelling code to be simpler, and less racy
This merges the various labelling calls into a single label_fix_full(),
which can operate on paths, on inode fds, and in a dirfd/fname style
(i.e. like openat()). It also systematically separates the path to look
up in the db from the path we actually use to reference the inode to
relabel.

This then ports tmpfiles over to labelling by fd. This should make the
code a bit less racy, as we'll try hard to always operate on the very
same inode, pinning it via an fd.

User-visibly the behaviour should not change.
2022-07-08 17:43:49 +02:00
Lennart Poettering
7176f06c9e basic: split out dev_t related calls into new devno-util.[ch]
No actual code changes, just splitting out of some dev_t handling
related calls from stat-util.[ch], they are quite a number already, and
deserve their own module now I think.

Also, try to settle on the name "devnum" as the name for the concept,
instead of "devno" or "dev" or "devid". "devnum" is the name exported in
udev APIs, hence probably best to stick to that. (this just renames a
few symbols to "devum", local variables are left untouched, to make the
patch not too invasive)

No actual code changes.
2022-04-13 16:26:31 +02:00
Yu Watanabe
26dd37f6d5 udev: move apply_static_dev_perms() to udev-node.c
and make it internally use udev_node_apply_permissions_impl().
2022-04-06 14:52:36 +09:00
Yu Watanabe
e5ddfe3ec5 udev: upgrade mode in udev_node_apply_permissions_impl() 2022-04-06 14:46:13 +09:00
Yu Watanabe
a782f2a3fc udev: split udev_node_apply_permissions() into two 2022-04-06 14:46:13 +09:00
Yu Watanabe
f14aa5ad42 udev: drop unnecessary code
Follow-up for 78e278ad48.
2022-04-06 14:46:13 +09:00
Yu Watanabe
78e278ad48 udev: use sd_device_open() where appropriate 2022-04-01 15:21:05 +09:00
Zbigniew Jędrzejewski-Szmek
c7f0d9e5ac tree-wide: make FOREACH_DIRENT_ALL define the iterator variable
The variable is not useful outside of the loop (it'll always be null
after the loop is finished), so we can declare it inline in the loop.
This saves one variable declaration and reduces the chances that somebody
tries to use the variable outside of the loop.

For consistency, 'de' is used everywhere for the var name.
2021-12-15 16:19:13 +01:00
Lennart Poettering
35cd0ba516 shared: clean up mkdir.h/label.h situation
Previously the mkdir_label() family of calls was implemented in
src/shared/mkdir-label.c but its functions partly declared ins
src/shared/label.h and partly in src/basic/mkdir.h (!!). That's weird
(and wrong).

Let's clean this up, and add a proper mkdir-label.h matching the .c
file.
2021-11-16 17:03:28 +01:00
Lennart Poettering
7c248223eb tree-wide: use new RET_NERRNO() helper at various places 2021-11-16 08:04:09 +01:00
Yu Watanabe
0706cdf4ec udev-node: do not ignore unexpected errors on removing symlink in stack directory
Only acceptable error here is -ENOENT.
2021-09-12 16:14:44 +09:00
Yu Watanabe
3df566a667 udev-node: simplify the example of race 2021-09-12 16:05:51 +09:00
Yu Watanabe
7920d0a135 udev-node: drop redundant trial of devlink creation
Previously, the devlink was created based on the priority saved in udev
database. So, we needed to reevaluate devlinks after database is saved.

But now the priority is stored in the symlink under /run/udev/links, and
the loop of devlink creation is controlled with the timestamp of the
directory. So, the double evaluation is not necessary anymore.
2021-09-02 09:06:25 +09:00
Yu Watanabe
0063fa23a1 udev-node: add random delay on conflict in updating device node symlink
To make multiple workers not update the same device node symlink
simultaneously.
2021-09-02 09:06:24 +09:00
Yu Watanabe
8424da2de8 udev-node: shorten code a bit and update log message 2021-09-02 09:06:24 +09:00
Yu Watanabe
1cd4e32569 udev-node: check stack directory change even if devlink is removed
Otherwise, when multiple device additions and removals occur
simultaneously, symlink to unexisting devnode may be created.

Hopefully fixes #19946.
2021-09-02 09:06:24 +09:00
Yu Watanabe
242d39ebc1 udev-node: always atomically create symlink to device node
By the previous commit, it is not necessary to distinguish if the devlink
already exists. Also, I cannot find any significant advantages of the
previous complecated logic, that is, first try to create directly, and then
fallback to atomically creation. Moreover, such logic increases the chance
of conflicts between multiple udev workers.

This makes devlinks always created atomically. Hopefully, this reduces the
conflicts between the workers.
2021-09-02 09:06:24 +09:00
Yu Watanabe
8f27311eb2 udev-node: assume no new claim to a symlink if /run/udev/links is not updated
During creating a symlink to a device node, if another device node which
requests the same symlink is added/removed, `stat_inode_unmodified()`
should always detects that. We do not need to continue the loop
unconditionally.
2021-09-02 09:06:24 +09:00
Yu Watanabe
6df797f75f udev-node: always update timestamp of stack directory
Please see the comments in the code.
2021-09-02 09:06:08 +09:00
Yu Watanabe
377a83f0d8 udev-node: save information about device node and priority in symlink
Previously, we only store device IDs in /run/udev/links, and when
creating/removing device node symlink, we create sd_device object
corresponds to the IDs and read device node and priority from the
object. That requires parsing uevent and udev database files.

This makes link_find_prioritized() get the most prioritzed device node
without parsing the files.
2021-09-02 08:30:51 +09:00
Yu Watanabe
46070dbf26 udev-node: stack directory must exist when adding device node symlink 2021-09-02 08:30:51 +09:00
Yu Watanabe
2f48561e0d udev-node: split out permission handling from udev_node_add()
And then merge udev_node_add() and udev_node_update_old_links().
2021-09-02 08:30:51 +09:00
Yu Watanabe
2bb0227165 udev: always use last 11 chars for hash string
This makes the last 11 chars are always preserved for hashed string.
So, it is hard to generate a path which conflicts to another path.

Fixes an issue demonstrated in the previous commit.
2021-06-04 22:31:24 +09:00