1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
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 "io-util.h"
13 #include "libudev-device-internal.h"
14 #include "string-util.h"
15
16 /**
17 * SECTION:libudev-monitor
18 * @short_description: device event source
19 *
20 * Connects to a device event source.
21 */
22
23 /**
24 * udev_monitor:
25 *
26 * Opaque object handling an event source.
27 */
28 struct udev_monitor {
29 struct udev *udev;
30 unsigned n_ref;
31 sd_device_monitor *monitor;
32 };
33
monitor_netlink_group_from_string(const char * name)34 static 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;
42 }
43
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
53 * "kernel" events, because the devices might not be usable
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 **/
udev_monitor_new_from_netlink(struct udev * udev,const char * name)66 _public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name) {
67 _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL;
68 struct udev_monitor *udev_monitor;
69 MonitorNetlinkGroup g;
70 int r;
71
72 g = monitor_netlink_group_from_string(name);
73 if (g < 0)
74 return_with_errno(NULL, EINVAL);
75
76 r = device_monitor_new_full(&m, g, -1);
77 if (r < 0)
78 return_with_errno(NULL, r);
79
80 udev_monitor = new(struct udev_monitor, 1);
81 if (!udev_monitor)
82 return_with_errno(NULL, ENOMEM);
83
84 *udev_monitor = (struct udev_monitor) {
85 .udev = udev,
86 .n_ref = 1,
87 .monitor = TAKE_PTR(m),
88 };
89
90 return udev_monitor;
91 }
92
93 /**
94 * udev_monitor_filter_update:
95 * @udev_monitor: monitor
96 *
97 * Update the installed socket filter. This is only needed,
98 * if the filter was removed or changed.
99 *
100 * Returns: 0 on success, otherwise a negative error value.
101 */
udev_monitor_filter_update(struct udev_monitor * udev_monitor)102 _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) {
103 assert_return(udev_monitor, -EINVAL);
104
105 return sd_device_monitor_filter_update(udev_monitor->monitor);
106 }
107
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 */
udev_monitor_enable_receiving(struct udev_monitor * udev_monitor)116 _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) {
117 assert_return(udev_monitor, -EINVAL);
118
119 return device_monitor_enable_receiving(udev_monitor->monitor);
120 }
121
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 */
udev_monitor_set_receive_buffer_size(struct udev_monitor * udev_monitor,int size)132 _public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size) {
133 assert_return(udev_monitor, -EINVAL);
134
135 return sd_device_monitor_set_receive_buffer_size(udev_monitor->monitor, (size_t) size);
136 }
137
udev_monitor_free(struct udev_monitor * udev_monitor)138 static struct udev_monitor *udev_monitor_free(struct udev_monitor *udev_monitor) {
139 assert(udev_monitor);
140
141 sd_device_monitor_unref(udev_monitor->monitor);
142 return mfree(udev_monitor);
143 }
144
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 **/
153
154 /**
155 * udev_monitor_unref:
156 * @udev_monitor: udev monitor
157 *
158 * Drop a reference of a udev monitor. If the refcount reaches zero,
159 * the bound socket will be closed, and the resources of the monitor
160 * will be released.
161 *
162 * Returns: #NULL
163 **/
164 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_monitor, udev_monitor, udev_monitor_free);
165
166 /**
167 * udev_monitor_get_udev:
168 * @udev_monitor: udev monitor
169 *
170 * Retrieve the udev library context the monitor was created with.
171 *
172 * Returns: the udev library context
173 **/
udev_monitor_get_udev(struct udev_monitor * udev_monitor)174 _public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) {
175 assert_return(udev_monitor, NULL);
176
177 return udev_monitor->udev;
178 }
179
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 **/
udev_monitor_get_fd(struct udev_monitor * udev_monitor)188 _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) {
189 assert_return(udev_monitor, -EINVAL);
190
191 return device_monitor_get_fd(udev_monitor->monitor);
192 }
193
udev_monitor_receive_sd_device(struct udev_monitor * udev_monitor,sd_device ** ret)194 static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) {
195 int r;
196
197 assert(udev_monitor);
198 assert(ret);
199
200 for (;;) {
201 /* r == 0 means a device is received but it does not pass the current filter. */
202 r = device_monitor_receive_device(udev_monitor->monitor, ret);
203 if (r != 0)
204 return r;
205
206 for (;;) {
207 /* Wait for next message */
208 r = fd_wait_for_event(device_monitor_get_fd(udev_monitor->monitor), POLLIN, 0);
209 if (r == -EINTR)
210 continue;
211 if (r < 0)
212 return r;
213 if (r == 0)
214 return -EAGAIN;
215
216 /* Receive next message */
217 break;
218 }
219 }
220 }
221
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 **/
udev_monitor_receive_device(struct udev_monitor * udev_monitor)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;
244
245 assert_return(udev_monitor, NULL);
246
247 r = udev_monitor_receive_sd_device(udev_monitor, &device);
248 if (r < 0)
249 return_with_errno(NULL, r);
250
251 return udev_device_new(udev_monitor->udev, device);
252 }
253
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
258 * @devtype: the devtype value to match the incoming devices against
259 *
260 * This filter is efficiently executed inside the kernel, and libudev subscribers
261 * will usually not be woken up for devices which do not match.
262 *
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 */
udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor * udev_monitor,const char * subsystem,const char * devtype)267 _public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype) {
268 int r;
269
270 assert_return(udev_monitor, -EINVAL);
271
272 r = sd_device_monitor_filter_add_match_subsystem_devtype(udev_monitor->monitor, subsystem, devtype);
273 return r < 0 ? r : 0;
274 }
275
276 /**
277 * udev_monitor_filter_add_match_tag:
278 * @udev_monitor: the monitor
279 * @tag: the name of a tag
280 *
281 * This filter is efficiently executed inside the kernel, and libudev subscribers
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 */
udev_monitor_filter_add_match_tag(struct udev_monitor * udev_monitor,const char * tag)288 _public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag) {
289 int r;
290
291 assert_return(udev_monitor, -EINVAL);
292
293 r = sd_device_monitor_filter_add_match_tag(udev_monitor->monitor, tag);
294 return r < 0 ? r : 0;
295 }
296
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 */
udev_monitor_filter_remove(struct udev_monitor * udev_monitor)305 _public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor) {
306 assert_return(udev_monitor, -EINVAL);
307
308 return sd_device_monitor_filter_remove(udev_monitor->monitor);
309 }
310