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 "libudev-device-internal.h"
33 #include "sd-device.h"
34 #include "device-util.h"
35 #include "device-enumerator-private.h"
39 * SECTION:libudev-enumerate
40 * @short_description: lookup and sort sys devices
42 * Lookup devices in the sys filesystem, filter devices by properties,
43 * and return a sorted list of devices.
49 * Opaque object representing one device lookup/sort context.
51 struct udev_enumerate
{
54 struct udev_list devices_list
;
55 bool devices_uptodate
:1;
57 sd_device_enumerator
*enumerator
;
62 * @udev: udev library context
64 * Create an enumeration context to scan /sys.
66 * Returns: an enumeration context.
68 _public_
struct udev_enumerate
*udev_enumerate_new(struct udev
*udev
) {
69 _cleanup_free_
struct udev_enumerate
*udev_enumerate
= NULL
;
70 struct udev_enumerate
*ret
;
73 assert_return_errno(udev
, NULL
, EINVAL
);
75 udev_enumerate
= new0(struct udev_enumerate
, 1);
76 if (!udev_enumerate
) {
81 r
= sd_device_enumerator_new(&udev_enumerate
->enumerator
);
87 r
= sd_device_enumerator_allow_uninitialized(udev_enumerate
->enumerator
);
93 udev_enumerate
->refcount
= 1;
94 udev_enumerate
->udev
= udev
;
96 udev_list_init(udev
, &udev_enumerate
->devices_list
, false);
99 udev_enumerate
= NULL
;
105 * udev_enumerate_ref:
106 * @udev_enumerate: context
108 * Take a reference of a enumeration context.
110 * Returns: the passed enumeration context
112 _public_
struct udev_enumerate
*udev_enumerate_ref(struct udev_enumerate
*udev_enumerate
) {
114 udev_enumerate
->refcount
++;
116 return udev_enumerate
;
120 * udev_enumerate_unref:
121 * @udev_enumerate: context
123 * Drop a reference of an enumeration context. If the refcount reaches zero,
124 * all resources of the enumeration context will be released.
128 _public_
struct udev_enumerate
*udev_enumerate_unref(struct udev_enumerate
*udev_enumerate
) {
129 if (udev_enumerate
&& (-- udev_enumerate
->refcount
) == 0) {
130 udev_list_cleanup(&udev_enumerate
->devices_list
);
131 sd_device_enumerator_unref(udev_enumerate
->enumerator
);
132 free(udev_enumerate
);
139 * udev_enumerate_get_udev:
140 * @udev_enumerate: context
142 * Get the udev library context.
144 * Returns: a pointer to the context.
146 _public_
struct udev
*udev_enumerate_get_udev(struct udev_enumerate
*udev_enumerate
) {
147 assert_return_errno(udev_enumerate
, NULL
, EINVAL
);
149 return udev_enumerate
->udev
;
153 * udev_enumerate_get_list_entry:
154 * @udev_enumerate: context
156 * Get the first entry of the sorted list of device paths.
158 * Returns: a udev_list_entry.
160 _public_
struct udev_list_entry
*udev_enumerate_get_list_entry(struct udev_enumerate
*udev_enumerate
) {
161 assert_return_errno(udev_enumerate
, NULL
, EINVAL
);
163 if (!udev_enumerate
->devices_uptodate
) {
166 udev_list_cleanup(&udev_enumerate
->devices_list
);
168 FOREACH_DEVICE_AND_SUBSYSTEM(udev_enumerate
->enumerator
, device
) {
172 r
= sd_device_get_syspath(device
, &syspath
);
178 udev_list_entry_add(&udev_enumerate
->devices_list
, syspath
, NULL
);
181 udev_enumerate
->devices_uptodate
= true;
184 return udev_list_get_entry(&udev_enumerate
->devices_list
);
188 * udev_enumerate_add_match_subsystem:
189 * @udev_enumerate: context
190 * @subsystem: filter for a subsystem of the device to include in the list
192 * Match only devices belonging to a certain kernel subsystem.
194 * Returns: 0 on success, otherwise a negative error value.
196 _public_
int udev_enumerate_add_match_subsystem(struct udev_enumerate
*udev_enumerate
, const char *subsystem
) {
197 assert_return(udev_enumerate
, -EINVAL
);
199 return sd_device_enumerator_add_match_subsystem(udev_enumerate
->enumerator
, subsystem
, true);
203 * udev_enumerate_add_nomatch_subsystem:
204 * @udev_enumerate: context
205 * @subsystem: filter for a subsystem of the device to exclude from the list
207 * Match only devices not belonging to a certain kernel subsystem.
209 * Returns: 0 on success, otherwise a negative error value.
211 _public_
int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate
*udev_enumerate
, const char *subsystem
) {
212 assert_return(udev_enumerate
, -EINVAL
);
214 return sd_device_enumerator_add_match_subsystem(udev_enumerate
->enumerator
, subsystem
, false);
218 * udev_enumerate_add_match_sysattr:
219 * @udev_enumerate: context
220 * @sysattr: filter for a sys attribute at the device to include in the list
221 * @value: optional value of the sys attribute
223 * Match only devices with a certain /sys device attribute.
225 * Returns: 0 on success, otherwise a negative error value.
227 _public_
int udev_enumerate_add_match_sysattr(struct udev_enumerate
*udev_enumerate
, const char *sysattr
, const char *value
) {
228 assert_return(udev_enumerate
, -EINVAL
);
230 return sd_device_enumerator_add_match_sysattr(udev_enumerate
->enumerator
, sysattr
, value
, true);
234 * udev_enumerate_add_nomatch_sysattr:
235 * @udev_enumerate: context
236 * @sysattr: filter for a sys attribute at the device to exclude from the list
237 * @value: optional value of the sys attribute
239 * Match only devices not having a certain /sys device attribute.
241 * Returns: 0 on success, otherwise a negative error value.
243 _public_
int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate
*udev_enumerate
, const char *sysattr
, const char *value
) {
244 assert_return(udev_enumerate
, -EINVAL
);
246 return sd_device_enumerator_add_match_sysattr(udev_enumerate
->enumerator
, sysattr
, value
, false);
250 * udev_enumerate_add_match_property:
251 * @udev_enumerate: context
252 * @property: filter for a property of the device to include in the list
253 * @value: value of the property
255 * Match only devices with a certain property.
257 * Returns: 0 on success, otherwise a negative error value.
259 _public_
int udev_enumerate_add_match_property(struct udev_enumerate
*udev_enumerate
, const char *property
, const char *value
) {
260 assert_return(udev_enumerate
, -EINVAL
);
262 return sd_device_enumerator_add_match_property(udev_enumerate
->enumerator
, property
, value
);
266 * udev_enumerate_add_match_tag:
267 * @udev_enumerate: context
268 * @tag: filter for a tag of the device to include in the list
270 * Match only devices with a certain tag.
272 * Returns: 0 on success, otherwise a negative error value.
274 _public_
int udev_enumerate_add_match_tag(struct udev_enumerate
*udev_enumerate
, const char *tag
) {
275 assert_return(udev_enumerate
, -EINVAL
);
277 return sd_device_enumerator_add_match_tag(udev_enumerate
->enumerator
, tag
);
281 * udev_enumerate_add_match_parent:
282 * @udev_enumerate: context
283 * @parent: parent device where to start searching
285 * Return the devices on the subtree of one given device. The parent
286 * itself is included in the list.
288 * A reference for the device is held until the udev_enumerate context
291 * Returns: 0 on success, otherwise a negative error value.
293 _public_
int udev_enumerate_add_match_parent(struct udev_enumerate
*udev_enumerate
, struct udev_device
*parent
) {
294 assert_return(udev_enumerate
, -EINVAL
);
299 return sd_device_enumerator_add_match_parent(udev_enumerate
->enumerator
, parent
->device
);
303 * udev_enumerate_add_match_is_initialized:
304 * @udev_enumerate: context
306 * Match only devices which udev has set up already. This makes
307 * sure, that the device node permissions and context are properly set
308 * and that network devices are fully renamed.
310 * Usually, devices which are found in the kernel but not already
311 * handled by udev, have still pending events. Services should subscribe
312 * to monitor events and wait for these devices to become ready, instead
313 * of using uninitialized devices.
315 * For now, this will not affect devices which do not have a device node
316 * and are not network interfaces.
318 * Returns: 0 on success, otherwise a negative error value.
320 _public_
int udev_enumerate_add_match_is_initialized(struct udev_enumerate
*udev_enumerate
) {
321 assert_return(udev_enumerate
, -EINVAL
);
323 return device_enumerator_add_match_is_initialized(udev_enumerate
->enumerator
);
327 * udev_enumerate_add_match_sysname:
328 * @udev_enumerate: context
329 * @sysname: filter for the name of the device to include in the list
331 * Match only devices with a given /sys device name.
333 * Returns: 0 on success, otherwise a negative error value.
335 _public_
int udev_enumerate_add_match_sysname(struct udev_enumerate
*udev_enumerate
, const char *sysname
) {
336 assert_return(udev_enumerate
, -EINVAL
);
338 return sd_device_enumerator_add_match_sysname(udev_enumerate
->enumerator
, sysname
);
342 * udev_enumerate_add_syspath:
343 * @udev_enumerate: context
344 * @syspath: path of a device
346 * Add a device to the list of devices, to retrieve it back sorted in dependency order.
348 * Returns: 0 on success, otherwise a negative error value.
350 _public_
int udev_enumerate_add_syspath(struct udev_enumerate
*udev_enumerate
, const char *syspath
) {
351 _cleanup_device_unref_ sd_device
*device
= NULL
;
354 assert_return(udev_enumerate
, -EINVAL
);
359 r
= sd_device_new_from_syspath(&device
, syspath
);
363 r
= device_enumerator_add_device(udev_enumerate
->enumerator
, device
);
371 * udev_enumerate_scan_devices:
372 * @udev_enumerate: udev enumeration context
374 * Scan /sys for all devices which match the given filters. No matches
375 * will return all currently available devices.
377 * Returns: 0 on success, otherwise a negative error value.
379 _public_
int udev_enumerate_scan_devices(struct udev_enumerate
*udev_enumerate
) {
380 assert_return(udev_enumerate
, -EINVAL
);
382 return device_enumerator_scan_devices(udev_enumerate
->enumerator
);
386 * udev_enumerate_scan_subsystems:
387 * @udev_enumerate: udev enumeration context
389 * Scan /sys for all kernel subsystems, including buses, classes, drivers.
391 * Returns: 0 on success, otherwise a negative error value.
393 _public_
int udev_enumerate_scan_subsystems(struct udev_enumerate
*udev_enumerate
) {
394 assert_return(udev_enumerate
, -EINVAL
);
396 return device_enumerator_scan_subsystems(udev_enumerate
->enumerator
);