]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-enumerate.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
6 Copyright 2015 Tom Gundersen <teg@jklm.no>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
33 #include "sd-device.h"
35 #include "alloc-util.h"
36 #include "device-enumerator-private.h"
37 #include "device-util.h"
38 #include "libudev-device-internal.h"
41 * SECTION:libudev-enumerate
42 * @short_description: lookup and sort sys devices
44 * Lookup devices in the sys filesystem, filter devices by properties,
45 * and return a sorted list of devices.
51 * Opaque object representing one device lookup/sort context.
53 struct udev_enumerate
{
56 struct udev_list devices_list
;
57 bool devices_uptodate
:1;
59 sd_device_enumerator
*enumerator
;
64 * @udev: udev library context
66 * Create an enumeration context to scan /sys.
68 * Returns: an enumeration context.
70 _public_
struct udev_enumerate
*udev_enumerate_new(struct udev
*udev
) {
71 _cleanup_free_
struct udev_enumerate
*udev_enumerate
= NULL
;
72 struct udev_enumerate
*ret
;
75 assert_return_errno(udev
, NULL
, EINVAL
);
77 udev_enumerate
= new0(struct udev_enumerate
, 1);
78 if (!udev_enumerate
) {
83 r
= sd_device_enumerator_new(&udev_enumerate
->enumerator
);
89 r
= sd_device_enumerator_allow_uninitialized(udev_enumerate
->enumerator
);
95 udev_enumerate
->refcount
= 1;
96 udev_enumerate
->udev
= udev
;
98 udev_list_init(udev
, &udev_enumerate
->devices_list
, false);
100 ret
= udev_enumerate
;
101 udev_enumerate
= NULL
;
107 * udev_enumerate_ref:
108 * @udev_enumerate: context
110 * Take a reference of a enumeration context.
112 * Returns: the passed enumeration context
114 _public_
struct udev_enumerate
*udev_enumerate_ref(struct udev_enumerate
*udev_enumerate
) {
116 udev_enumerate
->refcount
++;
118 return udev_enumerate
;
122 * udev_enumerate_unref:
123 * @udev_enumerate: context
125 * Drop a reference of an enumeration context. If the refcount reaches zero,
126 * all resources of the enumeration context will be released.
130 _public_
struct udev_enumerate
*udev_enumerate_unref(struct udev_enumerate
*udev_enumerate
) {
131 if (udev_enumerate
&& (-- udev_enumerate
->refcount
) == 0) {
132 udev_list_cleanup(&udev_enumerate
->devices_list
);
133 sd_device_enumerator_unref(udev_enumerate
->enumerator
);
134 free(udev_enumerate
);
141 * udev_enumerate_get_udev:
142 * @udev_enumerate: context
144 * Get the udev library context.
146 * Returns: a pointer to the context.
148 _public_
struct udev
*udev_enumerate_get_udev(struct udev_enumerate
*udev_enumerate
) {
149 assert_return_errno(udev_enumerate
, NULL
, EINVAL
);
151 return udev_enumerate
->udev
;
155 * udev_enumerate_get_list_entry:
156 * @udev_enumerate: context
158 * Get the first entry of the sorted list of device paths.
160 * Returns: a udev_list_entry.
162 _public_
struct udev_list_entry
*udev_enumerate_get_list_entry(struct udev_enumerate
*udev_enumerate
) {
163 struct udev_list_entry
*e
;
165 assert_return_errno(udev_enumerate
, NULL
, EINVAL
);
167 if (!udev_enumerate
->devices_uptodate
) {
170 udev_list_cleanup(&udev_enumerate
->devices_list
);
172 FOREACH_DEVICE_AND_SUBSYSTEM(udev_enumerate
->enumerator
, device
) {
176 r
= sd_device_get_syspath(device
, &syspath
);
182 udev_list_entry_add(&udev_enumerate
->devices_list
, syspath
, NULL
);
185 udev_enumerate
->devices_uptodate
= true;
188 e
= udev_list_get_entry(&udev_enumerate
->devices_list
);
196 * udev_enumerate_add_match_subsystem:
197 * @udev_enumerate: context
198 * @subsystem: filter for a subsystem of the device to include in the list
200 * Match only devices belonging to a certain kernel subsystem.
202 * Returns: 0 on success, otherwise a negative error value.
204 _public_
int udev_enumerate_add_match_subsystem(struct udev_enumerate
*udev_enumerate
, const char *subsystem
) {
205 assert_return(udev_enumerate
, -EINVAL
);
210 return sd_device_enumerator_add_match_subsystem(udev_enumerate
->enumerator
, subsystem
, true);
214 * udev_enumerate_add_nomatch_subsystem:
215 * @udev_enumerate: context
216 * @subsystem: filter for a subsystem of the device to exclude from the list
218 * Match only devices not belonging to a certain kernel subsystem.
220 * Returns: 0 on success, otherwise a negative error value.
222 _public_
int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate
*udev_enumerate
, const char *subsystem
) {
223 assert_return(udev_enumerate
, -EINVAL
);
228 return sd_device_enumerator_add_match_subsystem(udev_enumerate
->enumerator
, subsystem
, false);
232 * udev_enumerate_add_match_sysattr:
233 * @udev_enumerate: context
234 * @sysattr: filter for a sys attribute at the device to include in the list
235 * @value: optional value of the sys attribute
237 * Match only devices with a certain /sys device attribute.
239 * Returns: 0 on success, otherwise a negative error value.
241 _public_
int udev_enumerate_add_match_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
, true);
251 * udev_enumerate_add_nomatch_sysattr:
252 * @udev_enumerate: context
253 * @sysattr: filter for a sys attribute at the device to exclude from the list
254 * @value: optional value of the sys attribute
256 * Match only devices not having a certain /sys device attribute.
258 * Returns: 0 on success, otherwise a negative error value.
260 _public_
int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate
*udev_enumerate
, const char *sysattr
, const char *value
) {
261 assert_return(udev_enumerate
, -EINVAL
);
266 return sd_device_enumerator_add_match_sysattr(udev_enumerate
->enumerator
, sysattr
, value
, false);
270 * udev_enumerate_add_match_property:
271 * @udev_enumerate: context
272 * @property: filter for a property of the device to include in the list
273 * @value: value of the property
275 * Match only devices with a certain property.
277 * Returns: 0 on success, otherwise a negative error value.
279 _public_
int udev_enumerate_add_match_property(struct udev_enumerate
*udev_enumerate
, const char *property
, const char *value
) {
280 assert_return(udev_enumerate
, -EINVAL
);
285 return sd_device_enumerator_add_match_property(udev_enumerate
->enumerator
, property
, value
);
289 * udev_enumerate_add_match_tag:
290 * @udev_enumerate: context
291 * @tag: filter for a tag of the device to include in the list
293 * Match only devices with a certain tag.
295 * Returns: 0 on success, otherwise a negative error value.
297 _public_
int udev_enumerate_add_match_tag(struct udev_enumerate
*udev_enumerate
, const char *tag
) {
298 assert_return(udev_enumerate
, -EINVAL
);
303 return sd_device_enumerator_add_match_tag(udev_enumerate
->enumerator
, tag
);
307 * udev_enumerate_add_match_parent:
308 * @udev_enumerate: context
309 * @parent: parent device where to start searching
311 * Return the devices on the subtree of one given device. The parent
312 * itself is included in the list.
314 * A reference for the device is held until the udev_enumerate context
317 * Returns: 0 on success, otherwise a negative error value.
319 _public_
int udev_enumerate_add_match_parent(struct udev_enumerate
*udev_enumerate
, struct udev_device
*parent
) {
320 assert_return(udev_enumerate
, -EINVAL
);
325 return sd_device_enumerator_add_match_parent(udev_enumerate
->enumerator
, parent
->device
);
329 * udev_enumerate_add_match_is_initialized:
330 * @udev_enumerate: context
332 * Match only devices which udev has set up already. This makes
333 * sure, that the device node permissions and context are properly set
334 * and that network devices are fully renamed.
336 * Usually, devices which are found in the kernel but not already
337 * handled by udev, have still pending events. Services should subscribe
338 * to monitor events and wait for these devices to become ready, instead
339 * of using uninitialized devices.
341 * For now, this will not affect devices which do not have a device node
342 * and are not network interfaces.
344 * Returns: 0 on success, otherwise a negative error value.
346 _public_
int udev_enumerate_add_match_is_initialized(struct udev_enumerate
*udev_enumerate
) {
347 assert_return(udev_enumerate
, -EINVAL
);
349 return device_enumerator_add_match_is_initialized(udev_enumerate
->enumerator
);
353 * udev_enumerate_add_match_sysname:
354 * @udev_enumerate: context
355 * @sysname: filter for the name of the device to include in the list
357 * Match only devices with a given /sys device name.
359 * Returns: 0 on success, otherwise a negative error value.
361 _public_
int udev_enumerate_add_match_sysname(struct udev_enumerate
*udev_enumerate
, const char *sysname
) {
362 assert_return(udev_enumerate
, -EINVAL
);
367 return sd_device_enumerator_add_match_sysname(udev_enumerate
->enumerator
, sysname
);
371 * udev_enumerate_add_syspath:
372 * @udev_enumerate: context
373 * @syspath: path of a device
375 * Add a device to the list of devices, to retrieve it back sorted in dependency order.
377 * Returns: 0 on success, otherwise a negative error value.
379 _public_
int udev_enumerate_add_syspath(struct udev_enumerate
*udev_enumerate
, const char *syspath
) {
380 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
383 assert_return(udev_enumerate
, -EINVAL
);
388 r
= sd_device_new_from_syspath(&device
, syspath
);
392 r
= device_enumerator_add_device(udev_enumerate
->enumerator
, device
);
400 * udev_enumerate_scan_devices:
401 * @udev_enumerate: udev enumeration context
403 * Scan /sys for all devices which match the given filters. No matches
404 * will return all currently available devices.
406 * Returns: 0 on success, otherwise a negative error value.
408 _public_
int udev_enumerate_scan_devices(struct udev_enumerate
*udev_enumerate
) {
409 assert_return(udev_enumerate
, -EINVAL
);
411 return device_enumerator_scan_devices(udev_enumerate
->enumerator
);
415 * udev_enumerate_scan_subsystems:
416 * @udev_enumerate: udev enumeration context
418 * Scan /sys for all kernel subsystems, including buses, classes, drivers.
420 * Returns: 0 on success, otherwise a negative error value.
422 _public_
int udev_enumerate_scan_subsystems(struct udev_enumerate
*udev_enumerate
) {
423 assert_return(udev_enumerate
, -EINVAL
);
425 return device_enumerator_scan_subsystems(udev_enumerate
->enumerator
);