]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/libudev/libudev-device.c
Merge pull request #12753 from jrouleau/fix/hibernate-resume-timeout
[thirdparty/systemd.git] / src / libudev / libudev-device.c
... / ...
CommitLineData
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <ctype.h>
4#include <dirent.h>
5#include <errno.h>
6#include <fcntl.h>
7#include <linux/sockios.h>
8#include <net/if.h>
9#include <stdbool.h>
10#include <stddef.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <sys/ioctl.h>
15#include <sys/socket.h>
16#include <sys/stat.h>
17#include <unistd.h>
18
19#include "libudev.h"
20#include "sd-device.h"
21
22#include "alloc-util.h"
23#include "device-private.h"
24#include "device-util.h"
25#include "libudev-device-internal.h"
26#include "libudev-list-internal.h"
27#include "parse-util.h"
28#include "time-util.h"
29
30/**
31 * SECTION:libudev-device
32 * @short_description: kernel sys devices
33 *
34 * Representation of kernel sys devices. Devices are uniquely identified
35 * by their syspath, every device has exactly one path in the kernel sys
36 * filesystem. Devices usually belong to a kernel subsystem, and have
37 * a unique name inside that subsystem.
38 */
39
40/**
41 * udev_device:
42 *
43 * Opaque object representing one kernel sys device.
44 */
45struct udev_device {
46 struct udev *udev;
47
48 /* real device object */
49 sd_device *device;
50
51 /* legacy */
52 unsigned n_ref;
53
54 struct udev_device *parent;
55 bool parent_set;
56
57 struct udev_list *properties;
58 uint64_t properties_generation;
59 struct udev_list *tags;
60 uint64_t tags_generation;
61 struct udev_list *devlinks;
62 uint64_t devlinks_generation;
63 bool properties_read:1;
64 bool tags_read:1;
65 bool devlinks_read:1;
66 struct udev_list *sysattrs;
67 bool sysattrs_read;
68};
69
70/**
71 * udev_device_get_seqnum:
72 * @udev_device: udev device
73 *
74 * This is only valid if the device was received through a monitor. Devices read from
75 * sys do not have a sequence number.
76 *
77 * Returns: the kernel event sequence number, or 0 if there is no sequence number available.
78 **/
79_public_ unsigned long long udev_device_get_seqnum(struct udev_device *udev_device) {
80 uint64_t seqnum;
81
82 assert_return_errno(udev_device, 0, EINVAL);
83
84 if (device_get_seqnum(udev_device->device, &seqnum) < 0)
85 return 0;
86
87 return seqnum;
88}
89
90/**
91 * udev_device_get_devnum:
92 * @udev_device: udev device
93 *
94 * Get the device major/minor number.
95 *
96 * Returns: the dev_t number.
97 **/
98_public_ dev_t udev_device_get_devnum(struct udev_device *udev_device) {
99 dev_t devnum;
100 int r;
101
102 assert_return_errno(udev_device, makedev(0, 0), EINVAL);
103
104 r = sd_device_get_devnum(udev_device->device, &devnum);
105 if (r == -ENOENT)
106 return makedev(0, 0);
107 if (r < 0)
108 return_with_errno(makedev(0, 0), r);
109
110 return devnum;
111}
112
113/**
114 * udev_device_get_driver:
115 * @udev_device: udev device
116 *
117 * Get the kernel driver name.
118 *
119 * Returns: the driver name string, or #NULL if there is no driver attached.
120 **/
121_public_ const char *udev_device_get_driver(struct udev_device *udev_device) {
122 const char *driver;
123 int r;
124
125 assert_return_errno(udev_device, NULL, EINVAL);
126
127 r = sd_device_get_driver(udev_device->device, &driver);
128 if (r < 0)
129 return_with_errno(NULL, r);
130
131 return driver;
132}
133
134/**
135 * udev_device_get_devtype:
136 * @udev_device: udev device
137 *
138 * Retrieve the devtype string of the udev device.
139 *
140 * Returns: the devtype name of the udev device, or #NULL if it cannot be determined
141 **/
142_public_ const char *udev_device_get_devtype(struct udev_device *udev_device) {
143 const char *devtype;
144 int r;
145
146 assert_return_errno(udev_device, NULL, EINVAL);
147
148 r = sd_device_get_devtype(udev_device->device, &devtype);
149 if (r == -ENOENT)
150 return NULL;
151 if (r < 0)
152 return_with_errno(NULL, r);
153
154 return devtype;
155}
156
157/**
158 * udev_device_get_subsystem:
159 * @udev_device: udev device
160 *
161 * Retrieve the subsystem string of the udev device. The string does not
162 * contain any "/".
163 *
164 * Returns: the subsystem name of the udev device, or #NULL if it cannot be determined
165 **/
166_public_ const char *udev_device_get_subsystem(struct udev_device *udev_device) {
167 const char *subsystem;
168 int r;
169
170 assert_return_errno(udev_device, NULL, EINVAL);
171
172 r = sd_device_get_subsystem(udev_device->device, &subsystem);
173 if (r < 0)
174 return_with_errno(NULL, r);
175
176 return subsystem;
177}
178
179/**
180 * udev_device_get_property_value:
181 * @udev_device: udev device
182 * @key: property name
183 *
184 * Get the value of a given property.
185 *
186 * Returns: the property string, or #NULL if there is no such property.
187 **/
188_public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key) {
189 const char *value;
190 int r;
191
192 assert_return_errno(udev_device && key, NULL, EINVAL);
193
194 r = sd_device_get_property_value(udev_device->device, key, &value);
195 if (r < 0)
196 return_with_errno(NULL, r);
197
198 return value;
199}
200
201struct udev_device *udev_device_new(struct udev *udev, sd_device *device) {
202 _cleanup_(udev_list_freep) struct udev_list *properties = NULL, *tags = NULL, *sysattrs = NULL, *devlinks = NULL;
203 struct udev_device *udev_device;
204
205 assert(device);
206
207 properties = udev_list_new(true);
208 if (!properties)
209 return_with_errno(NULL, ENOMEM);
210 tags = udev_list_new(true);
211 if (!tags)
212 return_with_errno(NULL, ENOMEM);
213 sysattrs = udev_list_new(true);
214 if (!sysattrs)
215 return_with_errno(NULL, ENOMEM);
216 devlinks = udev_list_new(true);
217 if (!devlinks)
218 return_with_errno(NULL, ENOMEM);
219
220 udev_device = new(struct udev_device, 1);
221 if (!udev_device)
222 return_with_errno(NULL, ENOMEM);
223
224 *udev_device = (struct udev_device) {
225 .n_ref = 1,
226 .udev = udev,
227 .device = sd_device_ref(device),
228 .properties = TAKE_PTR(properties),
229 .tags = TAKE_PTR(tags),
230 .sysattrs = TAKE_PTR(sysattrs),
231 .devlinks = TAKE_PTR(devlinks),
232 };
233
234 return udev_device;
235}
236
237/**
238 * udev_device_new_from_syspath:
239 * @udev: udev library context
240 * @syspath: sys device path including sys directory
241 *
242 * Create new udev device, and fill in information from the sys
243 * device and the udev database entry. The syspath is the absolute
244 * path to the device, including the sys mount point.
245 *
246 * The initial refcount is 1, and needs to be decremented to
247 * release the resources of the udev device.
248 *
249 * Returns: a new udev device, or #NULL, if it does not exist
250 **/
251_public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath) {
252 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
253 int r;
254
255 r = sd_device_new_from_syspath(&device, syspath);
256 if (r < 0)
257 return_with_errno(NULL, r);
258
259 return udev_device_new(udev, device);
260}
261
262/**
263 * udev_device_new_from_devnum:
264 * @udev: udev library context
265 * @type: char or block device
266 * @devnum: device major/minor number
267 *
268 * Create new udev device, and fill in information from the sys
269 * device and the udev database entry. The device is looked-up
270 * by its major/minor number and type. Character and block device
271 * numbers are not unique across the two types.
272 *
273 * The initial refcount is 1, and needs to be decremented to
274 * release the resources of the udev device.
275 *
276 * Returns: a new udev device, or #NULL, if it does not exist
277 **/
278_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) {
279 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
280 int r;
281
282 r = sd_device_new_from_devnum(&device, type, devnum);
283 if (r < 0)
284 return_with_errno(NULL, r);
285
286 return udev_device_new(udev, device);
287}
288
289/**
290 * udev_device_new_from_device_id:
291 * @udev: udev library context
292 * @id: text string identifying a kernel device
293 *
294 * Create new udev device, and fill in information from the sys
295 * device and the udev database entry. The device is looked-up
296 * by a special string:
297 * b8:2 - block device major:minor
298 * c128:1 - char device major:minor
299 * n3 - network device ifindex
300 * +sound:card29 - kernel driver core subsystem:device name
301 *
302 * The initial refcount is 1, and needs to be decremented to
303 * release the resources of the udev device.
304 *
305 * Returns: a new udev device, or #NULL, if it does not exist
306 **/
307_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id) {
308 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
309 int r;
310
311 r = sd_device_new_from_device_id(&device, id);
312 if (r < 0)
313 return_with_errno(NULL, r);
314
315 return udev_device_new(udev, device);
316}
317
318/**
319 * udev_device_new_from_subsystem_sysname:
320 * @udev: udev library context
321 * @subsystem: the subsystem of the device
322 * @sysname: the name of the device
323 *
324 * Create new udev device, and fill in information from the sys device
325 * and the udev database entry. The device is looked up by the subsystem
326 * and name string of the device, like "mem" / "zero", or "block" / "sda".
327 *
328 * The initial refcount is 1, and needs to be decremented to
329 * release the resources of the udev device.
330 *
331 * Returns: a new udev device, or #NULL, if it does not exist
332 **/
333_public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) {
334 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
335 int r;
336
337 r = sd_device_new_from_subsystem_sysname(&device, subsystem, sysname);
338 if (r < 0)
339 return_with_errno(NULL, r);
340
341 return udev_device_new(udev, device);
342}
343
344/**
345 * udev_device_new_from_environment
346 * @udev: udev library context
347 *
348 * Create new udev device, and fill in information from the
349 * current process environment. This only works reliable if
350 * the process is called from a udev rule. It is usually used
351 * for tools executed from IMPORT= rules.
352 *
353 * The initial refcount is 1, and needs to be decremented to
354 * release the resources of the udev device.
355 *
356 * Returns: a new udev device, or #NULL, if it does not exist
357 **/
358_public_ struct udev_device *udev_device_new_from_environment(struct udev *udev) {
359 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
360 int r;
361
362 r = device_new_from_strv(&device, environ);
363 if (r < 0)
364 return_with_errno(NULL, r);
365
366 return udev_device_new(udev, device);
367}
368
369static struct udev_device *device_new_from_parent(struct udev_device *child) {
370 sd_device *parent;
371 int r;
372
373 assert_return_errno(child, NULL, EINVAL);
374
375 r = sd_device_get_parent(child->device, &parent);
376 if (r < 0)
377 return_with_errno(NULL, r);
378
379 return udev_device_new(child->udev, parent);
380}
381
382/**
383 * udev_device_get_parent:
384 * @udev_device: the device to start searching from
385 *
386 * Find the next parent device, and fill in information from the sys
387 * device and the udev database entry.
388 *
389 * Returned device is not referenced. It is attached to the child
390 * device, and will be cleaned up when the child device is cleaned up.
391 *
392 * It is not necessarily just the upper level directory, empty or not
393 * recognized sys directories are ignored.
394 *
395 * It can be called as many times as needed, without caring about
396 * references.
397 *
398 * Returns: a new udev device, or #NULL, if it no parent exist.
399 **/
400_public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device) {
401 assert_return_errno(udev_device, NULL, EINVAL);
402
403 if (!udev_device->parent_set) {
404 udev_device->parent_set = true;
405 udev_device->parent = device_new_from_parent(udev_device);
406 }
407
408 /* TODO: errno will differ here in case parent == NULL */
409 return udev_device->parent;
410}
411
412/**
413 * udev_device_get_parent_with_subsystem_devtype:
414 * @udev_device: udev device to start searching from
415 * @subsystem: the subsystem of the device
416 * @devtype: the type (DEVTYPE) of the device
417 *
418 * Find the next parent device, with a matching subsystem and devtype
419 * value, and fill in information from the sys device and the udev
420 * database entry.
421 *
422 * If devtype is #NULL, only subsystem is checked, and any devtype will
423 * match.
424 *
425 * Returned device is not referenced. It is attached to the child
426 * device, and will be cleaned up when the child device is cleaned up.
427 *
428 * It can be called as many times as needed, without caring about
429 * references.
430 *
431 * Returns: a new udev device, or #NULL if no matching parent exists.
432 **/
433_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype) {
434 sd_device *parent;
435 int r;
436
437 assert_return_errno(udev_device, NULL, EINVAL);
438
439 /* this relies on the fact that finding the subdevice of a parent or the
440 parent of a subdevice commute */
441
442 /* first find the correct sd_device */
443 r = sd_device_get_parent_with_subsystem_devtype(udev_device->device, subsystem, devtype, &parent);
444 if (r < 0)
445 return_with_errno(NULL, r);
446
447 /* then walk the chain of udev_device parents until the corresponding
448 one is found */
449 while ((udev_device = udev_device_get_parent(udev_device)))
450 if (udev_device->device == parent)
451 return udev_device;
452
453 return_with_errno(NULL, ENOENT);
454}
455
456/**
457 * udev_device_get_udev:
458 * @udev_device: udev device
459 *
460 * Retrieve the udev library context the device was created with.
461 *
462 * Returns: the udev library context
463 **/
464_public_ struct udev *udev_device_get_udev(struct udev_device *udev_device) {
465 assert_return_errno(udev_device, NULL, EINVAL);
466
467 return udev_device->udev;
468}
469
470static struct udev_device *udev_device_free(struct udev_device *udev_device) {
471 assert(udev_device);
472
473 sd_device_unref(udev_device->device);
474 udev_device_unref(udev_device->parent);
475
476 udev_list_free(udev_device->properties);
477 udev_list_free(udev_device->sysattrs);
478 udev_list_free(udev_device->tags);
479 udev_list_free(udev_device->devlinks);
480
481 return mfree(udev_device);
482}
483
484/**
485 * udev_device_ref:
486 * @udev_device: udev device
487 *
488 * Take a reference of a udev device.
489 *
490 * Returns: the passed udev device
491 **/
492
493/**
494 * udev_device_unref:
495 * @udev_device: udev device
496 *
497 * Drop a reference of a udev device. If the refcount reaches zero,
498 * the resources of the device will be released.
499 *
500 * Returns: #NULL
501 **/
502DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_device, udev_device, udev_device_free);
503
504/**
505 * udev_device_get_devpath:
506 * @udev_device: udev device
507 *
508 * Retrieve the kernel devpath value of the udev device. The path
509 * does not contain the sys mount point, and starts with a '/'.
510 *
511 * Returns: the devpath of the udev device
512 **/
513_public_ const char *udev_device_get_devpath(struct udev_device *udev_device) {
514 const char *devpath;
515 int r;
516
517 assert_return_errno(udev_device, NULL, EINVAL);
518
519 r = sd_device_get_devpath(udev_device->device, &devpath);
520 if (r < 0)
521 return_with_errno(NULL, r);
522
523 return devpath;
524}
525
526/**
527 * udev_device_get_syspath:
528 * @udev_device: udev device
529 *
530 * Retrieve the sys path of the udev device. The path is an
531 * absolute path and starts with the sys mount point.
532 *
533 * Returns: the sys path of the udev device
534 **/
535_public_ const char *udev_device_get_syspath(struct udev_device *udev_device) {
536 const char *syspath;
537 int r;
538
539 assert_return_errno(udev_device, NULL, EINVAL);
540
541 r = sd_device_get_syspath(udev_device->device, &syspath);
542 if (r < 0)
543 return_with_errno(NULL, r);
544
545 return syspath;
546}
547
548/**
549 * udev_device_get_sysname:
550 * @udev_device: udev device
551 *
552 * Get the kernel device name in /sys.
553 *
554 * Returns: the name string of the device
555 **/
556_public_ const char *udev_device_get_sysname(struct udev_device *udev_device) {
557 const char *sysname;
558 int r;
559
560 assert_return_errno(udev_device, NULL, EINVAL);
561
562 r = sd_device_get_sysname(udev_device->device, &sysname);
563 if (r < 0)
564 return_with_errno(NULL, r);
565
566 return sysname;
567}
568
569/**
570 * udev_device_get_sysnum:
571 * @udev_device: udev device
572 *
573 * Get the instance number of the device.
574 *
575 * Returns: the trailing number string of the device name
576 **/
577_public_ const char *udev_device_get_sysnum(struct udev_device *udev_device) {
578 const char *sysnum;
579 int r;
580
581 assert_return_errno(udev_device, NULL, EINVAL);
582
583 r = sd_device_get_sysnum(udev_device->device, &sysnum);
584 if (r == -ENOENT)
585 return NULL;
586 if (r < 0)
587 return_with_errno(NULL, r);
588
589 return sysnum;
590}
591
592/**
593 * udev_device_get_devnode:
594 * @udev_device: udev device
595 *
596 * Retrieve the device node file name belonging to the udev device.
597 * The path is an absolute path, and starts with the device directory.
598 *
599 * Returns: the device node file name of the udev device, or #NULL if no device node exists
600 **/
601_public_ const char *udev_device_get_devnode(struct udev_device *udev_device) {
602 const char *devnode;
603 int r;
604
605 assert_return_errno(udev_device, NULL, EINVAL);
606
607 r = sd_device_get_devname(udev_device->device, &devnode);
608 if (r < 0)
609 return_with_errno(NULL, r);
610
611 return devnode;
612}
613
614/**
615 * udev_device_get_devlinks_list_entry:
616 * @udev_device: udev device
617 *
618 * Retrieve the list of device links pointing to the device file of
619 * the udev device. The next list entry can be retrieved with
620 * udev_list_entry_get_next(), which returns #NULL if no more entries exist.
621 * The devlink path can be retrieved from the list entry by
622 * udev_list_entry_get_name(). The path is an absolute path, and starts with
623 * the device directory.
624 *
625 * Returns: the first entry of the device node link list
626 **/
627_public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device) {
628 assert_return_errno(udev_device, NULL, EINVAL);
629
630 if (device_get_devlinks_generation(udev_device->device) != udev_device->devlinks_generation ||
631 !udev_device->devlinks_read) {
632 const char *devlink;
633
634 udev_list_cleanup(udev_device->devlinks);
635
636 FOREACH_DEVICE_DEVLINK(udev_device->device, devlink)
637 if (!udev_list_entry_add(udev_device->devlinks, devlink, NULL))
638 return_with_errno(NULL, ENOMEM);
639
640 udev_device->devlinks_read = true;
641 udev_device->devlinks_generation = device_get_devlinks_generation(udev_device->device);
642 }
643
644 return udev_list_get_entry(udev_device->devlinks);
645}
646
647/**
648 * udev_device_get_event_properties_entry:
649 * @udev_device: udev device
650 *
651 * Retrieve the list of key/value device properties of the udev
652 * device. The next list entry can be retrieved with udev_list_entry_get_next(),
653 * which returns #NULL if no more entries exist. The property name
654 * can be retrieved from the list entry by udev_list_entry_get_name(),
655 * the property value by udev_list_entry_get_value().
656 *
657 * Returns: the first entry of the property list
658 **/
659_public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device) {
660 assert_return_errno(udev_device, NULL, EINVAL);
661
662 if (device_get_properties_generation(udev_device->device) != udev_device->properties_generation ||
663 !udev_device->properties_read) {
664 const char *key, *value;
665
666 udev_list_cleanup(udev_device->properties);
667
668 FOREACH_DEVICE_PROPERTY(udev_device->device, key, value)
669 if (!udev_list_entry_add(udev_device->properties, key, value))
670 return_with_errno(NULL, ENOMEM);
671
672 udev_device->properties_read = true;
673 udev_device->properties_generation = device_get_properties_generation(udev_device->device);
674 }
675
676 return udev_list_get_entry(udev_device->properties);
677}
678
679/**
680 * udev_device_get_action:
681 * @udev_device: udev device
682 *
683 * This is only valid if the device was received through a monitor. Devices read from
684 * sys do not have an action string. Usual actions are: add, remove, change, online,
685 * offline.
686 *
687 * Returns: the kernel action value, or #NULL if there is no action value available.
688 **/
689_public_ const char *udev_device_get_action(struct udev_device *udev_device) {
690 DeviceAction action;
691
692 assert_return_errno(udev_device, NULL, EINVAL);
693
694 if (device_get_action(udev_device->device, &action) < 0)
695 return NULL;
696
697 return device_action_to_string(action);
698}
699
700/**
701 * udev_device_get_usec_since_initialized:
702 * @udev_device: udev device
703 *
704 * Return the number of microseconds passed since udev set up the
705 * device for the first time.
706 *
707 * This is only implemented for devices with need to store properties
708 * in the udev database. All other devices return 0 here.
709 *
710 * Returns: the number of microseconds since the device was first seen.
711 **/
712_public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device) {
713 usec_t ts;
714 int r;
715
716 assert_return(udev_device, -EINVAL);
717
718 r = sd_device_get_usec_since_initialized(udev_device->device, &ts);
719 if (r < 0)
720 return_with_errno(0, r);
721
722 return ts;
723}
724
725/**
726 * udev_device_get_sysattr_value:
727 * @udev_device: udev device
728 * @sysattr: attribute name
729 *
730 * The retrieved value is cached in the device. Repeated calls will return the same
731 * value and not open the attribute again.
732 *
733 * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value.
734 **/
735_public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr) {
736 const char *value;
737 int r;
738
739 assert_return_errno(udev_device, NULL, EINVAL);
740
741 r = sd_device_get_sysattr_value(udev_device->device, sysattr, &value);
742 if (r < 0)
743 return_with_errno(NULL, r);
744
745 return value;
746}
747
748/**
749 * udev_device_set_sysattr_value:
750 * @udev_device: udev device
751 * @sysattr: attribute name
752 * @value: new value to be set
753 *
754 * Update the contents of the sys attribute and the cached value of the device.
755 *
756 * Returns: Negative error code on failure or 0 on success.
757 **/
758_public_ int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, const char *value) {
759 int r;
760
761 assert_return(udev_device, -EINVAL);
762
763 r = sd_device_set_sysattr_value(udev_device->device, sysattr, value);
764 if (r < 0)
765 return r;
766
767 return 0;
768}
769
770/**
771 * udev_device_get_sysattr_list_entry:
772 * @udev_device: udev device
773 *
774 * Retrieve the list of available sysattrs, with value being empty;
775 * This just return all available sysfs attributes for a particular
776 * device without reading their values.
777 *
778 * Returns: the first entry of the property list
779 **/
780_public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device) {
781 assert_return_errno(udev_device, NULL, EINVAL);
782
783 if (!udev_device->sysattrs_read) {
784 const char *sysattr;
785
786 udev_list_cleanup(udev_device->sysattrs);
787
788 FOREACH_DEVICE_SYSATTR(udev_device->device, sysattr)
789 if (!udev_list_entry_add(udev_device->sysattrs, sysattr, NULL))
790 return_with_errno(NULL, ENOMEM);
791
792 udev_device->sysattrs_read = true;
793 }
794
795 return udev_list_get_entry(udev_device->sysattrs);
796}
797
798/**
799 * udev_device_get_is_initialized:
800 * @udev_device: udev device
801 *
802 * Check if udev has already handled the device and has set up
803 * device node permissions and context, or has renamed a network
804 * device.
805 *
806 * This is only implemented for devices with a device node
807 * or network interfaces. All other devices return 1 here.
808 *
809 * Returns: 1 if the device is set up. 0 otherwise.
810 **/
811_public_ int udev_device_get_is_initialized(struct udev_device *udev_device) {
812 int r;
813
814 assert_return(udev_device, -EINVAL);
815
816 r = sd_device_get_is_initialized(udev_device->device);
817 if (r < 0)
818 return_with_errno(0, r);
819
820 return r;
821}
822
823/**
824 * udev_device_get_tags_list_entry:
825 * @udev_device: udev device
826 *
827 * Retrieve the list of tags attached to the udev device. The next
828 * list entry can be retrieved with udev_list_entry_get_next(),
829 * which returns #NULL if no more entries exist. The tag string
830 * can be retrieved from the list entry by udev_list_entry_get_name().
831 *
832 * Returns: the first entry of the tag list
833 **/
834_public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device) {
835 assert_return_errno(udev_device, NULL, EINVAL);
836
837 if (device_get_tags_generation(udev_device->device) != udev_device->tags_generation ||
838 !udev_device->tags_read) {
839 const char *tag;
840
841 udev_list_cleanup(udev_device->tags);
842
843 FOREACH_DEVICE_TAG(udev_device->device, tag)
844 if (!udev_list_entry_add(udev_device->tags, tag, NULL))
845 return_with_errno(NULL, ENOMEM);
846
847 udev_device->tags_read = true;
848 udev_device->tags_generation = device_get_tags_generation(udev_device->device);
849 }
850
851 return udev_list_get_entry(udev_device->tags);
852}
853
854/**
855 * udev_device_has_tag:
856 * @udev_device: udev device
857 * @tag: tag name
858 *
859 * Check if a given device has a certain tag associated.
860 *
861 * Returns: 1 if the tag is found. 0 otherwise.
862 **/
863_public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag) {
864 assert_return(udev_device, 0);
865
866 return sd_device_has_tag(udev_device->device, tag) > 0;
867}
868
869sd_device *udev_device_get_sd_device(struct udev_device *udev_device) {
870 assert(udev_device);
871
872 return udev_device->device;
873}