Commit Graph

407 Commits

Author SHA1 Message Date
Yu Watanabe b2d9e58f78 udev: introduce log_device_uevent() helper function
And this drops duplicated check for seqnum and device action.
2020-12-10 12:26:19 +09:00
Yu Watanabe 481f24d1f6 udev: drop meaningless size optimization
These objects are not allocated multiple times simultaneously per
single process.
2020-12-10 12:18:30 +09:00
Lennart Poettering 1c36b8bf53 log: add helper set sets log level in all realms
Prompted-by: #17903
2020-12-09 18:26:17 +01:00
Zbigniew Jędrzejewski-Szmek 44ee03d111 tree-wide: unsetenv cannot fail
... when called with a valid environment variable name. This means that
any time we call it with a fixed string, it is guaranteed to return 0.
(Also when the variable is not present in the environment block.)
2020-11-10 15:52:32 +01:00
Yu Watanabe f13467ec23 license: GPL-2.0+ -> GPL-2.0-or-later 2020-11-09 13:25:50 +09:00
Lennart Poettering b8380cc67a udev: make sure to install an inotify watch whenever we find a block device locked
This fixes a race where a block device that pops up and immediately is
locked (such as a loopback device in preparation) might result in
udev never run any rules for it, and thus never turn on inotify watching
for it (as inotify watching is controlled via an option set via udev
rules), thus not noticing when the device is unlocked/closed again
(which is noticed via IN_CLOSE_WRITE inotify events).

This changes two things:

1. Whenever we encounter a locked block device we'll now inotify watch
   it, so that it is guaranteed we'll notice when the BSD lock fd is
   closed again, and will reprobe.

2. We'll now turn off inotify watching again once we realise the
   udev rules don't actually want that. Previously, once watching a
   device was enabled via a udev rule, it would be watched forever until
   the device disappeared, even if the option was dropped by the rules
   for later events.

Together this will make sure that we'll watch the device via inotify
in both of the following cases:

a) The block device has been BSD locked when udev wanted to look at it

b) The udev rules run for the last seen event for the device say so

In all other cases inotify is off for block devices.

This new behaviour both fixes the race, but also makes the most sense,
as the rules (when they are run) actually really control the watch state
now. And if someone BSD locks a block device then it should be OK to
inotify watch it briefly until the lock is released again as the user
this way more or less opts into the locking protocol.
2020-10-09 13:22:29 +02:00
Franck Bui 64a3494c3d udev: rename kernel option 'log_priority' into 'log_level'
Let's be consistent with the rest of the project.

'log_priority' is still supported for backward compatibility.
2020-09-22 09:05:57 +02:00
Yu Watanabe e77f52e5f9 udev: warn if failed to set buffer size for device monitor 2020-09-09 06:46:54 +09:00
Zbigniew Jędrzejewski-Szmek 90e74a66e6 tree-wide: define iterator inside of the macro 2020-09-08 12:14:05 +02:00
Christian Göttsche 2df2152c20 selinux: fork label-aware children with up-to-date label database
The parent process may not perform any label operation, so the
database might not get updated on a SELinux policy change on its own.

Reload the label database once on a policy change, instead of n times
in every started child.
2020-08-27 10:28:53 +02:00
Lennart Poettering 39cf0351c5 tree-wide: make use of new relative time events in sd-event.h 2020-07-28 11:24:55 +02:00
Frantisek Sumsal cb713f1696 tree-wide: spellcheck fixes
Most of them were reported by Fossies.org
2020-06-26 22:33:56 +02:00
Lennart Poettering f49bead3b0
Merge pull request #16257 from keszybz/two-fuzzer-issues
Two fuzzer issues
2020-06-25 14:40:35 +02:00
Christian Göttsche a9ba0e328f Make failures of mac_selinux_init() fatal 2020-06-23 19:10:07 +02:00
Zbigniew Jędrzejewski-Szmek c238a1f5f1 udev: split rules object creation and loading
The only functional change is to downgrade the log line to avoid double
logging.
2020-06-23 18:04:18 +02:00
Lennart Poettering 6b2229c6c6 udev: set fewer process properties
On systemd systems we generally don't need to chdir() to root, we don't
need to setup /dev/ ourselves (as PID 1 does that during earliest boot),
and we don't need to set the OOM adjustment values, as that's done via
unit files.

Hence, drop this. if people want to use udev from other init systems
they should do this on their own, I am very sure it's a good thing to do
it from outside of udevd, so that fewer privileges are required by udevd. In
particular the dev_setup() stuff is something that people who build
their own non-systemd distros want to set up themselves anyway, in
particular as they already have to mount devtmpfs themselves anyway.

Note that this only drops stuff that isn't really necessary for testing
stuff, i.e. process properties and settings that don't matter if you
quickly want to invoke udev from a terminal session to test something.
2020-06-09 15:40:20 +02:00
Lennart Poettering fe56acd8e0 udevd: use cpus_in_affinity_mask()
Let's make use of our own helpers. This has the benefit that we can deal
with arbitrarily sized affinity masks.
2020-06-09 15:39:53 +02:00
Lennart Poettering 95ac523030 udev: optionally mark all block devices read-only as they pop up 2020-06-08 16:53:37 +02:00
Michal Sekletár e209926778 udev: make signal that we use to kill workers on timeout configurable 2020-06-05 11:09:17 +02:00
Norbert Lange 63e2d1714e udev: single binary replacing udevd and udevadm
Since the separate binaries contain mostly the same code,
this almost halves the size of the installation.

before:
398K /bin/udevadm
391K /lib/systemd/systemd-udevd

after:
431K /bin/udevadm
0    /lib/systemd/systemd-udevd -> ../../bin/udevadm

Fixes: #14200
2020-06-01 09:41:21 +02:00
Zbigniew Jędrzejewski-Szmek d1109e12c0 udevd: update snippet string
Repeating the unit name in the description is not useful, and "manages devices"
is too cryptic.
2020-05-30 17:15:20 +02:00
Lennart Poettering 5abee64ed4 udev: when the BSD lock on a block device is taken, don't complain
if someone implements https://systemd.io/BLOCK_DEVICE_LOCKING/ then we
shouldn't loudly complain about that.

This reverts back to the original behaviour from
3ebdb81ef088afd3b4c72b516beb5610f8c93a0d: when the lock is taken we
silently skip processing the device and sending out the messages for it.
2020-05-27 15:30:48 +02:00
Lennart Poettering fb29cdbef2 tree-wide: make sure our control buffers are properly aligned
We always need to make them unions with a "struct cmsghdr" in them, so
that things properly aligned. Otherwise we might end up at an unaligned
address and the counting goes all wrong, possibly making the kernel
refuse our buffers.

Also, let's make sure we initialize the control buffers to zero when
sending, but leave them uninitialized when reading.

Both the alignment and the initialization thing is mentioned in the
cmsg(3) man page.
2020-05-07 14:39:44 +02:00
Lennart Poettering 371d72e05b socket-util: introduce type-safe, dereferencing wrapper CMSG_FIND_DATA around cmsg_find()
let's take this once step further, and add type-safety to cmsg_find(),
and imply the CMSG_DATA() macro for finding the cmsg payload.
2020-04-23 19:41:15 +02:00
Lennart Poettering 3691bcf3c5 tree-wide: use recvmsg_safe() at various places
Let's be extra careful whenever we return from recvmsg() and see
MSG_CTRUNC set. This generally means we ran into a programming error, as
we didn't size the control buffer large enough. It's an error condition
we should at least log about, or propagate up. Hence do that.

This is particularly important when receiving fds, since for those the
control data can be of any size. In particular on stream sockets that's
nasty, because if we miss an fd because of control data truncation we
cannot recover, we might not even realize that we are one off.

(Also, when failing early, if there's any chance the socket might be
AF_UNIX let's close all received fds, all the time. We got this right
most of the time, but there were a few cases missing. God, UNIX is hard
to use)
2020-04-23 09:41:47 +02:00
Uwe Kleine-König 7600dbb870 udev: add debug logs for delaying and delegation of events
Up to now each uevent logs the following things at debug level:

 - Device is queued
 - Processing device
 - Device processed

However when the device is queued it might still have to wait for
earlier devices to be processed before being able to start being
processed itself. When analysing logs this dependency information is
quite cruicial, so add respective debug log calls.
2020-03-11 08:44:32 +01:00
Franck Bui 1ffadeaae3 udev: assume that the recv buffer size of the netlink socket is already configured when the socket is passed in
This makes ReceiveBuffer= option in systemd-udevd-kernel.socket unit useful.
2020-01-28 22:35:08 +01:00
Martin Wilck 030f457167 udevd: don't use monitor after manager_exit()
If udevd receives an exit signal, it releases its reference on the udev
monitor in manager_exit(). If at this time a worker is hanging, and if
the event timeout for this worker expires before udevd exits, udevd
crashes in on_sigchld()->udev_monitor_send_device(), because the monitor
has already been freed.

Fix this by testing the validity of manager->monitor in on_sigchld().
2019-11-26 20:38:28 +01:00
Martin Wilck 3cabdc2345 Revert "udevd: fix crash when workers time out after exit is signal caught"
This reverts commit 5db454b8031c58a743cc4ee3d5d1dd01dcff17e8.
See https://github.com/systemd/systemd/issues/14128
2019-11-26 20:38:28 +01:00
Martin Wilck 7b6596d748 udevd: fix crash when workers time out after exit is signal caught
If udevd receives an exit signal, it releases its reference on the udev
monitor in manager_exit(). If at this time a worker is hanging, and if
the event timeout for this worker expires before udevd exits, udevd
crashes in on_sigchld()->udev_monitor_send_device(), because the monitor
has already been freed.

Fix this by releasing the main process's monitor ref later, in
manager_free().
2019-11-12 16:43:42 +01:00
Martin Wilck bfde9421af udevd: wait for workers to finish when exiting
On some systems with lots of devices, device probing for certain drivers can
take a very long time. If systemd-udevd detects a timeout and kills the worker
running modprobe using SIGKILL, some devices will not be probed, or end up in
unusable state. The --event-timeout option can be used to modify the maximum
time spent in an uevent handler. But if systemd-udevd exits, it uses a
different timeout, hard-coded to 30s, and exits when this timeout expires,
causing all workers to be KILLed by systemd afterwards. In practice, this may
lead to workers being killed after significantly less time than specified with
the event-timeout. This is particularly significant during initrd processing:
systemd-udevd will be stopped by systemd when initrd-switch-root.target is
about to be isolated, which usually happens quickly after finding and mounting
the root FS.

If systemd-udevd is started by PID 1 (i.e. basically always), systemd will
kill both udevd and the workers after expiry of TimeoutStopSec. This is
actually better than the built-in udevd timeout, because it's more transparent
and configurable for users. This way users can avoid the mentioned boot problem
by simply increasing StopTimeoutSec= in systemd-udevd.service.

If udevd is not started by systemd (standalone), this is still an
improvement. udevd will kill hanging workers when the event timeout is
reached, which is configurable via the udev.event_timeout= kernel
command line parameter. Before this patch, udevd would simply exit with
workers still running, which would then become zombie processes.

With the timeout removed, the sd_event_now() assertion in manager_exit() can be
dropped.
2019-11-12 12:20:20 +01:00
Yu Watanabe 021cdf8330 tree-wide: drop signal.h when signal-util.h is included 2019-11-04 00:30:32 +09:00
Yu Watanabe 92133d2878 tree-wide: drop socket.h when socket-util.h is included 2019-11-04 00:30:32 +09:00
Yu Watanabe 455fa9610c tree-wide: drop string.h when string-util.h or friends are included 2019-11-04 00:30:32 +09:00
Zbigniew Jędrzejewski-Szmek 0584b17a8c udevd: add helper with error handling to synthesize "change" events
Coverity was unhappy that we ignore the return value from write_string_file().
We should at least warn. CID#1302373.
2019-07-12 00:17:47 +02:00
Zbigniew Jędrzejewski-Szmek 6b413782df udevd: open log output early
We'd log to the "console", losing structured logs during configuration file parsing.
Let's be nice to journalctl users, and log to the journal immediately.
2019-07-04 10:36:30 +02:00
Lubomir Rintel f053fc337e udevd: fix a reversed conditional on global property set
# udevadm control --property=HELLO=WORLD
  Received udev control message (ENV), unsetting 'HELLO'
  # udevadm control --property=HELLO=
  Received udev control message (ENV), setting 'HELLO='

Oh no, it's busted. Let's try removing this one little negation real quick
to see if it helps...

  # udevadm control --property=HELLO=WORLD
  Received udev control message (ENV), setting 'HELLO=WORLD'
  # udevadm control --property=HELLO=
  Received udev control message (ENV), unsetting 'HELLO'

Feels much better now.
2019-06-25 10:20:48 +09:00
Yu Watanabe 99058cd66a udev: propagate errors in udev_event_execute_rules()
And do not set initialized flag to the device.
2019-06-05 10:44:17 +02:00
Yu Watanabe 25de7aa7b9 udev: modernize udev-rules.c
This does the following:
- rename enum udev_builtin_cmd -> UdevBuiltinCmd
- rename struct udev_builtin -> UdevBuiltin
- move type definitions to udev-rules.h
- move prototypes of functions defined in udev-rules.c to udev-rules.h
- drop to use strbuf
- propagate critical errors in applying rules,
- drop limitation for number of tokens per line.
2019-06-02 14:15:26 +09:00
Franck Bui 88bd5a32e8 udevd: change the default value of udev.children-max (again)
Follow-up for faae64fa3d, which increased the
default number of udev workers per cpu regardless of how big the system is.

It's not really clear from the commit message if the new number of workers
improved the overall time for the boot process or only reduced the number of
times the max number of children limit was reached (and in this case
5406c36844 commit might have been more appropriate in the first place).

But systems with ~1000 CPUs are not rare these days and the worker numbers get
quite large with CPU factor of 8. Spawning more than 2000 workers can't be
healthy on any system, no matter how big.

Indeed the main mistake is the belief that udev is CPU-intensive, and thus the
number of allowed workers has to increase with the number of CPUs. It is not,
at probably has never been. It's I/O bound, and sometimes, bound by resources
such as locks.

This is an argument to:

 - scale only weakly with the number of CPUs, and the rationale to switch back
   to a scale factor C=2 but with a higher offset number which should affect
   systems with a small number of CPUs only. With this patch applied the offset
   is increased from O=8 to O=16.

 - put an absolute maximum limit to make sure no more than 2048 workers are
   spawned no matter how big the system is.

This still provides more workers for the laptop cases (where the number of CPUs
is limited), while avoiding sky-rocketing numbers for big systems.

Note that on most desktop systems, the memory limit will kick in. The following
table collects numbers about children-max. For each scenario, the first column
is the "cpu_limit" limit, and the second number is the minimum amount of memory
for the "cpu_limit" limit to become relevant (with less RAM, memory will limit
the number of children thus "mem_limit" will become the active limit).

       |    > v240    |    < v240     |  this patch   |
 CPUs  | C = 8, O = 8 | C = 2, O = 8  | C = 2, O = 16 |
-------------------------------------------------------
   1   |   16      2  |   10    1.3   |   18       2  |
   2   |   24      3  |   12    1.5   |   20       2  |
   4   |   40      5  |   16      2   |   24       3  |
   8   |   72      9  |   24      3   |   32       4  |
  16   |  136     17  |   40      5   |   48       5  |
  64   |  520     65  |  136     17   |  144      18  |
1024   | 8200   1025  | 2056    263   | 2048     256  |
2048   |16392   2049  | 4104    513   | 2048     256  |

This patch is mainly based on Martin Wilck's analyze and comments.
2019-05-16 23:09:41 +02:00
Franck Bui 5406c36844 udevd: notify when max number value of children is reached only once per batch of events
When booting with "udev.log-priority=debug" for example, the output might be
spammed with messages like this:

    systemd-udevd[23545]: maximum number (248) of children reached
    systemd-udevd[23545]: maximum number (248) of children reached
    systemd-udevd[23545]: maximum number (248) of children reached
    systemd-udevd[23545]: maximum number (248) of children reached
    systemd-udevd[23545]: maximum number (248) of children reached
    systemd-udevd[23545]: maximum number (248) of children reached
    systemd-udevd[23545]: maximum number (248) of children reached

While the message itself is useful, printing it per batch of events should be
enough.
2019-04-26 09:58:12 +02:00
Yu Watanabe 76e62a4d22 udev: move udev_ctrl_cleanup() into manager_free() 2019-04-01 15:20:03 +02:00
Lennart Poettering eefc66aa8f util: split out some stuff into a new file limits-util.[ch] 2019-03-13 12:16:43 +01:00
Yu Watanabe d4d690facd udevd: use device_get_action() and device_get_seqnum() 2019-03-12 03:49:53 +09:00
Yu Watanabe d02c6f5461 udev-ctrl: use sd_event and introduce udev_ctrl_start()
Now the new callback function get enum udev_ctrl_msg_type.
So, this commit also drops udev_ctrl_connection and udev_ctrl_msg.
2019-02-20 06:17:42 +09:00
Yu Watanabe 204e9c3e29 udev: drop unused Manager::uevent_event 2019-02-20 06:17:42 +09:00
Yu Watanabe 100bc5bf98 udev-ctrl: make udev_ctrl_new() return negative errno on failure 2019-02-20 06:17:42 +09:00
Lennart Poettering bbd8598f8b
Merge pull request #11589 from yuwata/udevd-is-device-busy
udevd: refactoring is_device_busy()
2019-02-15 12:16:37 +01:00
Yu Watanabe 31cbd20253 udev: check whether systemd is running, and do not use cg_kill() if not
Fixes #11645.
2019-02-13 17:07:56 +01:00
Yu Watanabe 8671411668 udevd: save the result of devnum or ifindex blocker 2019-01-29 14:07:21 +01:00