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