]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libudev/libudev-monitor.c
basic/include: replace _Static_assert() with static_assert()
[thirdparty/systemd.git] / src / libudev / libudev-monitor.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
ba6929f6 2
07630cea 3#include <poll.h>
ba6929f6 4
b4bbcaa9 5#include "libudev.h"
f989d285 6#include "sd-device.h"
b4bbcaa9 7
b5efdb8a 8#include "alloc-util.h"
e39b4d25 9#include "device-monitor-private.h"
f989d285 10#include "errno-util.h"
0f2d351f 11#include "io-util.h"
3782454c 12#include "libudev-device-internal.h"
07630cea 13#include "string-util.h"
ba6929f6 14
ce1d6d7f
KS
15/**
16 * SECTION:libudev-monitor
17 * @short_description: device event source
18 *
19 * Connects to a device event source.
20 */
21
ce1d6d7f
KS
22/**
23 * udev_monitor:
24 *
50579295 25 * Opaque object handling an event source.
ce1d6d7f 26 */
ba6929f6 27struct udev_monitor {
912541b0 28 struct udev *udev;
3c6ac219 29 unsigned n_ref;
e39b4d25 30 sd_device_monitor *monitor;
ba6929f6
KS
31};
32
e39b4d25
YW
33static MonitorNetlinkGroup monitor_netlink_group_from_string(const char *name) {
34 if (!name)
35 return MONITOR_GROUP_NONE;
36 if (streq(name, "udev"))
37 return MONITOR_GROUP_UDEV;
38 if (streq(name, "kernel"))
39 return MONITOR_GROUP_KERNEL;
40 return _MONITOR_NETLINK_GROUP_INVALID;
44daf75d
TG
41}
42
c84954e8
YW
43/**
44 * udev_monitor_new_from_netlink:
45 * @udev: udev library context
46 * @name: name of event source
47 *
48 * Create new udev monitor and connect to a specified event
49 * source. Valid sources identifiers are "udev" and "kernel".
50 *
51 * Applications should usually not connect directly to the
5238e957 52 * "kernel" events, because the devices might not be usable
c84954e8
YW
53 * at that time, before udev has configured them, and created
54 * device nodes. Accessing devices at the same time as udev,
55 * might result in unpredictable behavior. The "udev" events
56 * are sent out after udev has finished its event processing,
57 * all rules have been processed, and needed device nodes are
58 * created.
59 *
60 * The initial refcount is 1, and needs to be decremented to
61 * release the resources of the udev monitor.
62 *
63 * Returns: a new udev monitor, or #NULL, in case of an error
64 **/
9ee08c8d 65_public_ struct udev_monitor* udev_monitor_new_from_netlink(struct udev *udev, const char *name) {
e39b4d25 66 _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL;
5ea78a39 67 struct udev_monitor *udev_monitor;
e39b4d25 68 MonitorNetlinkGroup g;
5e1e4c24
YW
69 int r;
70
e39b4d25 71 g = monitor_netlink_group_from_string(name);
fd05c424
YW
72 if (g < 0)
73 return_with_errno(NULL, EINVAL);
912541b0 74
fd386a6a 75 r = device_monitor_new_full(&m, g, -EBADF);
fd05c424
YW
76 if (r < 0)
77 return_with_errno(NULL, r);
912541b0 78
5e1e4c24 79 udev_monitor = new(struct udev_monitor, 1);
fd05c424
YW
80 if (!udev_monitor)
81 return_with_errno(NULL, ENOMEM);
5e1e4c24
YW
82
83 *udev_monitor = (struct udev_monitor) {
84 .udev = udev,
85 .n_ref = 1,
e39b4d25 86 .monitor = TAKE_PTR(m),
5e1e4c24
YW
87 };
88
5ea78a39 89 return udev_monitor;
1c7047ea
KS
90}
91
ce1d6d7f
KS
92/**
93 * udev_monitor_filter_update:
94 * @udev_monitor: monitor
95 *
50579295
KS
96 * Update the installed socket filter. This is only needed,
97 * if the filter was removed or changed.
ce1d6d7f
KS
98 *
99 * Returns: 0 on success, otherwise a negative error value.
100 */
759d9f3f 101_public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) {
759d9f3f 102 assert_return(udev_monitor, -EINVAL);
912541b0 103
e39b4d25 104 return sd_device_monitor_filter_update(udev_monitor->monitor);
e14bdd88
KS
105}
106
ce1d6d7f
KS
107/**
108 * udev_monitor_enable_receiving:
109 * @udev_monitor: the monitor which should receive events
110 *
f49faf05 111 * Deprecated, and alias of udev_monitor_filter_update().
ce1d6d7f
KS
112 *
113 * Returns: 0 on success, otherwise a negative error value.
114 */
e38242b0 115_public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) {
f49faf05 116 return udev_monitor_filter_update(udev_monitor);
ba6929f6
KS
117}
118
f712894d
KS
119/**
120 * udev_monitor_set_receive_buffer_size:
121 * @udev_monitor: the monitor which should receive events
122 * @size: the size in bytes
123 *
124 * Set the size of the kernel socket buffer. This call needs the
125 * appropriate privileges to succeed.
126 *
127 * Returns: 0 on success, otherwise -1 on error.
128 */
7f9e0395
YW
129_public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size) {
130 assert_return(udev_monitor, -EINVAL);
131
e39b4d25 132 return sd_device_monitor_set_receive_buffer_size(udev_monitor->monitor, (size_t) size);
cb25a958
KS
133}
134
9ee08c8d 135static struct udev_monitor* udev_monitor_free(struct udev_monitor *udev_monitor) {
3c6ac219
YW
136 assert(udev_monitor);
137
e39b4d25 138 sd_device_monitor_unref(udev_monitor->monitor);
3c6ac219
YW
139 return mfree(udev_monitor);
140}
141
7d8787b3
KS
142/**
143 * udev_monitor_ref:
144 * @udev_monitor: udev monitor
145 *
146 * Take a reference of a udev monitor.
147 *
148 * Returns: the passed udev monitor
149 **/
ba6929f6 150
7d8787b3
KS
151/**
152 * udev_monitor_unref:
153 * @udev_monitor: udev monitor
154 *
ff109b8d 155 * Drop a reference of a udev monitor. If the refcount reaches zero,
be7de409 156 * the bound socket will be closed, and the resources of the monitor
7d8787b3
KS
157 * will be released.
158 *
725d7e6c 159 * Returns: #NULL
7d8787b3 160 **/
3c6ac219 161DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_monitor, udev_monitor, udev_monitor_free);
ba6929f6 162
7d8787b3
KS
163/**
164 * udev_monitor_get_udev:
165 * @udev_monitor: udev monitor
166 *
b98fd840 167 * Retrieve the udev library context the monitor was created with.
7d8787b3
KS
168 *
169 * Returns: the udev library context
170 **/
9ee08c8d 171_public_ struct udev* udev_monitor_get_udev(struct udev_monitor *udev_monitor) {
7f9e0395
YW
172 assert_return(udev_monitor, NULL);
173
912541b0 174 return udev_monitor->udev;
ba6929f6
KS
175}
176
7d8787b3
KS
177/**
178 * udev_monitor_get_fd:
179 * @udev_monitor: udev monitor
180 *
181 * Retrieve the socket file descriptor associated with the monitor.
182 *
183 * Returns: the socket file descriptor
184 **/
7f9e0395
YW
185_public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) {
186 assert_return(udev_monitor, -EINVAL);
187
bab889c5 188 return sd_device_monitor_get_fd(udev_monitor->monitor);
ba6929f6
KS
189}
190
c84954e8 191static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) {
23c457a7 192 int r;
ba6929f6 193
e39b4d25 194 assert(udev_monitor);
23c457a7 195 assert(ret);
912541b0 196
23c457a7
YW
197 for (;;) {
198 /* r == 0 means a device is received but it does not pass the current filter. */
bab889c5 199 r = sd_device_monitor_receive(udev_monitor->monitor, ret);
23c457a7
YW
200 if (r != 0)
201 return r;
202
203 for (;;) {
0f2d351f 204 /* Wait for next message */
bab889c5 205 r = fd_wait_for_event(sd_device_monitor_get_fd(udev_monitor->monitor), POLLIN, 0);
1d61d70a
YW
206 if (r == -EINTR)
207 continue;
208 if (r < 0)
0f2d351f 209 return r;
dad28bff 210 if (r == 0)
23c457a7
YW
211 return -EAGAIN;
212
0f2d351f 213 /* Receive next message */
23c457a7
YW
214 break;
215 }
216 }
ba6929f6 217}
9925ab04 218
23c457a7
YW
219/**
220 * udev_monitor_receive_device:
221 * @udev_monitor: udev monitor
222 *
223 * Receive data from the udev monitor socket, allocate a new udev
224 * device, fill in the received data, and return the device.
225 *
226 * Only socket connections with uid=0 are accepted.
227 *
228 * The monitor socket is by default set to NONBLOCK. A variant of poll() on
229 * the file descriptor returned by udev_monitor_get_fd() should to be used to
230 * wake up when new devices arrive, or alternatively the file descriptor
231 * switched into blocking mode.
232 *
233 * The initial refcount is 1, and needs to be decremented to
234 * release the resources of the udev device.
235 *
236 * Returns: a new udev device, or #NULL, in case of an error
237 **/
9ee08c8d 238_public_ struct udev_device* udev_monitor_receive_device(struct udev_monitor *udev_monitor) {
23c457a7
YW
239 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
240 int r;
3782454c 241
23c457a7 242 assert_return(udev_monitor, NULL);
3782454c 243
23c457a7 244 r = udev_monitor_receive_sd_device(udev_monitor, &device);
fd05c424
YW
245 if (r < 0)
246 return_with_errno(NULL, r);
3782454c 247
23c457a7 248 return udev_device_new(udev_monitor->udev, device);
3782454c
YW
249}
250
ce1d6d7f
KS
251/**
252 * udev_monitor_filter_add_match_subsystem_devtype:
253 * @udev_monitor: the monitor
254 * @subsystem: the subsystem value to match the incoming devices against
214a6c79 255 * @devtype: the devtype value to match the incoming devices against
ce1d6d7f 256 *
50579295 257 * This filter is efficiently executed inside the kernel, and libudev subscribers
28460195
KS
258 * will usually not be woken up for devices which do not match.
259 *
ce1d6d7f
KS
260 * The filter must be installed before the monitor is switched to listening mode.
261 *
262 * Returns: 0 on success, otherwise a negative error value.
263 */
759d9f3f 264_public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype) {
0f4b6e59
ZJS
265 int r;
266
759d9f3f 267 assert_return(udev_monitor, -EINVAL);
759d9f3f 268
0f4b6e59
ZJS
269 r = sd_device_monitor_filter_add_match_subsystem_devtype(udev_monitor->monitor, subsystem, devtype);
270 return r < 0 ? r : 0;
e14bdd88 271}
08a7a795 272
28460195
KS
273/**
274 * udev_monitor_filter_add_match_tag:
275 * @udev_monitor: the monitor
276 * @tag: the name of a tag
277 *
50579295 278 * This filter is efficiently executed inside the kernel, and libudev subscribers
28460195
KS
279 * will usually not be woken up for devices which do not match.
280 *
281 * The filter must be installed before the monitor is switched to listening mode.
282 *
283 * Returns: 0 on success, otherwise a negative error value.
284 */
759d9f3f 285_public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag) {
0f4b6e59
ZJS
286 int r;
287
759d9f3f 288 assert_return(udev_monitor, -EINVAL);
759d9f3f 289
0f4b6e59
ZJS
290 r = sd_device_monitor_filter_add_match_tag(udev_monitor->monitor, tag);
291 return r < 0 ? r : 0;
28460195
KS
292}
293
ce1d6d7f
KS
294/**
295 * udev_monitor_filter_remove:
296 * @udev_monitor: monitor
297 *
298 * Remove all filters from monitor.
299 *
300 * Returns: 0 on success, otherwise a negative error value.
301 */
759d9f3f 302_public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor) {
759d9f3f
YW
303 assert_return(udev_monitor, -EINVAL);
304
e39b4d25 305 return sd_device_monitor_filter_remove(udev_monitor->monitor);
08a7a795 306}