1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
9 #include "alloc-util.h"
10 #include "device-internal.h"
11 #include "device-private.h"
12 #include "device-util.h"
19 #include "nulstr-util.h"
20 #include "parse-util.h"
21 #include "path-util.h"
23 #include "stdio-util.h"
24 #include "string-table.h"
25 #include "string-util.h"
28 #include "tmpfile-util.h"
29 #include "user-util.h"
31 int device_add_property(sd_device
*device
, const char *key
, const char *value
) {
37 r
= device_add_property_aux(device
, key
, value
, false);
42 r
= device_add_property_aux(device
, key
, value
, true);
50 int device_add_propertyf(sd_device
*device
, const char *key
, const char *format
, ...) {
51 _cleanup_free_
char *value
= NULL
;
59 return device_add_property(device
, key
, NULL
);
62 r
= vasprintf(&value
, format
, ap
);
68 return device_add_property(device
, key
, value
);
71 void device_set_devlink_priority(sd_device
*device
, int priority
) {
74 device
->devlink_priority
= priority
;
77 void device_set_is_initialized(sd_device
*device
) {
80 device
->is_initialized
= true;
83 int device_ensure_usec_initialized(sd_device
*device
, sd_device
*device_old
) {
88 if (device_old
&& device_old
->usec_initialized
> 0)
89 when
= device_old
->usec_initialized
;
91 when
= now(CLOCK_MONOTONIC
);
93 return device_set_usec_initialized(device
, when
);
96 uint64_t device_get_properties_generation(sd_device
*device
) {
99 return device
->properties_generation
;
102 uint64_t device_get_tags_generation(sd_device
*device
) {
105 return device
->tags_generation
;
108 uint64_t device_get_devlinks_generation(sd_device
*device
) {
111 return device
->devlinks_generation
;
114 int device_get_devnode_mode(sd_device
*device
, mode_t
*ret
) {
119 r
= device_read_db(device
);
123 if (device
->devmode
== MODE_INVALID
)
127 *ret
= device
->devmode
;
132 int device_get_devnode_uid(sd_device
*device
, uid_t
*ret
) {
137 r
= device_read_db(device
);
141 if (device
->devuid
== UID_INVALID
)
145 *ret
= device
->devuid
;
150 static int device_set_devuid(sd_device
*device
, const char *uid
) {
157 r
= parse_uid(uid
, &u
);
161 r
= device_add_property_internal(device
, "DEVUID", uid
);
170 int device_get_devnode_gid(sd_device
*device
, gid_t
*ret
) {
175 r
= device_read_db(device
);
179 if (device
->devgid
== GID_INVALID
)
183 *ret
= device
->devgid
;
188 static int device_set_devgid(sd_device
*device
, const char *gid
) {
195 r
= parse_gid(gid
, &g
);
199 r
= device_add_property_internal(device
, "DEVGID", gid
);
208 int device_set_action(sd_device
*device
, sd_device_action_t a
) {
212 assert(a
>= 0 && a
< _SD_DEVICE_ACTION_MAX
);
214 r
= device_add_property_internal(device
, "ACTION", device_action_to_string(a
));
223 static int device_set_action_from_string(sd_device
*device
, const char *action
) {
224 sd_device_action_t a
;
229 a
= device_action_from_string(action
);
233 return device_set_action(device
, a
);
236 static int device_set_seqnum(sd_device
*device
, const char *str
) {
243 r
= safe_atou64(str
, &seqnum
);
249 r
= device_add_property_internal(device
, "SEQNUM", str
);
253 device
->seqnum
= seqnum
;
258 static int device_amend(sd_device
*device
, const char *key
, const char *value
) {
265 if (streq(key
, "DEVPATH")) {
268 path
= strjoina("/sys", value
);
270 /* the caller must verify or trust this data (e.g., if it comes from the kernel) */
271 r
= device_set_syspath(device
, path
, false);
273 return log_device_debug_errno(device
, r
, "sd-device: Failed to set syspath to '%s': %m", path
);
274 } else if (streq(key
, "SUBSYSTEM")) {
275 r
= device_set_subsystem(device
, value
);
277 return log_device_debug_errno(device
, r
, "sd-device: Failed to set subsystem to '%s': %m", value
);
278 } else if (streq(key
, "DEVTYPE")) {
279 r
= device_set_devtype(device
, value
);
281 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devtype to '%s': %m", value
);
282 } else if (streq(key
, "DEVNAME")) {
283 r
= device_set_devname(device
, value
);
285 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devname to '%s': %m", value
);
286 } else if (streq(key
, "USEC_INITIALIZED")) {
289 r
= safe_atou64(value
, &t
);
291 return log_device_debug_errno(device
, r
, "sd-device: Failed to parse timestamp '%s': %m", value
);
293 r
= device_set_usec_initialized(device
, t
);
295 return log_device_debug_errno(device
, r
, "sd-device: Failed to set usec-initialized to '%s': %m", value
);
296 } else if (streq(key
, "DRIVER")) {
297 r
= device_set_driver(device
, value
);
299 return log_device_debug_errno(device
, r
, "sd-device: Failed to set driver to '%s': %m", value
);
300 } else if (streq(key
, "IFINDEX")) {
301 r
= device_set_ifindex(device
, value
);
303 return log_device_debug_errno(device
, r
, "sd-device: Failed to set ifindex to '%s': %m", value
);
304 } else if (streq(key
, "DEVMODE")) {
305 r
= device_set_devmode(device
, value
);
307 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devmode to '%s': %m", value
);
308 } else if (streq(key
, "DEVUID")) {
309 r
= device_set_devuid(device
, value
);
311 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devuid to '%s': %m", value
);
312 } else if (streq(key
, "DEVGID")) {
313 r
= device_set_devgid(device
, value
);
315 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devgid to '%s': %m", value
);
316 } else if (streq(key
, "ACTION")) {
317 r
= device_set_action_from_string(device
, value
);
319 return log_device_debug_errno(device
, r
, "sd-device: Failed to set action to '%s': %m", value
);
320 } else if (streq(key
, "SEQNUM")) {
321 r
= device_set_seqnum(device
, value
);
323 return log_device_debug_errno(device
, r
, "sd-device: Failed to set SEQNUM to '%s': %m", value
);
324 } else if (streq(key
, "DISKSEQ")) {
325 r
= device_set_diskseq(device
, value
);
327 return log_device_debug_errno(device
, r
, "sd-device: Failed to set DISKSEQ to '%s': %m", value
);
328 } else if (streq(key
, "DEVLINKS")) {
329 for (const char *p
= value
;;) {
330 _cleanup_free_
char *word
= NULL
;
332 /* udev rules may set escaped strings, and sd-device does not modify the input
333 * strings. So, it is also necessary to keep the strings received through
334 * sd-device-monitor. */
335 r
= extract_first_word(&p
, &word
, NULL
, EXTRACT_RETAIN_ESCAPE
);
341 r
= device_add_devlink(device
, word
);
343 return log_device_debug_errno(device
, r
, "sd-device: Failed to add devlink '%s': %m", word
);
345 } else if (STR_IN_SET(key
, "TAGS", "CURRENT_TAGS")) {
346 for (const char *p
= value
;;) {
347 _cleanup_free_
char *word
= NULL
;
349 r
= extract_first_word(&p
, &word
, ":", EXTRACT_DONT_COALESCE_SEPARATORS
);
355 r
= device_add_tag(device
, word
, streq(key
, "CURRENT_TAGS"));
357 return log_device_debug_errno(device
, r
, "sd-device: Failed to add tag '%s': %m", word
);
359 } else if (streq(key
, "UDEV_DATABASE_VERSION")) {
360 r
= safe_atou(value
, &device
->database_version
);
362 return log_device_debug_errno(device
, r
, "sd-device: Failed to parse udev database version '%s': %m", value
);
364 r
= device_add_property_internal(device
, key
, value
);
366 return log_device_debug_errno(device
, r
, "sd-device: Failed to add property '%s=%s': %m", key
, value
);
372 static int device_append(
376 const char **_minor
) {
378 const char *major
= NULL
, *minor
= NULL
;
387 value
= strchr(key
, '=');
389 return log_device_debug_errno(device
, SYNTHETIC_ERRNO(EINVAL
),
390 "sd-device: Not a key-value pair: '%s'", key
);
396 if (streq(key
, "MAJOR"))
398 else if (streq(key
, "MINOR"))
401 r
= device_amend(device
, key
, value
);
415 void device_seal(sd_device
*device
) {
418 device
->sealed
= true;
421 static int device_verify(sd_device
*device
) {
426 if (!device
->devpath
|| !device
->subsystem
|| device
->action
< 0 || device
->seqnum
== 0)
427 return log_device_debug_errno(device
, SYNTHETIC_ERRNO(EINVAL
),
428 "sd-device: Device created from strv or nulstr lacks devpath, subsystem, action or seqnum.");
430 if (streq(device
->subsystem
, "drivers")) {
431 r
= device_set_drivers_subsystem(device
);
436 device
->sealed
= true;
441 int device_new_from_strv(sd_device
**ret
, char **strv
) {
442 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
443 const char *major
= NULL
, *minor
= NULL
;
449 r
= device_new_aux(&device
);
453 STRV_FOREACH(key
, strv
) {
454 r
= device_append(device
, *key
, &major
, &minor
);
460 r
= device_set_devnum(device
, major
, minor
);
462 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devnum %s:%s: %m", major
, minor
);
465 r
= device_verify(device
);
469 *ret
= TAKE_PTR(device
);
474 int device_new_from_nulstr(sd_device
**ret
, char *nulstr
, size_t len
) {
475 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
476 const char *major
= NULL
, *minor
= NULL
;
483 r
= device_new_aux(&device
);
487 for (size_t i
= 0; i
< len
; ) {
492 end
= memchr(key
, '\0', len
- i
);
494 return log_device_debug_errno(device
, SYNTHETIC_ERRNO(EINVAL
),
495 "sd-device: Failed to parse nulstr");
499 /* netlink messages for some devices contain an unwanted newline at the end of value.
500 * Let's drop the newline and remaining characters after the newline. */
503 r
= device_append(device
, key
, &major
, &minor
);
509 r
= device_set_devnum(device
, major
, minor
);
511 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devnum %s:%s: %m", major
, minor
);
514 r
= device_verify(device
);
518 *ret
= TAKE_PTR(device
);
523 static int device_update_properties_bufs(sd_device
*device
) {
524 _cleanup_free_
char **buf_strv
= NULL
, *buf_nulstr
= NULL
;
525 size_t nulstr_len
= 0, num
= 0;
526 const char *val
, *prop
;
530 if (!device
->properties_buf_outdated
)
533 /* append udev database version */
534 buf_nulstr
= newdup(char, "UDEV_DATABASE_VERSION=" STRINGIFY(LATEST_UDEV_DATABASE_VERSION
) "\0",
535 STRLEN("UDEV_DATABASE_VERSION=" STRINGIFY(LATEST_UDEV_DATABASE_VERSION
)) + 2);
539 nulstr_len
+= STRLEN("UDEV_DATABASE_VERSION=" STRINGIFY(LATEST_UDEV_DATABASE_VERSION
)) + 1;
542 FOREACH_DEVICE_PROPERTY(device
, prop
, val
) {
545 len
= strlen(prop
) + 1 + strlen(val
);
547 buf_nulstr
= GREEDY_REALLOC0(buf_nulstr
, nulstr_len
+ len
+ 2);
551 strscpyl(buf_nulstr
+ nulstr_len
, len
+ 1, prop
, "=", val
, NULL
);
552 nulstr_len
+= len
+ 1;
556 /* build buf_strv from buf_nulstr */
557 buf_strv
= new0(char*, num
+ 1);
562 NULSTR_FOREACH(p
, buf_nulstr
)
566 free_and_replace(device
->properties_nulstr
, buf_nulstr
);
567 device
->properties_nulstr_len
= nulstr_len
;
568 free_and_replace(device
->properties_strv
, buf_strv
);
570 device
->properties_buf_outdated
= false;
574 int device_get_properties_nulstr(sd_device
*device
, const char **ret_nulstr
, size_t *ret_len
) {
579 r
= device_update_properties_bufs(device
);
584 *ret_nulstr
= device
->properties_nulstr
;
586 *ret_len
= device
->properties_nulstr_len
;
591 int device_get_properties_strv(sd_device
*device
, char ***ret
) {
596 r
= device_update_properties_bufs(device
);
601 *ret
= device
->properties_strv
;
606 int device_get_devlink_priority(sd_device
*device
, int *ret
) {
611 r
= device_read_db(device
);
616 *ret
= device
->devlink_priority
;
621 static int device_shallow_clone(sd_device
*device
, sd_device
**ret
) {
622 _cleanup_(sd_device_unrefp
) sd_device
*dest
= NULL
;
623 const char *val
= NULL
;
629 r
= device_new_aux(&dest
);
633 r
= device_set_syspath(dest
, device
->syspath
, false);
637 (void) sd_device_get_subsystem(device
, &val
);
638 r
= device_set_subsystem(dest
, val
);
641 if (streq_ptr(val
, "drivers")) {
642 r
= free_and_strdup(&dest
->driver_subsystem
, device
->driver_subsystem
);
647 /* The device may be already removed. Let's copy minimal set of information to make
648 * device_get_device_id() work without uevent file. */
650 if (sd_device_get_property_value(device
, "IFINDEX", &val
) >= 0) {
651 r
= device_set_ifindex(dest
, val
);
656 if (sd_device_get_property_value(device
, "MAJOR", &val
) >= 0) {
657 const char *minor
= NULL
;
659 (void) sd_device_get_property_value(device
, "MINOR", &minor
);
660 r
= device_set_devnum(dest
, val
, minor
);
665 r
= device_read_uevent_file(dest
);
669 *ret
= TAKE_PTR(dest
);
673 int device_clone_with_db(sd_device
*device
, sd_device
**ret
) {
674 _cleanup_(sd_device_unrefp
) sd_device
*dest
= NULL
;
680 r
= device_shallow_clone(device
, &dest
);
684 r
= device_read_db(dest
);
690 *ret
= TAKE_PTR(dest
);
694 void device_cleanup_tags(sd_device
*device
) {
697 device
->all_tags
= set_free_free(device
->all_tags
);
698 device
->current_tags
= set_free_free(device
->current_tags
);
699 device
->property_tags_outdated
= true;
700 device
->tags_generation
++;
703 void device_cleanup_devlinks(sd_device
*device
) {
706 set_free_free(device
->devlinks
);
707 device
->devlinks
= NULL
;
708 device
->property_devlinks_outdated
= true;
709 device
->devlinks_generation
++;
712 void device_remove_tag(sd_device
*device
, const char *tag
) {
716 free(set_remove(device
->current_tags
, tag
));
717 device
->property_tags_outdated
= true;
718 device
->tags_generation
++;
721 static int device_tag(sd_device
*device
, const char *tag
, bool add
) {
729 r
= device_get_device_id(device
, &id
);
733 path
= strjoina("/run/udev/tags/", tag
, "/", id
);
736 return touch_file(path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0444);
738 if (unlink(path
) < 0 && errno
!= ENOENT
)
744 int device_tag_index(sd_device
*device
, sd_device
*device_old
, bool add
) {
748 if (add
&& device_old
)
749 /* delete possible left-over tags */
750 FOREACH_DEVICE_TAG(device_old
, tag
)
751 if (!sd_device_has_tag(device
, tag
)) {
752 k
= device_tag(device_old
, tag
, false);
757 FOREACH_DEVICE_TAG(device
, tag
) {
758 k
= device_tag(device
, tag
, add
);
766 static bool device_has_info(sd_device
*device
) {
769 if (!set_isempty(device
->devlinks
))
772 if (device
->devlink_priority
!= 0)
775 if (!ordered_hashmap_isempty(device
->properties_db
))
778 if (!set_isempty(device
->all_tags
))
781 if (!set_isempty(device
->current_tags
))
787 void device_set_db_persist(sd_device
*device
) {
790 device
->db_persist
= true;
793 int device_update_db(sd_device
*device
) {
796 _cleanup_fclose_
FILE *f
= NULL
;
797 _cleanup_(unlink_and_freep
) char *path_tmp
= NULL
;
803 has_info
= device_has_info(device
);
805 r
= device_get_device_id(device
, &id
);
809 path
= strjoina("/run/udev/data/", id
);
811 /* do not store anything for otherwise empty devices */
812 if (!has_info
&& major(device
->devnum
) == 0 && device
->ifindex
== 0) {
813 if (unlink(path
) < 0 && errno
!= ENOENT
)
819 /* write a database file */
820 r
= mkdir_parents(path
, 0755);
824 r
= fopen_temporary(path
, &f
, &path_tmp
);
828 /* set 'sticky' bit to indicate that we should not clean the database when we transition from initrd
829 * to the real root */
830 if (fchmod(fileno(f
), device
->db_persist
? 01644 : 0644) < 0) {
836 const char *property
, *value
, *tag
;
838 if (major(device
->devnum
) > 0) {
841 FOREACH_DEVICE_DEVLINK(device
, devlink
)
842 fprintf(f
, "S:%s\n", devlink
+ STRLEN("/dev/"));
844 if (device
->devlink_priority
!= 0)
845 fprintf(f
, "L:%i\n", device
->devlink_priority
);
848 if (device
->usec_initialized
> 0)
849 fprintf(f
, "I:"USEC_FMT
"\n", device
->usec_initialized
);
851 ORDERED_HASHMAP_FOREACH_KEY(value
, property
, device
->properties_db
)
852 fprintf(f
, "E:%s=%s\n", property
, value
);
854 FOREACH_DEVICE_TAG(device
, tag
)
855 fprintf(f
, "G:%s\n", tag
); /* Any tag */
857 SET_FOREACH(tag
, device
->current_tags
)
858 fprintf(f
, "Q:%s\n", tag
); /* Current tag */
860 /* Always write the latest database version here, instead of the value stored in
861 * device->database_version, as which may be 0. */
862 fputs("V:" STRINGIFY(LATEST_UDEV_DATABASE_VERSION
) "\n", f
);
865 r
= fflush_and_check(f
);
869 if (rename(path_tmp
, path
) < 0) {
874 path_tmp
= mfree(path_tmp
);
876 log_device_debug(device
, "sd-device: Created %s file '%s' for '%s'", has_info
? "db" : "empty",
877 path
, device
->devpath
);
884 return log_device_debug_errno(device
, r
, "sd-device: Failed to create %s file '%s' for '%s'", has_info
? "db" : "empty", path
, device
->devpath
);
887 int device_delete_db(sd_device
*device
) {
894 r
= device_get_device_id(device
, &id
);
898 path
= strjoina("/run/udev/data/", id
);
900 if (unlink(path
) < 0 && errno
!= ENOENT
)
906 static const char* const device_action_table
[_SD_DEVICE_ACTION_MAX
] = {
907 [SD_DEVICE_ADD
] = "add",
908 [SD_DEVICE_REMOVE
] = "remove",
909 [SD_DEVICE_CHANGE
] = "change",
910 [SD_DEVICE_MOVE
] = "move",
911 [SD_DEVICE_ONLINE
] = "online",
912 [SD_DEVICE_OFFLINE
] = "offline",
913 [SD_DEVICE_BIND
] = "bind",
914 [SD_DEVICE_UNBIND
] = "unbind",
917 DEFINE_STRING_TABLE_LOOKUP(device_action
, sd_device_action_t
);
919 void dump_device_action_table(void) {
920 DUMP_STRING_TABLE(device_action
, sd_device_action_t
, _SD_DEVICE_ACTION_MAX
);