1 /* SPDX-License-Identifier: LGPL-2.1+ */
9 #include "alloc-util.h"
10 #include "device-internal.h"
11 #include "device-private.h"
12 #include "device-util.h"
19 #include "parse-util.h"
20 #include "path-util.h"
23 #include "string-table.h"
24 #include "string-util.h"
27 #include "user-util.h"
30 int device_add_property(sd_device
*device
, const char *key
, const char *value
) {
36 r
= device_add_property_aux(device
, key
, value
, false);
41 r
= device_add_property_aux(device
, key
, value
, true);
49 static int device_add_property_internal_from_string(sd_device
*device
, const char *str
) {
50 _cleanup_free_
char *key
= NULL
;
60 value
= strchr(key
, '=');
69 return device_add_property_internal(device
, key
, value
);
72 static int handle_db_line(sd_device
*device
, char key
, const char *value
) {
81 path
= strjoina("/dev/", value
);
82 r
= device_add_devlink(device
, path
);
88 r
= safe_atoi(value
, &device
->devlink_priority
);
94 r
= device_add_property_internal_from_string(device
, value
);
100 r
= device_add_tag(device
, value
);
106 r
= safe_atoi(value
, &device
->watch_handle
);
112 r
= device_set_usec_initialized(device
, value
);
118 log_debug("device db: unknown key '%c'", key
);
124 void device_set_devlink_priority(sd_device
*device
, int priority
) {
127 device
->devlink_priority
= priority
;
130 void device_set_is_initialized(sd_device
*device
) {
133 device
->is_initialized
= true;
136 int device_ensure_usec_initialized(sd_device
*device
, sd_device
*device_old
) {
137 char num
[DECIMAL_STR_MAX(usec_t
)];
138 usec_t usec_initialized
;
143 if (device_old
&& device_old
->usec_initialized
> 0)
144 usec_initialized
= device_old
->usec_initialized
;
146 usec_initialized
= now(CLOCK_MONOTONIC
);
148 r
= snprintf(num
, sizeof(num
), USEC_FMT
, usec_initialized
);
152 r
= device_set_usec_initialized(device
, num
);
159 static int device_read_db(sd_device
*device
) {
160 _cleanup_free_
char *db
= NULL
;
162 const char *id
, *value
;
178 if (device
->db_loaded
|| device
->sealed
)
181 r
= device_get_id_filename(device
, &id
);
185 path
= strjoina("/run/udev/data/", id
);
187 r
= read_full_file(path
, &db
, &db_len
);
192 return log_debug_errno(r
, "sd-device: failed to read db '%s': %m", path
);
195 /* devices with a database entry are initialized */
196 device_set_is_initialized(device
);
198 for (i
= 0; i
< db_len
; i
++) {
201 if (!strchr(NEWLINE
, db
[i
])) {
210 log_debug("sd-device: ignoring invalid db entry with key '%c'", key
);
212 state
= INVALID_LINE
;
227 if (strchr(NEWLINE
, db
[i
]))
232 if (strchr(NEWLINE
, db
[i
])) {
234 r
= handle_db_line(device
, key
, value
);
236 log_debug_errno(r
, "sd-device: failed to handle db entry '%c:%s': %m", key
, value
);
243 assert_not_reached("invalid state when parsing db");
247 device
->db_loaded
= true;
252 uint64_t device_get_properties_generation(sd_device
*device
) {
255 return device
->properties_generation
;
258 uint64_t device_get_tags_generation(sd_device
*device
) {
261 return device
->tags_generation
;
264 uint64_t device_get_devlinks_generation(sd_device
*device
) {
267 return device
->devlinks_generation
;
270 int device_get_devnode_mode(sd_device
*device
, mode_t
*mode
) {
276 r
= device_read_db(device
);
280 *mode
= device
->devmode
;
285 int device_get_devnode_uid(sd_device
*device
, uid_t
*uid
) {
291 r
= device_read_db(device
);
295 *uid
= device
->devuid
;
300 static int device_set_devuid(sd_device
*device
, const char *uid
) {
307 r
= safe_atou(uid
, &u
);
311 r
= device_add_property_internal(device
, "DEVUID", uid
);
320 int device_get_devnode_gid(sd_device
*device
, gid_t
*gid
) {
326 r
= device_read_db(device
);
330 *gid
= device
->devgid
;
335 static int device_set_devgid(sd_device
*device
, const char *gid
) {
342 r
= safe_atou(gid
, &g
);
346 r
= device_add_property_internal(device
, "DEVGID", gid
);
355 static int device_amend(sd_device
*device
, const char *key
, const char *value
) {
362 if (streq(key
, "DEVPATH")) {
365 path
= strjoina("/sys", value
);
367 /* the caller must verify or trust this data (e.g., if it comes from the kernel) */
368 r
= device_set_syspath(device
, path
, false);
370 return log_debug_errno(r
, "sd-device: could not set syspath to '%s': %m", path
);
371 } else if (streq(key
, "SUBSYSTEM")) {
372 r
= device_set_subsystem(device
, value
);
374 return log_debug_errno(r
, "sd-device: could not set subsystem to '%s': %m", value
);
375 } else if (streq(key
, "DEVTYPE")) {
376 r
= device_set_devtype(device
, value
);
378 return log_debug_errno(r
, "sd-device: could not set devtype to '%s': %m", value
);
379 } else if (streq(key
, "DEVNAME")) {
380 r
= device_set_devname(device
, value
);
382 return log_debug_errno(r
, "sd-device: could not set devname to '%s': %m", value
);
383 } else if (streq(key
, "USEC_INITIALIZED")) {
384 r
= device_set_usec_initialized(device
, value
);
386 return log_debug_errno(r
, "sd-device: could not set usec-initialized to '%s': %m", value
);
387 } else if (streq(key
, "DRIVER")) {
388 r
= device_set_driver(device
, value
);
390 return log_debug_errno(r
, "sd-device: could not set driver to '%s': %m", value
);
391 } else if (streq(key
, "IFINDEX")) {
392 r
= device_set_ifindex(device
, value
);
394 return log_debug_errno(r
, "sd-device: could not set ifindex to '%s': %m", value
);
395 } else if (streq(key
, "DEVMODE")) {
396 r
= device_set_devmode(device
, value
);
398 return log_debug_errno(r
, "sd-device: could not set devmode to '%s': %m", value
);
399 } else if (streq(key
, "DEVUID")) {
400 r
= device_set_devuid(device
, value
);
402 return log_debug_errno(r
, "sd-device: could not set devuid to '%s': %m", value
);
403 } else if (streq(key
, "DEVGID")) {
404 r
= device_set_devgid(device
, value
);
406 return log_debug_errno(r
, "sd-device: could not set devgid to '%s': %m", value
);
407 } else if (streq(key
, "DEVLINKS")) {
408 const char *word
, *state
;
411 FOREACH_WORD(word
, l
, value
, state
) {
414 strncpy(devlink
, word
, l
);
417 r
= device_add_devlink(device
, devlink
);
419 return log_debug_errno(r
, "sd-device: could not add devlink '%s': %m", devlink
);
421 } else if (streq(key
, "TAGS")) {
422 const char *word
, *state
;
425 FOREACH_WORD_SEPARATOR(word
, l
, value
, ":", state
) {
428 (void) strncpy(tag
, word
, l
);
431 r
= device_add_tag(device
, tag
);
433 return log_debug_errno(r
, "sd-device: could not add tag '%s': %m", tag
);
436 r
= device_add_property_internal(device
, key
, value
);
438 return log_debug_errno(r
, "sd-device: could not add property '%s=%s': %m", key
, value
);
444 static const char* const device_action_table
[_DEVICE_ACTION_MAX
] = {
445 [DEVICE_ACTION_ADD
] = "add",
446 [DEVICE_ACTION_REMOVE
] = "remove",
447 [DEVICE_ACTION_CHANGE
] = "change",
448 [DEVICE_ACTION_MOVE
] = "move",
449 [DEVICE_ACTION_ONLINE
] = "online",
450 [DEVICE_ACTION_OFFLINE
] = "offline",
451 [DEVICE_ACTION_BIND
] = "bind",
452 [DEVICE_ACTION_UNBIND
] = "unbind",
455 DEFINE_STRING_TABLE_LOOKUP(device_action
, DeviceAction
);
457 static int device_append(sd_device
*device
, char *key
, const char **_major
, const char **_minor
, uint64_t *_seqnum
,
458 DeviceAction
*_action
) {
459 DeviceAction action
= _DEVICE_ACTION_INVALID
;
461 const char *major
= NULL
, *minor
= NULL
;
472 value
= strchr(key
, '=');
474 log_debug("sd-device: not a key-value pair: '%s'", key
);
482 if (streq(key
, "MAJOR"))
484 else if (streq(key
, "MINOR"))
487 if (streq(key
, "ACTION")) {
488 action
= device_action_from_string(value
);
489 if (action
== _DEVICE_ACTION_INVALID
)
491 } else if (streq(key
, "SEQNUM")) {
492 r
= safe_atou64(value
, &seqnum
);
495 else if (seqnum
== 0)
496 /* kernel only sends seqnum > 0 */
500 r
= device_amend(device
, key
, value
);
511 if (action
!= _DEVICE_ACTION_INVALID
)
520 void device_seal(sd_device
*device
) {
523 device
->sealed
= true;
526 static int device_verify(sd_device
*device
, DeviceAction action
, uint64_t seqnum
) {
529 if (!device
->devpath
|| !device
->subsystem
|| action
== _DEVICE_ACTION_INVALID
|| seqnum
== 0) {
530 log_debug("sd-device: device created from strv lacks devpath, subsystem, action or seqnum");
534 device
->sealed
= true;
539 int device_new_from_strv(sd_device
**ret
, char **strv
) {
540 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
542 const char *major
= NULL
, *minor
= NULL
;
543 DeviceAction action
= _DEVICE_ACTION_INVALID
;
550 r
= device_new_aux(&device
);
554 STRV_FOREACH(key
, strv
) {
555 r
= device_append(device
, *key
, &major
, &minor
, &seqnum
, &action
);
561 r
= device_set_devnum(device
, major
, minor
);
563 return log_debug_errno(r
, "sd-device: could not set devnum %s:%s: %m", major
, minor
);
566 r
= device_verify(device
, action
, seqnum
);
570 *ret
= TAKE_PTR(device
);
575 int device_new_from_nulstr(sd_device
**ret
, uint8_t *nulstr
, size_t len
) {
576 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
577 const char *major
= NULL
, *minor
= NULL
;
578 DeviceAction action
= _DEVICE_ACTION_INVALID
;
587 r
= device_new_aux(&device
);
595 key
= (char*)&nulstr
[i
];
596 end
= memchr(key
, '\0', len
- i
);
598 log_debug("sd-device: failed to parse nulstr");
603 r
= device_append(device
, key
, &major
, &minor
, &seqnum
, &action
);
609 r
= device_set_devnum(device
, major
, minor
);
611 return log_debug_errno(r
, "sd-device: could not set devnum %s:%s: %m", major
, minor
);
614 r
= device_verify(device
, action
, seqnum
);
618 *ret
= TAKE_PTR(device
);
623 static int device_update_properties_bufs(sd_device
*device
) {
624 const char *val
, *prop
;
625 _cleanup_free_
char **buf_strv
= NULL
;
626 _cleanup_free_
uint8_t *buf_nulstr
= NULL
;
627 size_t allocated_nulstr
= 0;
628 size_t nulstr_len
= 0, num
= 0, i
= 0;
632 if (!device
->properties_buf_outdated
)
635 FOREACH_DEVICE_PROPERTY(device
, prop
, val
) {
638 len
= strlen(prop
) + 1 + strlen(val
);
640 buf_nulstr
= GREEDY_REALLOC0(buf_nulstr
, allocated_nulstr
, nulstr_len
+ len
+ 2);
644 strscpyl((char *)buf_nulstr
+ nulstr_len
, len
+ 1, prop
, "=", val
, NULL
);
645 nulstr_len
+= len
+ 1;
649 /* build buf_strv from buf_nulstr */
650 buf_strv
= new0(char *, num
+ 1);
654 NULSTR_FOREACH(val
, (char*) buf_nulstr
) {
655 buf_strv
[i
] = (char *) val
;
660 free_and_replace(device
->properties_nulstr
, buf_nulstr
);
661 device
->properties_nulstr_len
= nulstr_len
;
662 free_and_replace(device
->properties_strv
, buf_strv
);
664 device
->properties_buf_outdated
= false;
669 int device_get_properties_nulstr(sd_device
*device
, const uint8_t **nulstr
, size_t *len
) {
676 r
= device_update_properties_bufs(device
);
680 *nulstr
= device
->properties_nulstr
;
681 *len
= device
->properties_nulstr_len
;
686 int device_get_properties_strv(sd_device
*device
, char ***strv
) {
692 r
= device_update_properties_bufs(device
);
696 *strv
= device
->properties_strv
;
701 int device_get_devlink_priority(sd_device
*device
, int *priority
) {
707 r
= device_read_db(device
);
711 *priority
= device
->devlink_priority
;
716 int device_get_watch_handle(sd_device
*device
, int *handle
) {
722 r
= device_read_db(device
);
726 *handle
= device
->watch_handle
;
731 void device_set_watch_handle(sd_device
*device
, int handle
) {
734 device
->watch_handle
= handle
;
737 int device_rename(sd_device
*device
, const char *name
) {
738 _cleanup_free_
char *dirname
= NULL
;
740 const char *interface
;
746 dirname
= dirname_malloc(device
->syspath
);
750 new_syspath
= strjoina(dirname
, "/", name
);
752 /* the user must trust that the new name is correct */
753 r
= device_set_syspath(device
, new_syspath
, false);
757 r
= sd_device_get_property_value(device
, "INTERFACE", &interface
);
759 /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
760 r
= device_add_property_internal(device
, "INTERFACE_OLD", interface
);
764 r
= device_add_property_internal(device
, "INTERFACE", name
);
767 } else if (r
!= -ENOENT
)
773 int device_shallow_clone(sd_device
*old_device
, sd_device
**new_device
) {
774 _cleanup_(sd_device_unrefp
) sd_device
*ret
= NULL
;
780 r
= device_new_aux(&ret
);
784 r
= device_set_syspath(ret
, old_device
->syspath
, false);
788 r
= device_set_subsystem(ret
, old_device
->subsystem
);
792 ret
->devnum
= old_device
->devnum
;
794 *new_device
= TAKE_PTR(ret
);
799 int device_clone_with_db(sd_device
*old_device
, sd_device
**new_device
) {
800 _cleanup_(sd_device_unrefp
) sd_device
*ret
= NULL
;
806 r
= device_shallow_clone(old_device
, &ret
);
810 r
= device_read_db(ret
);
816 *new_device
= TAKE_PTR(ret
);
821 int device_new_from_synthetic_event(sd_device
**new_device
, const char *syspath
, const char *action
) {
822 _cleanup_(sd_device_unrefp
) sd_device
*ret
= NULL
;
829 r
= sd_device_new_from_syspath(&ret
, syspath
);
833 r
= device_read_uevent_file(ret
);
837 r
= device_add_property_internal(ret
, "ACTION", action
);
841 *new_device
= TAKE_PTR(ret
);
846 int device_new_from_stat_rdev(sd_device
**ret
, const struct stat
*st
) {
852 if (S_ISBLK(st
->st_mode
))
854 else if (S_ISCHR(st
->st_mode
))
859 return sd_device_new_from_devnum(ret
, type
, st
->st_rdev
);
862 int device_copy_properties(sd_device
*device_dst
, sd_device
*device_src
) {
863 const char *property
, *value
;
869 FOREACH_DEVICE_PROPERTY(device_src
, property
, value
) {
870 r
= device_add_property(device_dst
, property
, value
);
878 void device_cleanup_tags(sd_device
*device
) {
881 set_free_free(device
->tags
);
883 device
->property_tags_outdated
= true;
884 device
->tags_generation
++;
887 void device_cleanup_devlinks(sd_device
*device
) {
890 set_free_free(device
->devlinks
);
891 device
->devlinks
= NULL
;
892 device
->property_devlinks_outdated
= true;
893 device
->devlinks_generation
++;
896 void device_remove_tag(sd_device
*device
, const char *tag
) {
900 free(set_remove(device
->tags
, tag
));
901 device
->property_tags_outdated
= true;
902 device
->tags_generation
++;
905 static int device_tag(sd_device
*device
, const char *tag
, bool add
) {
913 r
= device_get_id_filename(device
, &id
);
917 path
= strjoina("/run/udev/tags/", tag
, "/", id
);
920 r
= touch_file(path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0444);
925 if (r
< 0 && errno
!= ENOENT
)
932 int device_tag_index(sd_device
*device
, sd_device
*device_old
, bool add
) {
936 if (add
&& device_old
) {
937 /* delete possible left-over tags */
938 FOREACH_DEVICE_TAG(device_old
, tag
) {
939 if (!sd_device_has_tag(device
, tag
)) {
940 k
= device_tag(device_old
, tag
, false);
947 FOREACH_DEVICE_TAG(device
, tag
) {
948 k
= device_tag(device
, tag
, add
);
956 static bool device_has_info(sd_device
*device
) {
959 if (!set_isempty(device
->devlinks
))
962 if (device
->devlink_priority
!= 0)
965 if (!ordered_hashmap_isempty(device
->properties_db
))
968 if (!set_isempty(device
->tags
))
971 if (device
->watch_handle
>= 0)
977 void device_set_db_persist(sd_device
*device
) {
980 device
->db_persist
= true;
983 int device_update_db(sd_device
*device
) {
986 _cleanup_fclose_
FILE *f
= NULL
;
987 _cleanup_free_
char *path_tmp
= NULL
;
993 has_info
= device_has_info(device
);
995 r
= device_get_id_filename(device
, &id
);
999 path
= strjoina("/run/udev/data/", id
);
1001 /* do not store anything for otherwise empty devices */
1002 if (!has_info
&& major(device
->devnum
) == 0 && device
->ifindex
== 0) {
1004 if (r
< 0 && errno
!= ENOENT
)
1010 /* write a database file */
1011 r
= mkdir_parents(path
, 0755);
1015 r
= fopen_temporary(path
, &f
, &path_tmp
);
1020 * set 'sticky' bit to indicate that we should not clean the
1021 * database when we transition from initramfs to the real root
1023 if (device
->db_persist
) {
1024 r
= fchmod(fileno(f
), 01644);
1030 r
= fchmod(fileno(f
), 0644);
1038 const char *property
, *value
, *tag
;
1041 if (major(device
->devnum
) > 0) {
1042 const char *devlink
;
1044 FOREACH_DEVICE_DEVLINK(device
, devlink
)
1045 fprintf(f
, "S:%s\n", devlink
+ STRLEN("/dev/"));
1047 if (device
->devlink_priority
!= 0)
1048 fprintf(f
, "L:%i\n", device
->devlink_priority
);
1050 if (device
->watch_handle
>= 0)
1051 fprintf(f
, "W:%i\n", device
->watch_handle
);
1054 if (device
->usec_initialized
> 0)
1055 fprintf(f
, "I:"USEC_FMT
"\n", device
->usec_initialized
);
1057 ORDERED_HASHMAP_FOREACH_KEY(value
, property
, device
->properties_db
, i
)
1058 fprintf(f
, "E:%s=%s\n", property
, value
);
1060 FOREACH_DEVICE_TAG(device
, tag
)
1061 fprintf(f
, "G:%s\n", tag
);
1064 r
= fflush_and_check(f
);
1068 r
= rename(path_tmp
, path
);
1074 log_debug("created %s file '%s' for '%s'", has_info
? "db" : "empty",
1075 path
, device
->devpath
);
1080 (void) unlink(path
);
1081 (void) unlink(path_tmp
);
1083 return log_error_errno(r
, "failed to create %s file '%s' for '%s'", has_info
? "db" : "empty", path
, device
->devpath
);
1086 int device_delete_db(sd_device
*device
) {
1093 r
= device_get_id_filename(device
, &id
);
1097 path
= strjoina("/run/udev/data/", id
);
1100 if (r
< 0 && errno
!= ENOENT
)
1106 int device_read_db_force(sd_device
*device
) {
1109 return device_read_db_aux(device
, true);