Systemd/src/systemd
Lennart Poettering 97ef539169 sd-event: add new API for subscribing to inotify events
This adds a new call sd_event_add_inotify() which allows watching for
inotify events on specified paths.

sd-event will try to minimize the number of inotify fds allocated, and
will try to add file watches to the same inotify fd objects as far as
that's possible. Doing this kind of inotify object should optimize
behaviour in programs that watch a limited set of mostly independent
files as in most cases a single inotify object will suffice for watching
all files.

Traditionally, this kind of coalescing logic (i.e. that multiple event
sources are implemented on top of a single inotify object) was very hard
to do, as the inotify API had serious limitations: it only allowed
adding watches by path, and would implicitly merge watches installed on
the same node via different path, without letting the caller know about
whether such merging took place or not.

With the advent of O_PATH this issue can be dealt with to some point:
instead of adding a path to watch to an inotify object with
inotify_add_watch() right away, we can open the path with O_PATH first,
call fstat() on the fd, and check the .st_dev/.st_ino fields of that
against a list of watches we already have in place. If we find one we
know that the inotify_add_watch() will update the watch mask of the
existing watch, otherwise it will create a new watch. To make this
race-free we use inotify_add_watch() on the /proc/self/fd/ path of the
O_PATH fd, instead of the original path, so that we do the checking and
watch updating with guaranteed the same inode.

This approach let's us deal safely with inodes that may appear under
various different paths (due to symlinks, hardlinks, bind mounts, fs
namespaces). However it's not a perfect solution: currently the kernel
has no API for changing the watch mask of an existing watch -- unless
you have a path or fd to the original inode. This means we can "merge"
the watches of the same inode of multiple event sources correctly, but
we cannot "unmerge" it again correctly in many cases, as access to the
original inode might have been lost, due to renames, mount/unmount, or
deletions. We could in theory always keep open an O_PATH fd of the inode
to watch so that we can change the mask anytime we want, but this is
highly problematics, as it would consume too many fds (and in fact the
scarcity of fds is the reason why watch descriptors are a separate
concepts from fds) and would keep the backing mounts busy (wds do not
keep mounts busy, fds do). The current implemented approach to all this:
filter in userspace and accept that the watch mask on some inode might
be higher than necessary due to earlier installed event sources that
might have ceased to exist. This approach while ugly shouldn't be too
bad for most cases as the same inodes are probably wacthed for the same
masks in most implementations.

In order to implement priorities correctly a seperate inotify object is
allocated for each priority that is used. This way we get separate
per-priority event queues, of which we never dequeue more than a few
events at a time.

Fixes: #3982
2018-06-06 10:53:56 +02:00
..
_sd-common.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
meson.build meson: test out headers with more standard versions 2018-05-28 14:16:37 +02:00
sd-bus-protocol.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-bus-vtable.h ISO-C compatibility: Remove empty initializer (#8713) 2018-04-12 21:31:19 +02:00
sd-bus.h sd-bus: add new sd_bus_slot_set_floating() call 2018-05-30 17:13:51 +02:00
sd-daemon.h core: add a new sd_notify() message for removing fds from the FD store again 2017-11-27 17:04:04 +01:00
sd-device.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-dhcp-client.h networkd: add support to send DHCP user class option (#7499) 2018-05-07 14:21:02 +02:00
sd-dhcp-lease.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-dhcp-server.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-dhcp6-client.h dhcp6: Add functionality to request DHCPv6 IA PD 2018-01-04 15:22:44 +02:00
sd-dhcp6-lease.h dhcp6: Add function to iterate and fetch delegated prefixes 2018-01-04 15:22:44 +02:00
sd-event.h sd-event: add new API for subscribing to inotify events 2018-06-06 10:53:56 +02:00
sd-hwdb.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-id128.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-ipv4acd.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-ipv4ll.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-journal.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-lldp.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-login.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-messages.h Make taint message structured and add catalog entry 2017-12-14 22:14:38 +01:00
sd-ndisc.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00
sd-netlink.h networkd: add support for wireguard interface type 2018-01-09 14:00:49 +01:00
sd-network.h Add a "RequiredForOnline=" Link attribute for .network files (#7347) 2017-11-30 18:03:50 +01:00
sd-path.h systemd-path: allow the default search path to be queried 2018-04-16 16:09:46 +02:00
sd-radv.h radv: Add function to remove prefixes 2018-01-04 15:22:44 +02:00
sd-resolve.h sd-resolve: remove misleading casts 2018-05-22 10:09:55 +02:00
sd-utf8.h Add SPDX license identifiers to source files under the LGPL 2017-11-19 19:08:15 +01:00