]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-monitor.c
Merge pull request #10538 from poettering/tmpfiles-reorder
[thirdparty/systemd.git] / src / libudev / libudev-monitor.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <poll.h>
5
6 #include "libudev.h"
7
8 #include "alloc-util.h"
9 #include "device-monitor-private.h"
10 #include "device-private.h"
11 #include "device-util.h"
12 #include "libudev-device-internal.h"
13 #include "string-util.h"
14
15 /**
16 * SECTION:libudev-monitor
17 * @short_description: device event source
18 *
19 * Connects to a device event source.
20 */
21
22 /**
23 * udev_monitor:
24 *
25 * Opaque object handling an event source.
26 */
27 struct udev_monitor {
28 struct udev *udev;
29 unsigned n_ref;
30 sd_device_monitor *monitor;
31 };
32
33 static 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;
41 }
42
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
52 * "kernel" events, because the devices might not be useable
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 **/
65 _public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name) {
66 _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL;
67 struct udev_monitor *udev_monitor;
68 MonitorNetlinkGroup g;
69 int r;
70
71 g = monitor_netlink_group_from_string(name);
72 if (g < 0) {
73 errno = EINVAL;
74 return NULL;
75 }
76
77 r = device_monitor_new_full(&m, g, -1);
78 if (r < 0) {
79 errno = -r;
80 return NULL;
81 }
82
83 udev_monitor = new(struct udev_monitor, 1);
84 if (!udev_monitor) {
85 errno = ENOMEM;
86 return NULL;
87 }
88
89 *udev_monitor = (struct udev_monitor) {
90 .udev = udev,
91 .n_ref = 1,
92 .monitor = TAKE_PTR(m),
93 };
94
95 return udev_monitor;
96 }
97
98 /**
99 * udev_monitor_filter_update:
100 * @udev_monitor: monitor
101 *
102 * Update the installed socket filter. This is only needed,
103 * if the filter was removed or changed.
104 *
105 * Returns: 0 on success, otherwise a negative error value.
106 */
107 _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) {
108 assert_return(udev_monitor, -EINVAL);
109
110 return sd_device_monitor_filter_update(udev_monitor->monitor);
111 }
112
113 /**
114 * udev_monitor_enable_receiving:
115 * @udev_monitor: the monitor which should receive events
116 *
117 * Binds the @udev_monitor socket to the event source.
118 *
119 * Returns: 0 on success, otherwise a negative error value.
120 */
121 _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) {
122 assert_return(udev_monitor, -EINVAL);
123
124 return device_monitor_enable_receiving(udev_monitor->monitor);
125 }
126
127 /**
128 * udev_monitor_set_receive_buffer_size:
129 * @udev_monitor: the monitor which should receive events
130 * @size: the size in bytes
131 *
132 * Set the size of the kernel socket buffer. This call needs the
133 * appropriate privileges to succeed.
134 *
135 * Returns: 0 on success, otherwise -1 on error.
136 */
137 _public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size) {
138 assert_return(udev_monitor, -EINVAL);
139
140 return sd_device_monitor_set_receive_buffer_size(udev_monitor->monitor, (size_t) size);
141 }
142
143 static struct udev_monitor *udev_monitor_free(struct udev_monitor *udev_monitor) {
144 assert(udev_monitor);
145
146 sd_device_monitor_unref(udev_monitor->monitor);
147 return mfree(udev_monitor);
148 }
149
150 /**
151 * udev_monitor_ref:
152 * @udev_monitor: udev monitor
153 *
154 * Take a reference of a udev monitor.
155 *
156 * Returns: the passed udev monitor
157 **/
158
159 /**
160 * udev_monitor_unref:
161 * @udev_monitor: udev monitor
162 *
163 * Drop a reference of a udev monitor. If the refcount reaches zero,
164 * the bound socket will be closed, and the resources of the monitor
165 * will be released.
166 *
167 * Returns: #NULL
168 **/
169 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_monitor, udev_monitor, udev_monitor_free);
170
171 /**
172 * udev_monitor_get_udev:
173 * @udev_monitor: udev monitor
174 *
175 * Retrieve the udev library context the monitor was created with.
176 *
177 * Returns: the udev library context
178 **/
179 _public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) {
180 assert_return(udev_monitor, NULL);
181
182 return udev_monitor->udev;
183 }
184
185 /**
186 * udev_monitor_get_fd:
187 * @udev_monitor: udev monitor
188 *
189 * Retrieve the socket file descriptor associated with the monitor.
190 *
191 * Returns: the socket file descriptor
192 **/
193 _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) {
194 assert_return(udev_monitor, -EINVAL);
195
196 return device_monitor_get_fd(udev_monitor->monitor);
197 }
198
199 static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) {
200 struct pollfd pfd;
201 int r;
202
203 assert(udev_monitor);
204 assert(ret);
205
206 pfd = (struct pollfd) {
207 .fd = device_monitor_get_fd(udev_monitor->monitor),
208 .events = POLLIN,
209 };
210
211 for (;;) {
212 /* r == 0 means a device is received but it does not pass the current filter. */
213 r = device_monitor_receive_device(udev_monitor->monitor, ret);
214 if (r != 0)
215 return r;
216
217 for (;;) {
218 /* wait next message */
219 r = poll(&pfd, 1, 0);
220 if (r < 0) {
221 if (IN_SET(errno, EINTR, EAGAIN))
222 continue;
223
224 return -errno;
225 } else if (r == 0)
226 return -EAGAIN;
227
228 /* receive next message */
229 break;
230 }
231 }
232 }
233
234 /**
235 * udev_monitor_receive_device:
236 * @udev_monitor: udev monitor
237 *
238 * Receive data from the udev monitor socket, allocate a new udev
239 * device, fill in the received data, and return the device.
240 *
241 * Only socket connections with uid=0 are accepted.
242 *
243 * The monitor socket is by default set to NONBLOCK. A variant of poll() on
244 * the file descriptor returned by udev_monitor_get_fd() should to be used to
245 * wake up when new devices arrive, or alternatively the file descriptor
246 * switched into blocking mode.
247 *
248 * The initial refcount is 1, and needs to be decremented to
249 * release the resources of the udev device.
250 *
251 * Returns: a new udev device, or #NULL, in case of an error
252 **/
253 _public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor) {
254 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
255 int r;
256
257 assert_return(udev_monitor, NULL);
258
259 r = udev_monitor_receive_sd_device(udev_monitor, &device);
260 if (r < 0) {
261 errno = -r;
262 return NULL;
263 }
264
265 return udev_device_new(udev_monitor->udev, device);
266 }
267
268 /**
269 * udev_monitor_filter_add_match_subsystem_devtype:
270 * @udev_monitor: the monitor
271 * @subsystem: the subsystem value to match the incoming devices against
272 * @devtype: the devtype value to match the incoming devices against
273 *
274 * This filter is efficiently executed inside the kernel, and libudev subscribers
275 * will usually not be woken up for devices which do not match.
276 *
277 * The filter must be installed before the monitor is switched to listening mode.
278 *
279 * Returns: 0 on success, otherwise a negative error value.
280 */
281 _public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype) {
282 assert_return(udev_monitor, -EINVAL);
283
284 return sd_device_monitor_filter_add_match_subsystem_devtype(udev_monitor->monitor, subsystem, devtype);
285 }
286
287 /**
288 * udev_monitor_filter_add_match_tag:
289 * @udev_monitor: the monitor
290 * @tag: the name of a tag
291 *
292 * This filter is efficiently executed inside the kernel, and libudev subscribers
293 * will usually not be woken up for devices which do not match.
294 *
295 * The filter must be installed before the monitor is switched to listening mode.
296 *
297 * Returns: 0 on success, otherwise a negative error value.
298 */
299 _public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag) {
300 assert_return(udev_monitor, -EINVAL);
301
302 return sd_device_monitor_filter_add_match_tag(udev_monitor->monitor, tag);
303 }
304
305 /**
306 * udev_monitor_filter_remove:
307 * @udev_monitor: monitor
308 *
309 * Remove all filters from monitor.
310 *
311 * Returns: 0 on success, otherwise a negative error value.
312 */
313 _public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor) {
314 assert_return(udev_monitor, -EINVAL);
315
316 return sd_device_monitor_filter_remove(udev_monitor->monitor);
317 }