]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-enumerate.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright © 2008-2012 Kay Sievers <kay@vrfy.org>
4 Copyright © 2015 Tom Gundersen <teg@jklm.no>
18 #include "sd-device.h"
20 #include "alloc-util.h"
21 #include "device-enumerator-private.h"
22 #include "device-util.h"
23 #include "libudev-device-internal.h"
26 * SECTION:libudev-enumerate
27 * @short_description: lookup and sort sys devices
29 * Lookup devices in the sys filesystem, filter devices by properties,
30 * and return a sorted list of devices.
36 * Opaque object representing one device lookup/sort context.
38 struct udev_enumerate
{
41 struct udev_list devices_list
;
42 bool devices_uptodate
:1;
44 sd_device_enumerator
*enumerator
;
49 * @udev: udev library context
51 * Create an enumeration context to scan /sys.
53 * Returns: an enumeration context.
55 _public_
struct udev_enumerate
*udev_enumerate_new(struct udev
*udev
) {
56 _cleanup_free_
struct udev_enumerate
*udev_enumerate
= NULL
;
59 assert_return_errno(udev
, NULL
, EINVAL
);
61 udev_enumerate
= new0(struct udev_enumerate
, 1);
62 if (!udev_enumerate
) {
67 r
= sd_device_enumerator_new(&udev_enumerate
->enumerator
);
73 r
= sd_device_enumerator_allow_uninitialized(udev_enumerate
->enumerator
);
79 udev_enumerate
->refcount
= 1;
80 udev_enumerate
->udev
= udev
;
82 udev_list_init(udev
, &udev_enumerate
->devices_list
, false);
84 return TAKE_PTR(udev_enumerate
);
89 * @udev_enumerate: context
91 * Take a reference of a enumeration context.
93 * Returns: the passed enumeration context
95 _public_
struct udev_enumerate
*udev_enumerate_ref(struct udev_enumerate
*udev_enumerate
) {
97 udev_enumerate
->refcount
++;
99 return udev_enumerate
;
103 * udev_enumerate_unref:
104 * @udev_enumerate: context
106 * Drop a reference of an enumeration context. If the refcount reaches zero,
107 * all resources of the enumeration context will be released.
111 _public_
struct udev_enumerate
*udev_enumerate_unref(struct udev_enumerate
*udev_enumerate
) {
112 if (udev_enumerate
&& (-- udev_enumerate
->refcount
) == 0) {
113 udev_list_cleanup(&udev_enumerate
->devices_list
);
114 sd_device_enumerator_unref(udev_enumerate
->enumerator
);
115 free(udev_enumerate
);
122 * udev_enumerate_get_udev:
123 * @udev_enumerate: context
125 * Get the udev library context.
127 * Returns: a pointer to the context.
129 _public_
struct udev
*udev_enumerate_get_udev(struct udev_enumerate
*udev_enumerate
) {
130 assert_return_errno(udev_enumerate
, NULL
, EINVAL
);
132 return udev_enumerate
->udev
;
136 * udev_enumerate_get_list_entry:
137 * @udev_enumerate: context
139 * Get the first entry of the sorted list of device paths.
141 * Returns: a udev_list_entry.
143 _public_
struct udev_list_entry
*udev_enumerate_get_list_entry(struct udev_enumerate
*udev_enumerate
) {
144 struct udev_list_entry
*e
;
146 assert_return_errno(udev_enumerate
, NULL
, EINVAL
);
148 if (!udev_enumerate
->devices_uptodate
) {
151 udev_list_cleanup(&udev_enumerate
->devices_list
);
153 FOREACH_DEVICE_AND_SUBSYSTEM(udev_enumerate
->enumerator
, device
) {
157 r
= sd_device_get_syspath(device
, &syspath
);
163 udev_list_entry_add(&udev_enumerate
->devices_list
, syspath
, NULL
);
166 udev_enumerate
->devices_uptodate
= true;
169 e
= udev_list_get_entry(&udev_enumerate
->devices_list
);
177 * udev_enumerate_add_match_subsystem:
178 * @udev_enumerate: context
179 * @subsystem: filter for a subsystem of the device to include in the list
181 * Match only devices belonging to a certain kernel subsystem.
183 * Returns: 0 on success, otherwise a negative error value.
185 _public_
int udev_enumerate_add_match_subsystem(struct udev_enumerate
*udev_enumerate
, const char *subsystem
) {
186 assert_return(udev_enumerate
, -EINVAL
);
191 return sd_device_enumerator_add_match_subsystem(udev_enumerate
->enumerator
, subsystem
, true);
195 * udev_enumerate_add_nomatch_subsystem:
196 * @udev_enumerate: context
197 * @subsystem: filter for a subsystem of the device to exclude from the list
199 * Match only devices not belonging to a certain kernel subsystem.
201 * Returns: 0 on success, otherwise a negative error value.
203 _public_
int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate
*udev_enumerate
, const char *subsystem
) {
204 assert_return(udev_enumerate
, -EINVAL
);
209 return sd_device_enumerator_add_match_subsystem(udev_enumerate
->enumerator
, subsystem
, false);
213 * udev_enumerate_add_match_sysattr:
214 * @udev_enumerate: context
215 * @sysattr: filter for a sys attribute at the device to include in the list
216 * @value: optional value of the sys attribute
218 * Match only devices with a certain /sys device attribute.
220 * Returns: 0 on success, otherwise a negative error value.
222 _public_
int udev_enumerate_add_match_sysattr(struct udev_enumerate
*udev_enumerate
, const char *sysattr
, const char *value
) {
223 assert_return(udev_enumerate
, -EINVAL
);
228 return sd_device_enumerator_add_match_sysattr(udev_enumerate
->enumerator
, sysattr
, value
, true);
232 * udev_enumerate_add_nomatch_sysattr:
233 * @udev_enumerate: context
234 * @sysattr: filter for a sys attribute at the device to exclude from the list
235 * @value: optional value of the sys attribute
237 * Match only devices not having a certain /sys device attribute.
239 * Returns: 0 on success, otherwise a negative error value.
241 _public_
int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate
*udev_enumerate
, const char *sysattr
, const char *value
) {
242 assert_return(udev_enumerate
, -EINVAL
);
247 return sd_device_enumerator_add_match_sysattr(udev_enumerate
->enumerator
, sysattr
, value
, false);
251 * udev_enumerate_add_match_property:
252 * @udev_enumerate: context
253 * @property: filter for a property of the device to include in the list
254 * @value: value of the property
256 * Match only devices with a certain property.
258 * Returns: 0 on success, otherwise a negative error value.
260 _public_
int udev_enumerate_add_match_property(struct udev_enumerate
*udev_enumerate
, const char *property
, const char *value
) {
261 assert_return(udev_enumerate
, -EINVAL
);
266 return sd_device_enumerator_add_match_property(udev_enumerate
->enumerator
, property
, value
);
270 * udev_enumerate_add_match_tag:
271 * @udev_enumerate: context
272 * @tag: filter for a tag of the device to include in the list
274 * Match only devices with a certain tag.
276 * Returns: 0 on success, otherwise a negative error value.
278 _public_
int udev_enumerate_add_match_tag(struct udev_enumerate
*udev_enumerate
, const char *tag
) {
279 assert_return(udev_enumerate
, -EINVAL
);
284 return sd_device_enumerator_add_match_tag(udev_enumerate
->enumerator
, tag
);
288 * udev_enumerate_add_match_parent:
289 * @udev_enumerate: context
290 * @parent: parent device where to start searching
292 * Return the devices on the subtree of one given device. The parent
293 * itself is included in the list.
295 * A reference for the device is held until the udev_enumerate context
298 * Returns: 0 on success, otherwise a negative error value.
300 _public_
int udev_enumerate_add_match_parent(struct udev_enumerate
*udev_enumerate
, struct udev_device
*parent
) {
301 assert_return(udev_enumerate
, -EINVAL
);
306 return sd_device_enumerator_add_match_parent(udev_enumerate
->enumerator
, parent
->device
);
310 * udev_enumerate_add_match_is_initialized:
311 * @udev_enumerate: context
313 * Match only devices which udev has set up already. This makes
314 * sure, that the device node permissions and context are properly set
315 * and that network devices are fully renamed.
317 * Usually, devices which are found in the kernel but not already
318 * handled by udev, have still pending events. Services should subscribe
319 * to monitor events and wait for these devices to become ready, instead
320 * of using uninitialized devices.
322 * For now, this will not affect devices which do not have a device node
323 * and are not network interfaces.
325 * Returns: 0 on success, otherwise a negative error value.
327 _public_
int udev_enumerate_add_match_is_initialized(struct udev_enumerate
*udev_enumerate
) {
328 assert_return(udev_enumerate
, -EINVAL
);
330 return device_enumerator_add_match_is_initialized(udev_enumerate
->enumerator
);
334 * udev_enumerate_add_match_sysname:
335 * @udev_enumerate: context
336 * @sysname: filter for the name of the device to include in the list
338 * Match only devices with a given /sys device name.
340 * Returns: 0 on success, otherwise a negative error value.
342 _public_
int udev_enumerate_add_match_sysname(struct udev_enumerate
*udev_enumerate
, const char *sysname
) {
343 assert_return(udev_enumerate
, -EINVAL
);
348 return sd_device_enumerator_add_match_sysname(udev_enumerate
->enumerator
, sysname
);
352 * udev_enumerate_add_syspath:
353 * @udev_enumerate: context
354 * @syspath: path of a device
356 * Add a device to the list of devices, to retrieve it back sorted in dependency order.
358 * Returns: 0 on success, otherwise a negative error value.
360 _public_
int udev_enumerate_add_syspath(struct udev_enumerate
*udev_enumerate
, const char *syspath
) {
361 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
364 assert_return(udev_enumerate
, -EINVAL
);
369 r
= sd_device_new_from_syspath(&device
, syspath
);
373 r
= device_enumerator_add_device(udev_enumerate
->enumerator
, device
);
381 * udev_enumerate_scan_devices:
382 * @udev_enumerate: udev enumeration context
384 * Scan /sys for all devices which match the given filters. No matches
385 * will return all currently available devices.
387 * Returns: 0 on success, otherwise a negative error value.
389 _public_
int udev_enumerate_scan_devices(struct udev_enumerate
*udev_enumerate
) {
390 assert_return(udev_enumerate
, -EINVAL
);
392 return device_enumerator_scan_devices(udev_enumerate
->enumerator
);
396 * udev_enumerate_scan_subsystems:
397 * @udev_enumerate: udev enumeration context
399 * Scan /sys for all kernel subsystems, including buses, classes, drivers.
401 * Returns: 0 on success, otherwise a negative error value.
403 _public_
int udev_enumerate_scan_subsystems(struct udev_enumerate
*udev_enumerate
) {
404 assert_return(udev_enumerate
, -EINVAL
);
406 return device_enumerator_scan_subsystems(udev_enumerate
->enumerator
);