1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
4 Copyright 2014 Tom Gundersen <teg@jklm.no>
11 #include "sd-device.h"
13 #include "alloc-util.h"
14 #include "device-internal.h"
15 #include "device-private.h"
16 #include "device-util.h"
23 #include "parse-util.h"
24 #include "path-util.h"
27 #include "string-table.h"
28 #include "string-util.h"
31 #include "user-util.h"
34 int device_add_property(sd_device
*device
, const char *key
, const char *value
) {
40 r
= device_add_property_aux(device
, key
, value
, false);
45 r
= device_add_property_aux(device
, key
, value
, true);
53 static int device_add_property_internal_from_string(sd_device
*device
, const char *str
) {
54 _cleanup_free_
char *key
= NULL
;
64 value
= strchr(key
, '=');
73 return device_add_property_internal(device
, key
, value
);
76 static int handle_db_line(sd_device
*device
, char key
, const char *value
) {
85 path
= strjoina("/dev/", value
);
86 r
= device_add_devlink(device
, path
);
92 r
= safe_atoi(value
, &device
->devlink_priority
);
98 r
= device_add_property_internal_from_string(device
, value
);
104 r
= device_add_tag(device
, value
);
110 r
= safe_atoi(value
, &device
->watch_handle
);
116 r
= device_set_usec_initialized(device
, value
);
122 log_debug("device db: unknown key '%c'", key
);
128 void device_set_devlink_priority(sd_device
*device
, int priority
) {
131 device
->devlink_priority
= priority
;
134 void device_set_is_initialized(sd_device
*device
) {
137 device
->is_initialized
= true;
140 int device_ensure_usec_initialized(sd_device
*device
, sd_device
*device_old
) {
141 char num
[DECIMAL_STR_MAX(usec_t
)];
142 usec_t usec_initialized
;
147 if (device_old
&& device_old
->usec_initialized
> 0)
148 usec_initialized
= device_old
->usec_initialized
;
150 usec_initialized
= now(CLOCK_MONOTONIC
);
152 r
= snprintf(num
, sizeof(num
), USEC_FMT
, usec_initialized
);
156 r
= device_set_usec_initialized(device
, num
);
163 static int device_read_db(sd_device
*device
) {
164 _cleanup_free_
char *db
= NULL
;
166 const char *id
, *value
;
182 if (device
->db_loaded
|| device
->sealed
)
185 r
= device_get_id_filename(device
, &id
);
189 path
= strjoina("/run/udev/data/", id
);
191 r
= read_full_file(path
, &db
, &db_len
);
196 return log_debug_errno(r
, "sd-device: failed to read db '%s': %m", path
);
199 /* devices with a database entry are initialized */
200 device_set_is_initialized(device
);
202 for (i
= 0; i
< db_len
; i
++) {
205 if (!strchr(NEWLINE
, db
[i
])) {
214 log_debug("sd-device: ignoring invalid db entry with key '%c'", key
);
216 state
= INVALID_LINE
;
231 if (strchr(NEWLINE
, db
[i
]))
236 if (strchr(NEWLINE
, db
[i
])) {
238 r
= handle_db_line(device
, key
, value
);
240 log_debug_errno(r
, "sd-device: failed to handle db entry '%c:%s': %m", key
, value
);
247 assert_not_reached("invalid state when parsing db");
251 device
->db_loaded
= true;
256 uint64_t device_get_properties_generation(sd_device
*device
) {
259 return device
->properties_generation
;
262 uint64_t device_get_tags_generation(sd_device
*device
) {
265 return device
->tags_generation
;
268 uint64_t device_get_devlinks_generation(sd_device
*device
) {
271 return device
->devlinks_generation
;
274 int device_get_devnode_mode(sd_device
*device
, mode_t
*mode
) {
280 r
= device_read_db(device
);
284 *mode
= device
->devmode
;
289 int device_get_devnode_uid(sd_device
*device
, uid_t
*uid
) {
295 r
= device_read_db(device
);
299 *uid
= device
->devuid
;
304 static int device_set_devuid(sd_device
*device
, const char *uid
) {
311 r
= safe_atou(uid
, &u
);
315 r
= device_add_property_internal(device
, "DEVUID", uid
);
324 int device_get_devnode_gid(sd_device
*device
, gid_t
*gid
) {
330 r
= device_read_db(device
);
334 *gid
= device
->devgid
;
339 static int device_set_devgid(sd_device
*device
, const char *gid
) {
346 r
= safe_atou(gid
, &g
);
350 r
= device_add_property_internal(device
, "DEVGID", gid
);
359 static int device_amend(sd_device
*device
, const char *key
, const char *value
) {
366 if (streq(key
, "DEVPATH")) {
369 path
= strjoina("/sys", value
);
371 /* the caller must verify or trust this data (e.g., if it comes from the kernel) */
372 r
= device_set_syspath(device
, path
, false);
374 return log_debug_errno(r
, "sd-device: could not set syspath to '%s': %m", path
);
375 } else if (streq(key
, "SUBSYSTEM")) {
376 r
= device_set_subsystem(device
, value
);
378 return log_debug_errno(r
, "sd-device: could not set subsystem to '%s': %m", value
);
379 } else if (streq(key
, "DEVTYPE")) {
380 r
= device_set_devtype(device
, value
);
382 return log_debug_errno(r
, "sd-device: could not set devtype to '%s': %m", value
);
383 } else if (streq(key
, "DEVNAME")) {
384 r
= device_set_devname(device
, value
);
386 return log_debug_errno(r
, "sd-device: could not set devname to '%s': %m", value
);
387 } else if (streq(key
, "USEC_INITIALIZED")) {
388 r
= device_set_usec_initialized(device
, value
);
390 return log_debug_errno(r
, "sd-device: could not set usec-initialized to '%s': %m", value
);
391 } else if (streq(key
, "DRIVER")) {
392 r
= device_set_driver(device
, value
);
394 return log_debug_errno(r
, "sd-device: could not set driver to '%s': %m", value
);
395 } else if (streq(key
, "IFINDEX")) {
396 r
= device_set_ifindex(device
, value
);
398 return log_debug_errno(r
, "sd-device: could not set ifindex to '%s': %m", value
);
399 } else if (streq(key
, "DEVMODE")) {
400 r
= device_set_devmode(device
, value
);
402 return log_debug_errno(r
, "sd-device: could not set devmode to '%s': %m", value
);
403 } else if (streq(key
, "DEVUID")) {
404 r
= device_set_devuid(device
, value
);
406 return log_debug_errno(r
, "sd-device: could not set devuid to '%s': %m", value
);
407 } else if (streq(key
, "DEVGID")) {
408 r
= device_set_devgid(device
, value
);
410 return log_debug_errno(r
, "sd-device: could not set devgid to '%s': %m", value
);
411 } else if (streq(key
, "DEVLINKS")) {
412 const char *word
, *state
;
415 FOREACH_WORD(word
, l
, value
, state
) {
418 strncpy(devlink
, word
, l
);
421 r
= device_add_devlink(device
, devlink
);
423 return log_debug_errno(r
, "sd-device: could not add devlink '%s': %m", devlink
);
425 } else if (streq(key
, "TAGS")) {
426 const char *word
, *state
;
429 FOREACH_WORD_SEPARATOR(word
, l
, value
, ":", state
) {
432 (void)strncpy(tag
, word
, l
);
435 r
= device_add_tag(device
, tag
);
437 return log_debug_errno(r
, "sd-device: could not add tag '%s': %m", tag
);
440 r
= device_add_property_internal(device
, key
, value
);
442 return log_debug_errno(r
, "sd-device: could not add property '%s=%s': %m", key
, value
);
448 static const char* const device_action_table
[_DEVICE_ACTION_MAX
] = {
449 [DEVICE_ACTION_ADD
] = "add",
450 [DEVICE_ACTION_REMOVE
] = "remove",
451 [DEVICE_ACTION_CHANGE
] = "change",
452 [DEVICE_ACTION_MOVE
] = "move",
453 [DEVICE_ACTION_ONLINE
] = "online",
454 [DEVICE_ACTION_OFFLINE
] = "offline",
455 [DEVICE_ACTION_BIND
] = "bind",
456 [DEVICE_ACTION_UNBIND
] = "unbind",
459 DEFINE_STRING_TABLE_LOOKUP(device_action
, DeviceAction
);
461 static int device_append(sd_device
*device
, char *key
, const char **_major
, const char **_minor
, uint64_t *_seqnum
,
462 DeviceAction
*_action
) {
463 DeviceAction action
= _DEVICE_ACTION_INVALID
;
465 const char *major
= NULL
, *minor
= NULL
;
476 value
= strchr(key
, '=');
478 log_debug("sd-device: not a key-value pair: '%s'", key
);
486 if (streq(key
, "MAJOR"))
488 else if (streq(key
, "MINOR"))
491 if (streq(key
, "ACTION")) {
492 action
= device_action_from_string(value
);
493 if (action
== _DEVICE_ACTION_INVALID
)
495 } else if (streq(key
, "SEQNUM")) {
496 r
= safe_atou64(value
, &seqnum
);
499 else if (seqnum
== 0)
500 /* kernel only sends seqnum > 0 */
504 r
= device_amend(device
, key
, value
);
515 if (action
!= _DEVICE_ACTION_INVALID
)
524 void device_seal(sd_device
*device
) {
527 device
->sealed
= true;
530 static int device_verify(sd_device
*device
, DeviceAction action
, uint64_t seqnum
) {
533 if (!device
->devpath
|| !device
->subsystem
|| action
== _DEVICE_ACTION_INVALID
|| seqnum
== 0) {
534 log_debug("sd-device: device created from strv lacks devpath, subsystem, action or seqnum");
538 device
->sealed
= true;
543 int device_new_from_strv(sd_device
**ret
, char **strv
) {
544 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
546 const char *major
= NULL
, *minor
= NULL
;
547 DeviceAction action
= _DEVICE_ACTION_INVALID
;
554 r
= device_new_aux(&device
);
558 STRV_FOREACH(key
, strv
) {
559 r
= device_append(device
, *key
, &major
, &minor
, &seqnum
, &action
);
565 r
= device_set_devnum(device
, major
, minor
);
567 return log_debug_errno(r
, "sd-device: could not set devnum %s:%s: %m", major
, minor
);
570 r
= device_verify(device
, action
, seqnum
);
574 *ret
= TAKE_PTR(device
);
579 int device_new_from_nulstr(sd_device
**ret
, uint8_t *nulstr
, size_t len
) {
580 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
581 const char *major
= NULL
, *minor
= NULL
;
582 DeviceAction action
= _DEVICE_ACTION_INVALID
;
591 r
= device_new_aux(&device
);
599 key
= (char*)&nulstr
[i
];
600 end
= memchr(key
, '\0', len
- i
);
602 log_debug("sd-device: failed to parse nulstr");
607 r
= device_append(device
, key
, &major
, &minor
, &seqnum
, &action
);
613 r
= device_set_devnum(device
, major
, minor
);
615 return log_debug_errno(r
, "sd-device: could not set devnum %s:%s: %m", major
, minor
);
618 r
= device_verify(device
, action
, seqnum
);
622 *ret
= TAKE_PTR(device
);
627 static int device_update_properties_bufs(sd_device
*device
) {
628 const char *val
, *prop
;
629 _cleanup_free_
char **buf_strv
= NULL
;
630 _cleanup_free_
uint8_t *buf_nulstr
= NULL
;
631 size_t allocated_nulstr
= 0;
632 size_t nulstr_len
= 0, num
= 0, i
= 0;
636 if (!device
->properties_buf_outdated
)
639 FOREACH_DEVICE_PROPERTY(device
, prop
, val
) {
642 len
= strlen(prop
) + 1 + strlen(val
);
644 buf_nulstr
= GREEDY_REALLOC0(buf_nulstr
, allocated_nulstr
, nulstr_len
+ len
+ 2);
648 strscpyl((char *)buf_nulstr
+ nulstr_len
, len
+ 1, prop
, "=", val
, NULL
);
649 nulstr_len
+= len
+ 1;
653 /* build buf_strv from buf_nulstr */
654 buf_strv
= new0(char *, num
+ 1);
658 NULSTR_FOREACH(val
, (char*) buf_nulstr
) {
659 buf_strv
[i
] = (char *) val
;
664 free_and_replace(device
->properties_nulstr
, buf_nulstr
);
665 device
->properties_nulstr_len
= nulstr_len
;
666 free_and_replace(device
->properties_strv
, buf_strv
);
668 device
->properties_buf_outdated
= false;
673 int device_get_properties_nulstr(sd_device
*device
, const uint8_t **nulstr
, size_t *len
) {
680 r
= device_update_properties_bufs(device
);
684 *nulstr
= device
->properties_nulstr
;
685 *len
= device
->properties_nulstr_len
;
690 int device_get_properties_strv(sd_device
*device
, char ***strv
) {
696 r
= device_update_properties_bufs(device
);
700 *strv
= device
->properties_strv
;
705 int device_get_devlink_priority(sd_device
*device
, int *priority
) {
711 r
= device_read_db(device
);
715 *priority
= device
->devlink_priority
;
720 int device_get_watch_handle(sd_device
*device
, int *handle
) {
726 r
= device_read_db(device
);
730 *handle
= device
->watch_handle
;
735 void device_set_watch_handle(sd_device
*device
, int handle
) {
738 device
->watch_handle
= handle
;
741 int device_rename(sd_device
*device
, const char *name
) {
742 _cleanup_free_
char *dirname
= NULL
;
744 const char *interface
;
750 dirname
= dirname_malloc(device
->syspath
);
754 new_syspath
= strjoina(dirname
, "/", name
);
756 /* the user must trust that the new name is correct */
757 r
= device_set_syspath(device
, new_syspath
, false);
761 r
= sd_device_get_property_value(device
, "INTERFACE", &interface
);
763 /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
764 r
= device_add_property_internal(device
, "INTERFACE_OLD", interface
);
768 r
= device_add_property_internal(device
, "INTERFACE", name
);
771 } else if (r
!= -ENOENT
)
777 int device_shallow_clone(sd_device
*old_device
, sd_device
**new_device
) {
778 _cleanup_(sd_device_unrefp
) sd_device
*ret
= NULL
;
784 r
= device_new_aux(&ret
);
788 r
= device_set_syspath(ret
, old_device
->syspath
, false);
792 r
= device_set_subsystem(ret
, old_device
->subsystem
);
796 ret
->devnum
= old_device
->devnum
;
798 *new_device
= TAKE_PTR(ret
);
803 int device_clone_with_db(sd_device
*old_device
, sd_device
**new_device
) {
804 _cleanup_(sd_device_unrefp
) sd_device
*ret
= NULL
;
810 r
= device_shallow_clone(old_device
, &ret
);
814 r
= device_read_db(ret
);
820 *new_device
= TAKE_PTR(ret
);
825 int device_new_from_synthetic_event(sd_device
**new_device
, const char *syspath
, const char *action
) {
826 _cleanup_(sd_device_unrefp
) sd_device
*ret
= NULL
;
833 r
= sd_device_new_from_syspath(&ret
, syspath
);
837 r
= device_read_uevent_file(ret
);
841 r
= device_add_property_internal(ret
, "ACTION", action
);
845 *new_device
= TAKE_PTR(ret
);
850 int device_copy_properties(sd_device
*device_dst
, sd_device
*device_src
) {
851 const char *property
, *value
;
857 FOREACH_DEVICE_PROPERTY(device_src
, property
, value
) {
858 r
= device_add_property(device_dst
, property
, value
);
866 void device_cleanup_tags(sd_device
*device
) {
869 set_free_free(device
->tags
);
871 device
->property_tags_outdated
= true;
872 device
->tags_generation
++;
875 void device_cleanup_devlinks(sd_device
*device
) {
878 set_free_free(device
->devlinks
);
879 device
->devlinks
= NULL
;
880 device
->property_devlinks_outdated
= true;
881 device
->devlinks_generation
++;
884 void device_remove_tag(sd_device
*device
, const char *tag
) {
888 free(set_remove(device
->tags
, tag
));
889 device
->property_tags_outdated
= true;
890 device
->tags_generation
++;
893 static int device_tag(sd_device
*device
, const char *tag
, bool add
) {
901 r
= device_get_id_filename(device
, &id
);
905 path
= strjoina("/run/udev/tags/", tag
, "/", id
);
908 r
= touch_file(path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0444);
913 if (r
< 0 && errno
!= ENOENT
)
920 int device_tag_index(sd_device
*device
, sd_device
*device_old
, bool add
) {
924 if (add
&& device_old
) {
925 /* delete possible left-over tags */
926 FOREACH_DEVICE_TAG(device_old
, tag
) {
927 if (!sd_device_has_tag(device
, tag
)) {
928 k
= device_tag(device_old
, tag
, false);
935 FOREACH_DEVICE_TAG(device
, tag
) {
936 k
= device_tag(device
, tag
, add
);
944 static bool device_has_info(sd_device
*device
) {
947 if (!set_isempty(device
->devlinks
))
950 if (device
->devlink_priority
!= 0)
953 if (!ordered_hashmap_isempty(device
->properties_db
))
956 if (!set_isempty(device
->tags
))
959 if (device
->watch_handle
>= 0)
965 void device_set_db_persist(sd_device
*device
) {
968 device
->db_persist
= true;
971 int device_update_db(sd_device
*device
) {
974 _cleanup_fclose_
FILE *f
= NULL
;
975 _cleanup_free_
char *path_tmp
= NULL
;
981 has_info
= device_has_info(device
);
983 r
= device_get_id_filename(device
, &id
);
987 path
= strjoina("/run/udev/data/", id
);
989 /* do not store anything for otherwise empty devices */
990 if (!has_info
&& major(device
->devnum
) == 0 && device
->ifindex
== 0) {
992 if (r
< 0 && errno
!= ENOENT
)
998 /* write a database file */
999 r
= mkdir_parents(path
, 0755);
1003 r
= fopen_temporary(path
, &f
, &path_tmp
);
1008 * set 'sticky' bit to indicate that we should not clean the
1009 * database when we transition from initramfs to the real root
1011 if (device
->db_persist
) {
1012 r
= fchmod(fileno(f
), 01644);
1018 r
= fchmod(fileno(f
), 0644);
1026 const char *property
, *value
, *tag
;
1029 if (major(device
->devnum
) > 0) {
1030 const char *devlink
;
1032 FOREACH_DEVICE_DEVLINK(device
, devlink
)
1033 fprintf(f
, "S:%s\n", devlink
+ STRLEN("/dev/"));
1035 if (device
->devlink_priority
!= 0)
1036 fprintf(f
, "L:%i\n", device
->devlink_priority
);
1038 if (device
->watch_handle
>= 0)
1039 fprintf(f
, "W:%i\n", device
->watch_handle
);
1042 if (device
->usec_initialized
> 0)
1043 fprintf(f
, "I:"USEC_FMT
"\n", device
->usec_initialized
);
1045 ORDERED_HASHMAP_FOREACH_KEY(value
, property
, device
->properties_db
, i
)
1046 fprintf(f
, "E:%s=%s\n", property
, value
);
1048 FOREACH_DEVICE_TAG(device
, tag
)
1049 fprintf(f
, "G:%s\n", tag
);
1052 r
= fflush_and_check(f
);
1056 r
= rename(path_tmp
, path
);
1062 log_debug("created %s file '%s' for '%s'", has_info
? "db" : "empty",
1063 path
, device
->devpath
);
1068 (void) unlink(path
);
1069 (void) unlink(path_tmp
);
1071 return log_error_errno(r
, "failed to create %s file '%s' for '%s'", has_info
? "db" : "empty", path
, device
->devpath
);
1074 int device_delete_db(sd_device
*device
) {
1081 r
= device_get_id_filename(device
, &id
);
1085 path
= strjoina("/run/udev/data/", id
);
1088 if (r
< 0 && errno
!= ENOENT
)
1094 int device_read_db_force(sd_device
*device
) {
1097 return device_read_db_aux(device
, true);