2 This file is part of systemd.
4 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
5 Copyright 2015 Tom Gundersen <teg@jklm.no>
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
32 #include "sd-device.h"
34 #include "alloc-util.h"
35 #include "device-enumerator-private.h"
36 #include "device-util.h"
37 #include "libudev-device-internal.h"
40 * SECTION:libudev-enumerate
41 * @short_description: lookup and sort sys devices
43 * Lookup devices in the sys filesystem, filter devices by properties,
44 * and return a sorted list of devices.
50 * Opaque object representing one device lookup/sort context.
52 struct udev_enumerate
{
55 struct udev_list devices_list
;
56 bool devices_uptodate
:1;
58 sd_device_enumerator
*enumerator
;
63 * @udev: udev library context
65 * Create an enumeration context to scan /sys.
67 * Returns: an enumeration context.
69 _public_
struct udev_enumerate
*udev_enumerate_new(struct udev
*udev
) {
70 _cleanup_free_
struct udev_enumerate
*udev_enumerate
= NULL
;
71 struct udev_enumerate
*ret
;
74 assert_return_errno(udev
, NULL
, EINVAL
);
76 udev_enumerate
= new0(struct udev_enumerate
, 1);
77 if (!udev_enumerate
) {
82 r
= sd_device_enumerator_new(&udev_enumerate
->enumerator
);
88 r
= sd_device_enumerator_allow_uninitialized(udev_enumerate
->enumerator
);
94 udev_enumerate
->refcount
= 1;
95 udev_enumerate
->udev
= udev
;
97 udev_list_init(udev
, &udev_enumerate
->devices_list
, false);
100 udev_enumerate
= NULL
;
106 * udev_enumerate_ref:
107 * @udev_enumerate: context
109 * Take a reference of a enumeration context.
111 * Returns: the passed enumeration context
113 _public_
struct udev_enumerate
*udev_enumerate_ref(struct udev_enumerate
*udev_enumerate
) {
115 udev_enumerate
->refcount
++;
117 return udev_enumerate
;
121 * udev_enumerate_unref:
122 * @udev_enumerate: context
124 * Drop a reference of an enumeration context. If the refcount reaches zero,
125 * all resources of the enumeration context will be released.
129 _public_
struct udev_enumerate
*udev_enumerate_unref(struct udev_enumerate
*udev_enumerate
) {
130 if (udev_enumerate
&& (-- udev_enumerate
->refcount
) == 0) {
131 udev_list_cleanup(&udev_enumerate
->devices_list
);
132 sd_device_enumerator_unref(udev_enumerate
->enumerator
);
133 free(udev_enumerate
);
140 * udev_enumerate_get_udev:
141 * @udev_enumerate: context
143 * Get the udev library context.
145 * Returns: a pointer to the context.
147 _public_
struct udev
*udev_enumerate_get_udev(struct udev_enumerate
*udev_enumerate
) {
148 assert_return_errno(udev_enumerate
, NULL
, EINVAL
);
150 return udev_enumerate
->udev
;
154 * udev_enumerate_get_list_entry:
155 * @udev_enumerate: context
157 * Get the first entry of the sorted list of device paths.
159 * Returns: a udev_list_entry.
161 _public_
struct udev_list_entry
*udev_enumerate_get_list_entry(struct udev_enumerate
*udev_enumerate
) {
162 assert_return_errno(udev_enumerate
, NULL
, EINVAL
);
164 if (!udev_enumerate
->devices_uptodate
) {
167 udev_list_cleanup(&udev_enumerate
->devices_list
);
169 FOREACH_DEVICE_AND_SUBSYSTEM(udev_enumerate
->enumerator
, device
) {
173 r
= sd_device_get_syspath(device
, &syspath
);
179 udev_list_entry_add(&udev_enumerate
->devices_list
, syspath
, NULL
);
182 udev_enumerate
->devices_uptodate
= true;
185 return udev_list_get_entry(&udev_enumerate
->devices_list
);
189 * udev_enumerate_add_match_subsystem:
190 * @udev_enumerate: context
191 * @subsystem: filter for a subsystem of the device to include in the list
193 * Match only devices belonging to a certain kernel subsystem.
195 * Returns: 0 on success, otherwise a negative error value.
197 _public_
int udev_enumerate_add_match_subsystem(struct udev_enumerate
*udev_enumerate
, const char *subsystem
) {
198 assert_return(udev_enumerate
, -EINVAL
);
203 return sd_device_enumerator_add_match_subsystem(udev_enumerate
->enumerator
, subsystem
, true);
207 * udev_enumerate_add_nomatch_subsystem:
208 * @udev_enumerate: context
209 * @subsystem: filter for a subsystem of the device to exclude from the list
211 * Match only devices not belonging to a certain kernel subsystem.
213 * Returns: 0 on success, otherwise a negative error value.
215 _public_
int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate
*udev_enumerate
, const char *subsystem
) {
216 assert_return(udev_enumerate
, -EINVAL
);
221 return sd_device_enumerator_add_match_subsystem(udev_enumerate
->enumerator
, subsystem
, false);
225 * udev_enumerate_add_match_sysattr:
226 * @udev_enumerate: context
227 * @sysattr: filter for a sys attribute at the device to include in the list
228 * @value: optional value of the sys attribute
230 * Match only devices with a certain /sys device attribute.
232 * Returns: 0 on success, otherwise a negative error value.
234 _public_
int udev_enumerate_add_match_sysattr(struct udev_enumerate
*udev_enumerate
, const char *sysattr
, const char *value
) {
235 assert_return(udev_enumerate
, -EINVAL
);
240 return sd_device_enumerator_add_match_sysattr(udev_enumerate
->enumerator
, sysattr
, value
, true);
244 * udev_enumerate_add_nomatch_sysattr:
245 * @udev_enumerate: context
246 * @sysattr: filter for a sys attribute at the device to exclude from the list
247 * @value: optional value of the sys attribute
249 * Match only devices not having a certain /sys device attribute.
251 * Returns: 0 on success, otherwise a negative error value.
253 _public_
int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate
*udev_enumerate
, const char *sysattr
, const char *value
) {
254 assert_return(udev_enumerate
, -EINVAL
);
259 return sd_device_enumerator_add_match_sysattr(udev_enumerate
->enumerator
, sysattr
, value
, false);
263 * udev_enumerate_add_match_property:
264 * @udev_enumerate: context
265 * @property: filter for a property of the device to include in the list
266 * @value: value of the property
268 * Match only devices with a certain property.
270 * Returns: 0 on success, otherwise a negative error value.
272 _public_
int udev_enumerate_add_match_property(struct udev_enumerate
*udev_enumerate
, const char *property
, const char *value
) {
273 assert_return(udev_enumerate
, -EINVAL
);
278 return sd_device_enumerator_add_match_property(udev_enumerate
->enumerator
, property
, value
);
282 * udev_enumerate_add_match_tag:
283 * @udev_enumerate: context
284 * @tag: filter for a tag of the device to include in the list
286 * Match only devices with a certain tag.
288 * Returns: 0 on success, otherwise a negative error value.
290 _public_
int udev_enumerate_add_match_tag(struct udev_enumerate
*udev_enumerate
, const char *tag
) {
291 assert_return(udev_enumerate
, -EINVAL
);
296 return sd_device_enumerator_add_match_tag(udev_enumerate
->enumerator
, tag
);
300 * udev_enumerate_add_match_parent:
301 * @udev_enumerate: context
302 * @parent: parent device where to start searching
304 * Return the devices on the subtree of one given device. The parent
305 * itself is included in the list.
307 * A reference for the device is held until the udev_enumerate context
310 * Returns: 0 on success, otherwise a negative error value.
312 _public_
int udev_enumerate_add_match_parent(struct udev_enumerate
*udev_enumerate
, struct udev_device
*parent
) {
313 assert_return(udev_enumerate
, -EINVAL
);
318 return sd_device_enumerator_add_match_parent(udev_enumerate
->enumerator
, parent
->device
);
322 * udev_enumerate_add_match_is_initialized:
323 * @udev_enumerate: context
325 * Match only devices which udev has set up already. This makes
326 * sure, that the device node permissions and context are properly set
327 * and that network devices are fully renamed.
329 * Usually, devices which are found in the kernel but not already
330 * handled by udev, have still pending events. Services should subscribe
331 * to monitor events and wait for these devices to become ready, instead
332 * of using uninitialized devices.
334 * For now, this will not affect devices which do not have a device node
335 * and are not network interfaces.
337 * Returns: 0 on success, otherwise a negative error value.
339 _public_
int udev_enumerate_add_match_is_initialized(struct udev_enumerate
*udev_enumerate
) {
340 assert_return(udev_enumerate
, -EINVAL
);
342 return device_enumerator_add_match_is_initialized(udev_enumerate
->enumerator
);
346 * udev_enumerate_add_match_sysname:
347 * @udev_enumerate: context
348 * @sysname: filter for the name of the device to include in the list
350 * Match only devices with a given /sys device name.
352 * Returns: 0 on success, otherwise a negative error value.
354 _public_
int udev_enumerate_add_match_sysname(struct udev_enumerate
*udev_enumerate
, const char *sysname
) {
355 assert_return(udev_enumerate
, -EINVAL
);
360 return sd_device_enumerator_add_match_sysname(udev_enumerate
->enumerator
, sysname
);
364 * udev_enumerate_add_syspath:
365 * @udev_enumerate: context
366 * @syspath: path of a device
368 * Add a device to the list of devices, to retrieve it back sorted in dependency order.
370 * Returns: 0 on success, otherwise a negative error value.
372 _public_
int udev_enumerate_add_syspath(struct udev_enumerate
*udev_enumerate
, const char *syspath
) {
373 _cleanup_device_unref_ sd_device
*device
= NULL
;
376 assert_return(udev_enumerate
, -EINVAL
);
381 r
= sd_device_new_from_syspath(&device
, syspath
);
385 r
= device_enumerator_add_device(udev_enumerate
->enumerator
, device
);
393 * udev_enumerate_scan_devices:
394 * @udev_enumerate: udev enumeration context
396 * Scan /sys for all devices which match the given filters. No matches
397 * will return all currently available devices.
399 * Returns: 0 on success, otherwise a negative error value.
401 _public_
int udev_enumerate_scan_devices(struct udev_enumerate
*udev_enumerate
) {
402 assert_return(udev_enumerate
, -EINVAL
);
404 return device_enumerator_scan_devices(udev_enumerate
->enumerator
);
408 * udev_enumerate_scan_subsystems:
409 * @udev_enumerate: udev enumeration context
411 * Scan /sys for all kernel subsystems, including buses, classes, drivers.
413 * Returns: 0 on success, otherwise a negative error value.
415 _public_
int udev_enumerate_scan_subsystems(struct udev_enumerate
*udev_enumerate
) {
416 assert_return(udev_enumerate
, -EINVAL
);
418 return device_enumerator_scan_subsystems(udev_enumerate
->enumerator
);