Commit graph

132 commits

Author SHA1 Message Date
Lennart Poettering 69ce73d18d device: simplify device_found_to_string_many() a tiny bit
No need to maintain a NULL marker at the end of the table if we know the
size of the array anyway.
2018-06-07 15:28:50 +02:00
Lennart Poettering e5ca27b772 udev: add helper udev_device_new_from_stat_rdev()
This is a simple wrapper around udev_device_new_from_devnum(), and uses
the data from a struct stat's .st_rdev field to derive the udev_device
object.
2018-06-07 13:36:19 +02:00
Lennart Poettering 34c20ee09f core: split out device validation from device_found_node()
Let's separate the validate step out. Also, let's update some comments
which have long ceased to be true.

No change in behaviour.
2018-06-07 13:36:19 +02:00
Lennart Poettering 485ae697ba core: rework device_found_node() prototype
let's drop the "now" argument, it's exactly what MANAGER_IS_RUNNING()
returns, hence let's use that instead to simplify things.

Moreover, let's change the add/found argument pair to become found/mask,
which allows us to change multiple flags at the same time into opposing
directions, which will be useful later on.

Also, let's change the return type to void. It's a notifier call where
callers will ignore the return value anyway as it is nothing actionable.

Should not change behaviour.
2018-06-07 13:36:19 +02:00
Lennart Poettering 87934b36b1 core: split out reload propagation into its own function 2018-06-07 13:36:19 +02:00
Lennart Poettering 8bb2c8c94d core: improve error logging a bit 2018-06-07 13:36:19 +02:00
Lennart Poettering 86cdffd106 core: log when unit_add_dependency() fails for some reason
Also, proceed, as there's little we can do in this case.
2018-06-07 13:36:19 +02:00
Lennart Poettering ea8ec43bb5 core: modernize device_update_description() a bit 2018-06-07 13:36:19 +02:00
Lennart Poettering 43ba7d71e5 core: use device_found_to_string_many() result only on success 2018-06-07 13:36:19 +02:00
Lennart Poettering 6e0f878ee2 core: use FLAGS_SET() macro at one more place 2018-06-07 13:36:19 +02:00
Lennart Poettering ccd419f0e7 core: modernize device_set_sysfs() a bit 2018-06-07 13:36:19 +02:00
Lennart Poettering 2ad2e41a72 core: don't trigger OnFailure= deps when a unit is going to restart
This adds a flags parameter to unit_notify() which can be used to pass
additional notification information to the function. We the make the old
reload_failure boolean parameter one of these flags, and then add a new
flag that let's unit_notify() if we are configured to restart the
service.

Note that this adjusts behaviour of systemd to match what the docs say.

Fixes: #8398
2018-06-01 19:08:30 +02:00
Lennart Poettering 6f8fa29465
Merge pull request #8981 from keszybz/ratelimit-and-dbus
Ratelimit renaming and dbus error message fix
2018-05-18 21:38:30 +02:00
Yu Watanabe af4fa99d6a core: use _cleanup_set_free_ instread of _cleanup_(set_freep) 2018-05-14 14:13:57 +09:00
Zbigniew Jędrzejewski-Szmek 7994ac1d85 Rename ratelimit_test to ratelimit_below
When I see "test", I have to think three times what the return value
means. With "below" this is immediately clear. ratelimit_below(&limit)
sounds almost like English and is imho immediately obvious.

(I also considered ratelimit_ok, but this strongly implies that being under the
limit is somehow better. Most of the times this is true, but then we use the
ratelimit to detect triple-c-a-d, and "ok" doesn't fit so well there.)

C.f. a1bcaa07.
2018-05-13 22:08:30 +02:00
David Tardon 95f14a3e21 core: use automatic cleanup more 2018-05-12 18:29:41 +02:00
Zbigniew Jędrzejewski-Szmek 4d86c235b8 core: include Found state in device dumps
In particular, this confirms that the Found state needs to remain a bit-field:

$ systemd-analyze dump |grep 'Found: '|sort |uniq -c
    105 	Found: found-udev
      3 	Found: found-udev,found-mount
      1 	Found: found-udev,found-swap
2018-04-26 10:19:27 +02:00
Yu Watanabe 75d0aba49b device: fix serialization and deserialization of DeviceFound
DeviceFound is a bit flag. So, it is necessary to support the case
that multiple bits are set.

Follow-up for 918e6f1c01.
2018-04-25 22:05:00 +09:00
Lennart Poettering 8e766630f0 tree-wide: drop redundant _cleanup_ macros (#8810)
This drops a good number of type-specific _cleanup_ macros, and patches
all users to just use the generic ones.

In most recent code we abstained from defining type-specific macros, and
this basically removes all those added already, with the exception of
the really low-level ones.

Having explicit macros for this is not too useful, as the expression
without the extra macro is generally just 2ch wider. We should generally
emphesize generic code, unless there are really good reasons for
specific code, hence let's follow this in this case too.

Note that _cleanup_free_ and similar really low-level, libc'ish, Linux
API'ish macros continue to be defined, only the really high-level OO
ones are dropped. From now on this should really be the rule: for really
low-level stuff, such as memory allocation, fd handling and so one, go
ahead and define explicit per-type macros, but for high-level, specific
program code, just use the generic _cleanup_() macro directly, in order
to keep things simple and as readable as possible for the uninitiated.

Note that before this patch some of the APIs (notable libudev ones) were
already used with the high-level macros at some places and with the
generic _cleanup_ macro at others. With this patch we hence unify on the
latter.
2018-04-25 12:31:45 +02:00
Zbigniew Jędrzejewski-Szmek a1bcaa075b core/device: avoid bogus errno use and invert ratelimit_test()
I'm not sure if I understand the original code. AFAICS, errno does not
have to be set at all in this callback.

ratelimit_test() returns positive if we are under limit. The code would only
log if the condition happened very often, which I assume is not inteded, and
this check was supposed to prevent too much logging.
2018-04-24 14:10:27 +02:00
Franck Bui 036d2eefae device: skip deserialization of device units when udevd is not running
Do not try to party initialize a device during deserialization if it's not
known by udev (anymore) and therefore hasn't been seen during device
enumeration.

The device unit in this case has not been initialized properly and setting it
in the "plugged" state can be confusing.

Actually this happens during every boots when PID switches to the new rootfs:
PID is reexecuted and enumerates devices but since udev is not running, the
list of enumerated devices is empty.
2018-04-20 17:49:28 +02:00
Franck Bui 918e6f1c01 device: make sure to always retroactively start device dependencies
PID1 updates the state of device units upon 2 different events:

 - when it processes an event sent by udev and in this case the device deps are
   started if the device enters in the "plugged" state.

 - when it enumerates all devices during its startup or when it is asked to
   reload its configuration data but in this case the device deps (if any) are
   not retroactively started.

When udev processes a new "add" kernel event, it first registers the new device
in its databases then sends an event to systemd.

If for any reason, systemd is asked to reload its configuration between the
previous 2 steps, it might see for the first time the new device while scanning
/sys for all devices. Only during a second step, udev will send the event for
the new device.

In this peculiar case the device deps wont be started (even though the device
is first seen by PID1).

Indeed when reloading its configurations, PID1 will put the device unit in the
"plugged" state but without starting the device deps. Thereafter PID1 will get
the event from udev for the new device but the device unit will be in "plugged"
state already therefore it won't see any need to start the device dependencies.

Rather than assuming that during the reloading of systemd manager configuration
all devices listed in udev DBs have been already processed and should be put in
the "plugged" state (done by device_coldplug()), this patch does that only for
devices which have been processed via an udev event (device_dispatch_io())
previously. In this case we set "d->found" to "DEVICE_FOUND_UDEV" and we make
also sure to no more initialize "d->found" while enumerating devices. Instead
this field is now saved/restored while devices are serialized.
2018-04-20 17:49:28 +02:00
Zbigniew Jędrzejewski-Szmek 11a1589223 tree-wide: drop license boilerplate
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.

I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
2018-04-06 18:58:55 +02:00
Yu Watanabe 66f5730471
core/device: remove unnecessary check (#8661)
Follow-up for 0dfb0a0abd.
2018-04-06 15:45:13 +09:00
Yu Watanabe 0dfb0a0abd core/device: trivial simplification 2018-04-05 14:26:34 +09:00
Zbigniew Jędrzejewski-Szmek 37cbc1d579 When mangling names, optionally emit a warning (#8400)
The warning is not emitted for absolute paths like /dev/sda or /home, which are
converted to .device and .mount unit names without any fuss.

Most of the time it's unlikely that users use invalid unit names on purpose,
so let's warn them. Warnings are silenced when --quiet is used.

$ build/systemctl show -p Id hello@foo-bar/baz
Invalid unit name "hello@foo-bar/baz" was escaped as "hello@foo-bar-baz" (maybe you should use systemd-escape?)
Id=hello@foo-bar-baz.service

$ build/systemd-run --user --slice foo-bar/baz --unit foo-bar/foo true
Invalid unit name "foo-bar/foo" was escaped as "foo-bar-foo" (maybe you should use systemd-escape?)
Invalid unit name "foo-bar/baz" was escaped as "foo-bar-baz" (maybe you should use systemd-escape?)
Running as unit: foo-bar-foo.service

Fixes #8302.
2018-03-21 15:26:47 +01:00
Lennart Poettering 548f69375e tree-wide: use path_hash_ops instead of string_hash_ops whenever we key by a path
Let's make use of our new hash_ops!
2018-02-12 11:07:55 +01:00
Yu Watanabe e61d3d8aae core/device: remove unused variable
Follow-up for bf70ff2cff.
2018-01-24 12:52:23 +09:00
Jérémy Rosen bf70ff2cff fix reload propagation for device alias
udev-made .device aliases are not normal alias

They are full-fledged units which are linked to
the same sysfs path

we need to explicitely propagate reload to all
alias
2018-01-22 19:53:55 +01:00
Zbigniew Jędrzejewski-Szmek 53e1b68390 Add SPDX license identifiers to source files under the LGPL
This follows what the kernel is doing, c.f.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5fd54ace4721fc5ce2bb5aef6318fcf17f421460.
2017-11-19 19:08:15 +01:00
Lennart Poettering dcebc9bae4 core: when a unit template is specified in SYSTEMD_WANTS=, instantiate it with sysfs path
This should make cases like the user's setup in #7109 a lot easier to
handle, as in that case we'll do the right escaping automatically.
2017-11-10 19:52:41 +01:00
Lennart Poettering 38b9b72ec1 core: remove SYSTEMD_WANTS udev property configured dependencies at the right moment
Previously dependencies configured with SYSTEMD_WANTS would be collected
on a device unit as long as it was loaded. let's fix that, and remove
dependencies again when SYTEMD_WANTS changes.
2017-11-10 19:45:29 +01:00
Lennart Poettering de04054349 device: Let's simplify device_add_udev_wants() a bit
Let's drop use of one variable and make the rest more explicit.
2017-11-10 19:45:29 +01:00
Lennart Poettering 40b1a32ca8 device: rework device_is_bound_by_mounts() a bit
Let's log when we can't parse the udev property, and always use the most
precise, correct types.
2017-11-10 19:45:29 +01:00
Lennart Poettering eef85c4a3f core: track why unit dependencies came to be
This replaces the dependencies Set* objects by Hashmap* objects, where
the key is the depending Unit, and the value is a bitmask encoding why
the specific dependency was created.

The bitmask contains a number of different, defined bits, that indicate
why dependencies exist, for example whether they are created due to
explicitly configured deps in files, by udev rules or implicitly.

Note that memory usage is not increased by this change, even though we
store more information, as we manage to encode the bit mask inside the
value pointer each Hashmap entry contains.

Why this all? When we know how a dependency came to be, we can update
dependencies correctly when a configuration source changes but others
are left unaltered. Specifically:

1. We can fix UDEV_WANTS dependency generation: so far we kept adding
   dependencies configured that way, but if a device lost such a
   dependency we couldn't them again as there was no scheme for removing
   of dependencies in place.

2. We can implement "pin-pointed" reload of unit files. If we know what
   dependencies were created as result of configuration in a unit file,
   then we know what to flush out when we want to reload it.

3. It's useful for debugging: "systemd-analyze dump" now shows
   this information, helping substantially with understanding how
   systemd's dependency tree came to be the way it came to be.
2017-11-10 19:45:29 +01:00
Boucman f332611abe device : reload when udev generates a "changed" event (#6850) 2017-11-10 17:00:32 +01:00
Martin Pitt 6d44591141 Revert "device : reload when udev generates a "changed" event" (#6836)
This reverts commit 0ffddc6e2c. That
causes a rather severe disruption of D-Bus and other services when e. g.
restarting local-fs.target (as spotted by the "storage" test regression).

Fixes #6834
2017-09-15 09:21:49 +02:00
Jérémy Rosen 0ffddc6e2c device : reload when udev generates a "changed" event 2017-09-10 18:53:26 +02:00
Franck Bui cc0df6cc35 device: make sure to remove all device units sharing the same sysfs path (#6679)
When a device is unplugged all device units sharing the same sysfs path
pointing to that device are supposed to be removed.

However it didn't work since while iterating the device unit list containing
all the relevant units, each unit was removed during each iteration of
LIST_FOREACH. However LIST_FOREACH doesn't support this use case and
LIST_FOREACH_SAFE must be use instead.
2017-08-30 17:16:16 +02:00
Michal Sekletar 05e33aa1d5 core: unset sysfs path after transition to dead state (#6174)
Device is gone and most likely it will get garbage collected. However in
cases when it doesn't get gc'ed (because it is referenced by some
other unit, e.g. mount from fstab) we need to unset sysfs. This is
because when device appears next time, possibly, with different sysfs
path we need to update the sysfs path. Current code could end up caching
stale sysfs path forever.

In reality this is not a problem for normal disks (unless you swap them
during system runtime). However this issue causes failures to mount
filesystems on LVM where sysfs path depends on activation
order (i.e. logical volumes from volume group that is activated first
get assigned lower dm-X numbers and corresponding syspaths).

Fixes #6126.
2017-06-22 20:29:15 -04:00
Michal Koutný d9732d7803 core/device: Use JobRunningTimeoutSec= for device units
Device job timeouts should respect possible device job dependencies so we set
JobRunningTimeoutSec= by default.
2017-04-25 18:00:36 +02:00
Franck Bui d13489e2be core: make sure to not call device_is_bound_by_mounts() when dev is null (#5033)
device_setup_unit() might be called (when an event happened in
/proc/self/mountinfo for example) with a null 'dev' parameter. This
indicates that the device has been unplugged but the corresponding
mountpoint is still visible in /proc/self/mountinfo.

This patch makes sure we don't call device_is_bound_by_mounts() in
this case.

Fixes: #5025
2017-01-10 09:11:34 +01:00
Franck Bui ebc8968bc0 core: make mount units from /proc/self/mountinfo possibly bind to a device (#4515)
Since commit 9d06297, mount units from mountinfo are not bound to their devices
anymore (they use the "Requires" dependency instead).

This has the following drawback: if a media is mounted and the eject button is
pressed then the media is unconditionally ejected leaving some inconsistent
states.

Since udev is the component that is reacting (no matter if the device is used
or not) to the eject button, users expect that udev at least try to unmount the
media properly.

This patch introduces a new property "SYSTEMD_MOUNT_DEVICE_BOUND". When set on
a block device, all units that requires this device will see their "Requires"
dependency upgraded to a "BindTo" one. This is currently only used by cdrom
devices.

This patch also gives the possibility to the user to restore the previous
behavior that is bind a mount unit to a device. This is achieved by passing the
"x-systemd.device-bound" option to mount(8). Please note that currently this is
not working because libmount treats the x-* options has comments therefore
they're not available in utab for later application retrievals.
2016-12-16 17:13:58 +01:00
Thomas Hindoe Paaboel Andersen 8fb242abc9 core: remove unused variable 2016-12-06 00:09:50 +01:00
Lennart Poettering c9d5c9c0e1 core: make unit_free() accept NULL pointers
We generally try to make our destructors robust regarding NULL pointers, much
in the same way as glibc's free(). Do this also for unit_free().

Follow-up for #4748.
2016-12-01 00:25:51 +01:00
Dave Reisner d112eae7da device: Avoid calling unit_free(NULL) in device setup logic (#4748)
Since a581e45ae8, there's a few function calls to
unit_new_for_name which will unit_free on failure. Prior to this commit,
a failure would result in calling unit_free with a NULL unit, and hit an
assertion failure, seen at least via device_setup_unit:

Assertion 'u' failed at src/core/unit.c:519, function unit_free().  Aborting.

Fixes #4747
https://bugs.archlinux.org/task/51950
2016-11-27 23:05:39 +01:00
Lennart Poettering c5a97ed132 core: GC redundant device jobs from the run queue
In contrast to all other unit types device units when queued just track
external state, they cannot effect state changes on their own. Hence unless a
client or other job waits for them there's no reason to keep them in the job
queue. This adds a concept of GC'ing jobs of this type as soon as no client or
other job waits for them anymore.

To ensure this works correctly we need to track which clients actually
reference a job (i.e. which ones enqueued it). Unfortunately that's pretty
nasty to do for direct connections, as sd_bus_track doesn't work for
them. For now, work around this, by simply remembering in a boolean that a job
was requested by a direct connection, and reset it when we notice the direct
connection is gone. This means the GC logic works fine, except that jobs are
not immediately removed when direct connections disconnect.

In the longer term, a rework of the bus logic should fix this properly. For now
this should be good enough, as GC works for fine all cases except this one, and
thus is a clear improvement over the previous behaviour.

Fixes: #1921
2016-11-16 15:03:26 +01:00
Zbigniew Jędrzejewski-Szmek ceed8f0c8b core/device: port to extract_first_word 2016-11-05 18:54:27 -04:00
Lennart Poettering 493fd52f1a Merge pull request #4510 from keszybz/tree-wide-cleanups
Tree wide cleanups
2016-11-03 13:59:20 -06:00
Lennart Poettering a581e45ae8 unit: unify some code with new unit_new_for_name() call 2016-11-02 11:29:59 -06:00