]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libudev/libudev-device.c
357adf696440ef2377c6f4d783b2de7ff4a277d5
1 /* SPDX-License-Identifier: LGPL-2.1+ */
7 #include <linux/sockios.h>
14 #include <sys/ioctl.h>
15 #include <sys/socket.h>
20 #include "sd-device.h"
22 #include "alloc-util.h"
23 #include "device-private.h"
24 #include "device-util.h"
25 #include "libudev-device-internal.h"
26 #include "parse-util.h"
27 #include "time-util.h"
30 * SECTION:libudev-device
31 * @short_description: kernel sys devices
33 * Representation of kernel sys devices. Devices are uniquely identified
34 * by their syspath, every device has exactly one path in the kernel sys
35 * filesystem. Devices usually belong to a kernel subsystem, and have
36 * a unique name inside that subsystem.
40 * udev_device_get_seqnum:
41 * @udev_device: udev device
43 * This is only valid if the device was received through a monitor. Devices read from
44 * sys do not have a sequence number.
46 * Returns: the kernel event sequence number, or 0 if there is no sequence number available.
48 _public_
unsigned long long udev_device_get_seqnum(struct udev_device
*udev_device
) {
51 assert_return_errno(udev_device
, 0, EINVAL
);
53 if (device_get_seqnum(udev_device
->device
, &seqnum
) < 0)
60 * udev_device_get_devnum:
61 * @udev_device: udev device
63 * Get the device major/minor number.
65 * Returns: the dev_t number.
67 _public_ dev_t
udev_device_get_devnum(struct udev_device
*udev_device
) {
71 assert_return_errno(udev_device
, makedev(0, 0), EINVAL
);
73 r
= sd_device_get_devnum(udev_device
->device
, &devnum
);
77 return_with_errno(makedev(0, 0), r
);
83 * udev_device_get_driver:
84 * @udev_device: udev device
86 * Get the kernel driver name.
88 * Returns: the driver name string, or #NULL if there is no driver attached.
90 _public_
const char *udev_device_get_driver(struct udev_device
*udev_device
) {
94 assert_return_errno(udev_device
, NULL
, EINVAL
);
96 r
= sd_device_get_driver(udev_device
->device
, &driver
);
98 return_with_errno(NULL
, r
);
104 * udev_device_get_devtype:
105 * @udev_device: udev device
107 * Retrieve the devtype string of the udev device.
109 * Returns: the devtype name of the udev device, or #NULL if it cannot be determined
111 _public_
const char *udev_device_get_devtype(struct udev_device
*udev_device
) {
115 assert_return_errno(udev_device
, NULL
, EINVAL
);
117 r
= sd_device_get_devtype(udev_device
->device
, &devtype
);
121 return_with_errno(NULL
, r
);
127 * udev_device_get_subsystem:
128 * @udev_device: udev device
130 * Retrieve the subsystem string of the udev device. The string does not
133 * Returns: the subsystem name of the udev device, or #NULL if it cannot be determined
135 _public_
const char *udev_device_get_subsystem(struct udev_device
*udev_device
) {
136 const char *subsystem
;
139 assert_return_errno(udev_device
, NULL
, EINVAL
);
141 r
= sd_device_get_subsystem(udev_device
->device
, &subsystem
);
143 return_with_errno(NULL
, r
);
149 * udev_device_get_property_value:
150 * @udev_device: udev device
151 * @key: property name
153 * Get the value of a given property.
155 * Returns: the property string, or #NULL if there is no such property.
157 _public_
const char *udev_device_get_property_value(struct udev_device
*udev_device
, const char *key
) {
161 assert_return_errno(udev_device
&& key
, NULL
, EINVAL
);
163 r
= sd_device_get_property_value(udev_device
->device
, key
, &value
);
165 return_with_errno(NULL
, r
);
170 struct udev_device
*udev_device_new(struct udev
*udev
, sd_device
*device
) {
171 struct udev_device
*udev_device
;
175 udev_device
= new(struct udev_device
, 1);
177 return_with_errno(NULL
, ENOMEM
);
179 *udev_device
= (struct udev_device
) {
182 .device
= sd_device_ref(device
),
185 udev_list_init(&udev_device
->properties
, true);
186 udev_list_init(&udev_device
->tags
, true);
187 udev_list_init(&udev_device
->sysattrs
, true);
188 udev_list_init(&udev_device
->devlinks
, true);
194 * udev_device_new_from_syspath:
195 * @udev: udev library context
196 * @syspath: sys device path including sys directory
198 * Create new udev device, and fill in information from the sys
199 * device and the udev database entry. The syspath is the absolute
200 * path to the device, including the sys mount point.
202 * The initial refcount is 1, and needs to be decremented to
203 * release the resources of the udev device.
205 * Returns: a new udev device, or #NULL, if it does not exist
207 _public_
struct udev_device
*udev_device_new_from_syspath(struct udev
*udev
, const char *syspath
) {
208 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
211 r
= sd_device_new_from_syspath(&device
, syspath
);
213 return_with_errno(NULL
, r
);
215 return udev_device_new(udev
, device
);
219 * udev_device_new_from_devnum:
220 * @udev: udev library context
221 * @type: char or block device
222 * @devnum: device major/minor number
224 * Create new udev device, and fill in information from the sys
225 * device and the udev database entry. The device is looked-up
226 * by its major/minor number and type. Character and block device
227 * numbers are not unique across the two types.
229 * The initial refcount is 1, and needs to be decremented to
230 * release the resources of the udev device.
232 * Returns: a new udev device, or #NULL, if it does not exist
234 _public_
struct udev_device
*udev_device_new_from_devnum(struct udev
*udev
, char type
, dev_t devnum
) {
235 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
238 r
= sd_device_new_from_devnum(&device
, type
, devnum
);
240 return_with_errno(NULL
, r
);
242 return udev_device_new(udev
, device
);
246 * udev_device_new_from_device_id:
247 * @udev: udev library context
248 * @id: text string identifying a kernel device
250 * Create new udev device, and fill in information from the sys
251 * device and the udev database entry. The device is looked-up
252 * by a special string:
253 * b8:2 - block device major:minor
254 * c128:1 - char device major:minor
255 * n3 - network device ifindex
256 * +sound:card29 - kernel driver core subsystem:device name
258 * The initial refcount is 1, and needs to be decremented to
259 * release the resources of the udev device.
261 * Returns: a new udev device, or #NULL, if it does not exist
263 _public_
struct udev_device
*udev_device_new_from_device_id(struct udev
*udev
, const char *id
) {
264 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
267 r
= sd_device_new_from_device_id(&device
, id
);
269 return_with_errno(NULL
, r
);
271 return udev_device_new(udev
, device
);
275 * udev_device_new_from_subsystem_sysname:
276 * @udev: udev library context
277 * @subsystem: the subsystem of the device
278 * @sysname: the name of the device
280 * Create new udev device, and fill in information from the sys device
281 * and the udev database entry. The device is looked up by the subsystem
282 * and name string of the device, like "mem" / "zero", or "block" / "sda".
284 * The initial refcount is 1, and needs to be decremented to
285 * release the resources of the udev device.
287 * Returns: a new udev device, or #NULL, if it does not exist
289 _public_
struct udev_device
*udev_device_new_from_subsystem_sysname(struct udev
*udev
, const char *subsystem
, const char *sysname
) {
290 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
293 r
= sd_device_new_from_subsystem_sysname(&device
, subsystem
, sysname
);
295 return_with_errno(NULL
, r
);
297 return udev_device_new(udev
, device
);
301 * udev_device_new_from_environment
302 * @udev: udev library context
304 * Create new udev device, and fill in information from the
305 * current process environment. This only works reliable if
306 * the process is called from a udev rule. It is usually used
307 * for tools executed from IMPORT= rules.
309 * The initial refcount is 1, and needs to be decremented to
310 * release the resources of the udev device.
312 * Returns: a new udev device, or #NULL, if it does not exist
314 _public_
struct udev_device
*udev_device_new_from_environment(struct udev
*udev
) {
315 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
318 r
= device_new_from_strv(&device
, environ
);
320 return_with_errno(NULL
, r
);
322 return udev_device_new(udev
, device
);
325 static struct udev_device
*device_new_from_parent(struct udev_device
*child
) {
329 assert_return_errno(child
, NULL
, EINVAL
);
331 r
= sd_device_get_parent(child
->device
, &parent
);
333 return_with_errno(NULL
, r
);
335 return udev_device_new(child
->udev
, parent
);
339 * udev_device_get_parent:
340 * @udev_device: the device to start searching from
342 * Find the next parent device, and fill in information from the sys
343 * device and the udev database entry.
345 * Returned device is not referenced. It is attached to the child
346 * device, and will be cleaned up when the child device is cleaned up.
348 * It is not necessarily just the upper level directory, empty or not
349 * recognized sys directories are ignored.
351 * It can be called as many times as needed, without caring about
354 * Returns: a new udev device, or #NULL, if it no parent exist.
356 _public_
struct udev_device
*udev_device_get_parent(struct udev_device
*udev_device
) {
357 assert_return_errno(udev_device
, NULL
, EINVAL
);
359 if (!udev_device
->parent_set
) {
360 udev_device
->parent_set
= true;
361 udev_device
->parent
= device_new_from_parent(udev_device
);
364 /* TODO: errno will differ here in case parent == NULL */
365 return udev_device
->parent
;
369 * udev_device_get_parent_with_subsystem_devtype:
370 * @udev_device: udev device to start searching from
371 * @subsystem: the subsystem of the device
372 * @devtype: the type (DEVTYPE) of the device
374 * Find the next parent device, with a matching subsystem and devtype
375 * value, and fill in information from the sys device and the udev
378 * If devtype is #NULL, only subsystem is checked, and any devtype will
381 * Returned device is not referenced. It is attached to the child
382 * device, and will be cleaned up when the child device is cleaned up.
384 * It can be called as many times as needed, without caring about
387 * Returns: a new udev device, or #NULL if no matching parent exists.
389 _public_
struct udev_device
*udev_device_get_parent_with_subsystem_devtype(struct udev_device
*udev_device
, const char *subsystem
, const char *devtype
) {
393 assert_return_errno(udev_device
, NULL
, EINVAL
);
395 /* this relies on the fact that finding the subdevice of a parent or the
396 parent of a subdevice commute */
398 /* first find the correct sd_device */
399 r
= sd_device_get_parent_with_subsystem_devtype(udev_device
->device
, subsystem
, devtype
, &parent
);
401 return_with_errno(NULL
, r
);
403 /* then walk the chain of udev_device parents until the corresponding
405 while ((udev_device
= udev_device_get_parent(udev_device
)))
406 if (udev_device
->device
== parent
)
409 return_with_errno(NULL
, ENOENT
);
413 * udev_device_get_udev:
414 * @udev_device: udev device
416 * Retrieve the udev library context the device was created with.
418 * Returns: the udev library context
420 _public_
struct udev
*udev_device_get_udev(struct udev_device
*udev_device
) {
421 assert_return_errno(udev_device
, NULL
, EINVAL
);
423 return udev_device
->udev
;
426 static struct udev_device
*udev_device_free(struct udev_device
*udev_device
) {
429 sd_device_unref(udev_device
->device
);
430 udev_device_unref(udev_device
->parent
);
432 udev_list_cleanup(&udev_device
->properties
);
433 udev_list_cleanup(&udev_device
->sysattrs
);
434 udev_list_cleanup(&udev_device
->tags
);
435 udev_list_cleanup(&udev_device
->devlinks
);
437 return mfree(udev_device
);
442 * @udev_device: udev device
444 * Take a reference of a udev device.
446 * Returns: the passed udev device
451 * @udev_device: udev device
453 * Drop a reference of a udev device. If the refcount reaches zero,
454 * the resources of the device will be released.
458 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_device
, udev_device
, udev_device_free
);
461 * udev_device_get_devpath:
462 * @udev_device: udev device
464 * Retrieve the kernel devpath value of the udev device. The path
465 * does not contain the sys mount point, and starts with a '/'.
467 * Returns: the devpath of the udev device
469 _public_
const char *udev_device_get_devpath(struct udev_device
*udev_device
) {
473 assert_return_errno(udev_device
, NULL
, EINVAL
);
475 r
= sd_device_get_devpath(udev_device
->device
, &devpath
);
477 return_with_errno(NULL
, r
);
483 * udev_device_get_syspath:
484 * @udev_device: udev device
486 * Retrieve the sys path of the udev device. The path is an
487 * absolute path and starts with the sys mount point.
489 * Returns: the sys path of the udev device
491 _public_
const char *udev_device_get_syspath(struct udev_device
*udev_device
) {
495 assert_return_errno(udev_device
, NULL
, EINVAL
);
497 r
= sd_device_get_syspath(udev_device
->device
, &syspath
);
499 return_with_errno(NULL
, r
);
505 * udev_device_get_sysname:
506 * @udev_device: udev device
508 * Get the kernel device name in /sys.
510 * Returns: the name string of the device
512 _public_
const char *udev_device_get_sysname(struct udev_device
*udev_device
) {
516 assert_return_errno(udev_device
, NULL
, EINVAL
);
518 r
= sd_device_get_sysname(udev_device
->device
, &sysname
);
520 return_with_errno(NULL
, r
);
526 * udev_device_get_sysnum:
527 * @udev_device: udev device
529 * Get the instance number of the device.
531 * Returns: the trailing number string of the device name
533 _public_
const char *udev_device_get_sysnum(struct udev_device
*udev_device
) {
537 assert_return_errno(udev_device
, NULL
, EINVAL
);
539 r
= sd_device_get_sysnum(udev_device
->device
, &sysnum
);
543 return_with_errno(NULL
, r
);
549 * udev_device_get_devnode:
550 * @udev_device: udev device
552 * Retrieve the device node file name belonging to the udev device.
553 * The path is an absolute path, and starts with the device directory.
555 * Returns: the device node file name of the udev device, or #NULL if no device node exists
557 _public_
const char *udev_device_get_devnode(struct udev_device
*udev_device
) {
561 assert_return_errno(udev_device
, NULL
, EINVAL
);
563 r
= sd_device_get_devname(udev_device
->device
, &devnode
);
565 return_with_errno(NULL
, r
);
571 * udev_device_get_devlinks_list_entry:
572 * @udev_device: udev device
574 * Retrieve the list of device links pointing to the device file of
575 * the udev device. The next list entry can be retrieved with
576 * udev_list_entry_get_next(), which returns #NULL if no more entries exist.
577 * The devlink path can be retrieved from the list entry by
578 * udev_list_entry_get_name(). The path is an absolute path, and starts with
579 * the device directory.
581 * Returns: the first entry of the device node link list
583 _public_
struct udev_list_entry
*udev_device_get_devlinks_list_entry(struct udev_device
*udev_device
) {
584 assert_return_errno(udev_device
, NULL
, EINVAL
);
586 if (device_get_devlinks_generation(udev_device
->device
) != udev_device
->devlinks_generation
||
587 !udev_device
->devlinks_read
) {
590 udev_list_cleanup(&udev_device
->devlinks
);
592 FOREACH_DEVICE_DEVLINK(udev_device
->device
, devlink
)
593 if (!udev_list_entry_add(&udev_device
->devlinks
, devlink
, NULL
))
594 return_with_errno(NULL
, ENOMEM
);
596 udev_device
->devlinks_read
= true;
597 udev_device
->devlinks_generation
= device_get_devlinks_generation(udev_device
->device
);
600 return udev_list_get_entry(&udev_device
->devlinks
);
604 * udev_device_get_event_properties_entry:
605 * @udev_device: udev device
607 * Retrieve the list of key/value device properties of the udev
608 * device. The next list entry can be retrieved with udev_list_entry_get_next(),
609 * which returns #NULL if no more entries exist. The property name
610 * can be retrieved from the list entry by udev_list_entry_get_name(),
611 * the property value by udev_list_entry_get_value().
613 * Returns: the first entry of the property list
615 _public_
struct udev_list_entry
*udev_device_get_properties_list_entry(struct udev_device
*udev_device
) {
616 assert_return_errno(udev_device
, NULL
, EINVAL
);
618 if (device_get_properties_generation(udev_device
->device
) != udev_device
->properties_generation
||
619 !udev_device
->properties_read
) {
620 const char *key
, *value
;
622 udev_list_cleanup(&udev_device
->properties
);
624 FOREACH_DEVICE_PROPERTY(udev_device
->device
, key
, value
)
625 if (!udev_list_entry_add(&udev_device
->properties
, key
, value
))
626 return_with_errno(NULL
, ENOMEM
);
628 udev_device
->properties_read
= true;
629 udev_device
->properties_generation
= device_get_properties_generation(udev_device
->device
);
632 return udev_list_get_entry(&udev_device
->properties
);
636 * udev_device_get_action:
637 * @udev_device: udev device
639 * This is only valid if the device was received through a monitor. Devices read from
640 * sys do not have an action string. Usual actions are: add, remove, change, online,
643 * Returns: the kernel action value, or #NULL if there is no action value available.
645 _public_
const char *udev_device_get_action(struct udev_device
*udev_device
) {
648 assert_return_errno(udev_device
, NULL
, EINVAL
);
650 if (device_get_action(udev_device
->device
, &action
) < 0)
653 return device_action_to_string(action
);
657 * udev_device_get_usec_since_initialized:
658 * @udev_device: udev device
660 * Return the number of microseconds passed since udev set up the
661 * device for the first time.
663 * This is only implemented for devices with need to store properties
664 * in the udev database. All other devices return 0 here.
666 * Returns: the number of microseconds since the device was first seen.
668 _public_
unsigned long long int udev_device_get_usec_since_initialized(struct udev_device
*udev_device
) {
672 assert_return(udev_device
, -EINVAL
);
674 r
= sd_device_get_usec_since_initialized(udev_device
->device
, &ts
);
676 return_with_errno(0, r
);
682 * udev_device_get_sysattr_value:
683 * @udev_device: udev device
684 * @sysattr: attribute name
686 * The retrieved value is cached in the device. Repeated calls will return the same
687 * value and not open the attribute again.
689 * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value.
691 _public_
const char *udev_device_get_sysattr_value(struct udev_device
*udev_device
, const char *sysattr
) {
695 assert_return_errno(udev_device
, NULL
, EINVAL
);
697 r
= sd_device_get_sysattr_value(udev_device
->device
, sysattr
, &value
);
699 return_with_errno(NULL
, r
);
705 * udev_device_set_sysattr_value:
706 * @udev_device: udev device
707 * @sysattr: attribute name
708 * @value: new value to be set
710 * Update the contents of the sys attribute and the cached value of the device.
712 * Returns: Negative error code on failure or 0 on success.
714 _public_
int udev_device_set_sysattr_value(struct udev_device
*udev_device
, const char *sysattr
, const char *value
) {
717 assert_return(udev_device
, -EINVAL
);
719 r
= sd_device_set_sysattr_value(udev_device
->device
, sysattr
, value
);
727 * udev_device_get_sysattr_list_entry:
728 * @udev_device: udev device
730 * Retrieve the list of available sysattrs, with value being empty;
731 * This just return all available sysfs attributes for a particular
732 * device without reading their values.
734 * Returns: the first entry of the property list
736 _public_
struct udev_list_entry
*udev_device_get_sysattr_list_entry(struct udev_device
*udev_device
) {
737 assert_return_errno(udev_device
, NULL
, EINVAL
);
739 if (!udev_device
->sysattrs_read
) {
742 udev_list_cleanup(&udev_device
->sysattrs
);
744 FOREACH_DEVICE_SYSATTR(udev_device
->device
, sysattr
)
745 if (!udev_list_entry_add(&udev_device
->sysattrs
, sysattr
, NULL
))
746 return_with_errno(NULL
, ENOMEM
);
748 udev_device
->sysattrs_read
= true;
751 return udev_list_get_entry(&udev_device
->sysattrs
);
755 * udev_device_get_is_initialized:
756 * @udev_device: udev device
758 * Check if udev has already handled the device and has set up
759 * device node permissions and context, or has renamed a network
762 * This is only implemented for devices with a device node
763 * or network interfaces. All other devices return 1 here.
765 * Returns: 1 if the device is set up. 0 otherwise.
767 _public_
int udev_device_get_is_initialized(struct udev_device
*udev_device
) {
770 assert_return(udev_device
, -EINVAL
);
772 r
= sd_device_get_is_initialized(udev_device
->device
);
774 return_with_errno(0, r
);
780 * udev_device_get_tags_list_entry:
781 * @udev_device: udev device
783 * Retrieve the list of tags attached to the udev device. The next
784 * list entry can be retrieved with udev_list_entry_get_next(),
785 * which returns #NULL if no more entries exist. The tag string
786 * can be retrieved from the list entry by udev_list_entry_get_name().
788 * Returns: the first entry of the tag list
790 _public_
struct udev_list_entry
*udev_device_get_tags_list_entry(struct udev_device
*udev_device
) {
791 assert_return_errno(udev_device
, NULL
, EINVAL
);
793 if (device_get_tags_generation(udev_device
->device
) != udev_device
->tags_generation
||
794 !udev_device
->tags_read
) {
797 udev_list_cleanup(&udev_device
->tags
);
799 FOREACH_DEVICE_TAG(udev_device
->device
, tag
)
800 if (!udev_list_entry_add(&udev_device
->tags
, tag
, NULL
))
801 return_with_errno(NULL
, ENOMEM
);
803 udev_device
->tags_read
= true;
804 udev_device
->tags_generation
= device_get_tags_generation(udev_device
->device
);
807 return udev_list_get_entry(&udev_device
->tags
);
811 * udev_device_has_tag:
812 * @udev_device: udev device
815 * Check if a given device has a certain tag associated.
817 * Returns: 1 if the tag is found. 0 otherwise.
819 _public_
int udev_device_has_tag(struct udev_device
*udev_device
, const char *tag
) {
820 assert_return(udev_device
, 0);
822 return sd_device_has_tag(udev_device
->device
, tag
) > 0;