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 "nulstr-util.h"
20 #include "parse-util.h"
21 #include "path-util.h"
23 #include "string-table.h"
24 #include "string-util.h"
27 #include "tmpfile-util.h"
28 #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 void device_set_devlink_priority(sd_device
*device
, int priority
) {
52 device
->devlink_priority
= priority
;
55 void device_set_is_initialized(sd_device
*device
) {
58 device
->is_initialized
= true;
61 int device_ensure_usec_initialized(sd_device
*device
, sd_device
*device_old
) {
66 if (device_old
&& device_old
->usec_initialized
> 0)
67 when
= device_old
->usec_initialized
;
69 when
= now(CLOCK_MONOTONIC
);
71 return device_set_usec_initialized(device
, when
);
74 uint64_t device_get_properties_generation(sd_device
*device
) {
77 return device
->properties_generation
;
80 uint64_t device_get_tags_generation(sd_device
*device
) {
83 return device
->tags_generation
;
86 uint64_t device_get_devlinks_generation(sd_device
*device
) {
89 return device
->devlinks_generation
;
92 int device_get_devnode_mode(sd_device
*device
, mode_t
*mode
) {
97 r
= device_read_db(device
);
101 if (device
->devmode
== (mode_t
) -1)
105 *mode
= device
->devmode
;
110 int device_get_devnode_uid(sd_device
*device
, uid_t
*uid
) {
115 r
= device_read_db(device
);
119 if (device
->devuid
== (uid_t
) -1)
123 *uid
= device
->devuid
;
128 static int device_set_devuid(sd_device
*device
, const char *uid
) {
135 r
= safe_atou(uid
, &u
);
139 r
= device_add_property_internal(device
, "DEVUID", uid
);
148 int device_get_devnode_gid(sd_device
*device
, gid_t
*gid
) {
153 r
= device_read_db(device
);
157 if (device
->devgid
== (gid_t
) -1)
161 *gid
= device
->devgid
;
166 static int device_set_devgid(sd_device
*device
, const char *gid
) {
173 r
= safe_atou(gid
, &g
);
177 r
= device_add_property_internal(device
, "DEVGID", gid
);
186 int device_get_action(sd_device
*device
, DeviceAction
*action
) {
189 if (device
->action
< 0)
193 *action
= device
->action
;
198 static int device_set_action(sd_device
*device
, const char *action
) {
205 a
= device_action_from_string(action
);
209 r
= device_add_property_internal(device
, "ACTION", action
);
218 int device_get_seqnum(sd_device
*device
, uint64_t *seqnum
) {
221 if (device
->seqnum
== 0)
225 *seqnum
= device
->seqnum
;
230 static int device_set_seqnum(sd_device
*device
, const char *str
) {
237 r
= safe_atou64(str
, &seqnum
);
243 r
= device_add_property_internal(device
, "SEQNUM", str
);
247 device
->seqnum
= seqnum
;
252 static int device_amend(sd_device
*device
, const char *key
, const char *value
) {
259 if (streq(key
, "DEVPATH")) {
262 path
= strjoina("/sys", value
);
264 /* the caller must verify or trust this data (e.g., if it comes from the kernel) */
265 r
= device_set_syspath(device
, path
, false);
267 return log_device_debug_errno(device
, r
, "sd-device: Failed to set syspath to '%s': %m", path
);
268 } else if (streq(key
, "SUBSYSTEM")) {
269 r
= device_set_subsystem(device
, value
);
271 return log_device_debug_errno(device
, r
, "sd-device: Failed to set subsystem to '%s': %m", value
);
272 } else if (streq(key
, "DEVTYPE")) {
273 r
= device_set_devtype(device
, value
);
275 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devtype to '%s': %m", value
);
276 } else if (streq(key
, "DEVNAME")) {
277 r
= device_set_devname(device
, value
);
279 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devname to '%s': %m", value
);
280 } else if (streq(key
, "USEC_INITIALIZED")) {
283 r
= safe_atou64(value
, &t
);
285 return log_device_debug_errno(device
, r
, "sd-device: Failed to parse timestamp '%s': %m", value
);
287 r
= device_set_usec_initialized(device
, t
);
289 return log_device_debug_errno(device
, r
, "sd-device: Failed to set usec-initialized to '%s': %m", value
);
290 } else if (streq(key
, "DRIVER")) {
291 r
= device_set_driver(device
, value
);
293 return log_device_debug_errno(device
, r
, "sd-device: Failed to set driver to '%s': %m", value
);
294 } else if (streq(key
, "IFINDEX")) {
295 r
= device_set_ifindex(device
, value
);
297 return log_device_debug_errno(device
, r
, "sd-device: Failed to set ifindex to '%s': %m", value
);
298 } else if (streq(key
, "DEVMODE")) {
299 r
= device_set_devmode(device
, value
);
301 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devmode to '%s': %m", value
);
302 } else if (streq(key
, "DEVUID")) {
303 r
= device_set_devuid(device
, value
);
305 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devuid to '%s': %m", value
);
306 } else if (streq(key
, "DEVGID")) {
307 r
= device_set_devgid(device
, value
);
309 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devgid to '%s': %m", value
);
310 } else if (streq(key
, "ACTION")) {
311 r
= device_set_action(device
, value
);
313 return log_device_debug_errno(device
, r
, "sd-device: Failed to set action to '%s': %m", value
);
314 } else if (streq(key
, "SEQNUM")) {
315 r
= device_set_seqnum(device
, value
);
317 return log_device_debug_errno(device
, r
, "sd-device: Failed to set SEQNUM to '%s': %m", value
);
318 } else if (streq(key
, "DEVLINKS")) {
319 const char *word
, *state
;
322 FOREACH_WORD(word
, l
, value
, state
) {
325 strncpy(devlink
, word
, l
);
328 r
= device_add_devlink(device
, devlink
);
330 return log_device_debug_errno(device
, r
, "sd-device: Failed to add devlink '%s': %m", devlink
);
332 } else if (STR_IN_SET(key
, "TAGS", "CURRENT_TAGS")) {
333 const char *word
, *state
;
336 FOREACH_WORD_SEPARATOR(word
, l
, value
, ":", state
) {
339 (void) strncpy(tag
, word
, l
);
342 r
= device_add_tag(device
, tag
, streq(key
, "CURRENT_TAGS"));
344 return log_device_debug_errno(device
, r
, "sd-device: Failed to add tag '%s': %m", tag
);
348 r
= device_add_property_internal(device
, key
, value
);
350 return log_device_debug_errno(device
, r
, "sd-device: Failed to add property '%s=%s': %m", key
, value
);
356 static int device_append(sd_device
*device
, char *key
, const char **_major
, const char **_minor
) {
357 const char *major
= NULL
, *minor
= NULL
;
366 value
= strchr(key
, '=');
368 return log_device_debug_errno(device
, SYNTHETIC_ERRNO(EINVAL
),
369 "sd-device: Not a key-value pair: '%s'", key
);
375 if (streq(key
, "MAJOR"))
377 else if (streq(key
, "MINOR"))
380 r
= device_amend(device
, key
, value
);
394 void device_seal(sd_device
*device
) {
397 device
->sealed
= true;
400 static int device_verify(sd_device
*device
) {
403 if (!device
->devpath
|| !device
->subsystem
|| device
->action
< 0 || device
->seqnum
== 0)
404 return log_device_debug_errno(device
, SYNTHETIC_ERRNO(EINVAL
),
405 "sd-device: Device created from strv or nulstr lacks devpath, subsystem, action or seqnum.");
407 device
->sealed
= true;
412 int device_new_from_strv(sd_device
**ret
, char **strv
) {
413 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
415 const char *major
= NULL
, *minor
= NULL
;
421 r
= device_new_aux(&device
);
425 STRV_FOREACH(key
, strv
) {
426 r
= device_append(device
, *key
, &major
, &minor
);
432 r
= device_set_devnum(device
, major
, minor
);
434 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devnum %s:%s: %m", major
, minor
);
437 r
= device_verify(device
);
441 *ret
= TAKE_PTR(device
);
446 int device_new_from_nulstr(sd_device
**ret
, uint8_t *nulstr
, size_t len
) {
447 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
448 const char *major
= NULL
, *minor
= NULL
;
456 r
= device_new_aux(&device
);
464 key
= (char*)&nulstr
[i
];
465 end
= memchr(key
, '\0', len
- i
);
467 return log_device_debug_errno(device
, SYNTHETIC_ERRNO(EINVAL
),
468 "sd-device: Failed to parse nulstr");
472 r
= device_append(device
, key
, &major
, &minor
);
478 r
= device_set_devnum(device
, major
, minor
);
480 return log_device_debug_errno(device
, r
, "sd-device: Failed to set devnum %s:%s: %m", major
, minor
);
483 r
= device_verify(device
);
487 *ret
= TAKE_PTR(device
);
492 static int device_update_properties_bufs(sd_device
*device
) {
493 const char *val
, *prop
;
494 _cleanup_free_
char **buf_strv
= NULL
;
495 _cleanup_free_
uint8_t *buf_nulstr
= NULL
;
496 size_t allocated_nulstr
= 0;
497 size_t nulstr_len
= 0, num
= 0, i
= 0;
501 if (!device
->properties_buf_outdated
)
504 FOREACH_DEVICE_PROPERTY(device
, prop
, val
) {
507 len
= strlen(prop
) + 1 + strlen(val
);
509 buf_nulstr
= GREEDY_REALLOC0(buf_nulstr
, allocated_nulstr
, nulstr_len
+ len
+ 2);
513 strscpyl((char *)buf_nulstr
+ nulstr_len
, len
+ 1, prop
, "=", val
, NULL
);
514 nulstr_len
+= len
+ 1;
518 /* build buf_strv from buf_nulstr */
519 buf_strv
= new0(char *, num
+ 1);
523 NULSTR_FOREACH(val
, (char*) buf_nulstr
) {
524 buf_strv
[i
] = (char *) val
;
529 free_and_replace(device
->properties_nulstr
, buf_nulstr
);
530 device
->properties_nulstr_len
= nulstr_len
;
531 free_and_replace(device
->properties_strv
, buf_strv
);
533 device
->properties_buf_outdated
= false;
538 int device_get_properties_nulstr(sd_device
*device
, const uint8_t **nulstr
, size_t *len
) {
545 r
= device_update_properties_bufs(device
);
549 *nulstr
= device
->properties_nulstr
;
550 *len
= device
->properties_nulstr_len
;
555 int device_get_properties_strv(sd_device
*device
, char ***strv
) {
561 r
= device_update_properties_bufs(device
);
565 *strv
= device
->properties_strv
;
570 int device_get_devlink_priority(sd_device
*device
, int *priority
) {
576 r
= device_read_db(device
);
580 *priority
= device
->devlink_priority
;
585 int device_get_watch_handle(sd_device
*device
, int *handle
) {
590 r
= device_read_db(device
);
594 if (device
->watch_handle
< 0)
598 *handle
= device
->watch_handle
;
603 void device_set_watch_handle(sd_device
*device
, int handle
) {
606 device
->watch_handle
= handle
;
609 int device_rename(sd_device
*device
, const char *name
) {
610 _cleanup_free_
char *dirname
= NULL
;
611 const char *new_syspath
, *interface
;
617 dirname
= dirname_malloc(device
->syspath
);
621 new_syspath
= prefix_roota(dirname
, name
);
623 /* the user must trust that the new name is correct */
624 r
= device_set_syspath(device
, new_syspath
, false);
628 r
= sd_device_get_property_value(device
, "INTERFACE", &interface
);
630 /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
631 r
= device_add_property_internal(device
, "INTERFACE_OLD", interface
);
635 r
= device_add_property_internal(device
, "INTERFACE", name
);
638 } else if (r
!= -ENOENT
)
644 int device_shallow_clone(sd_device
*old_device
, sd_device
**new_device
) {
645 _cleanup_(sd_device_unrefp
) sd_device
*ret
= NULL
;
651 r
= device_new_aux(&ret
);
655 r
= device_set_syspath(ret
, old_device
->syspath
, false);
659 r
= device_set_subsystem(ret
, old_device
->subsystem
);
663 ret
->devnum
= old_device
->devnum
;
665 *new_device
= TAKE_PTR(ret
);
670 int device_clone_with_db(sd_device
*old_device
, sd_device
**new_device
) {
671 _cleanup_(sd_device_unrefp
) sd_device
*ret
= NULL
;
677 r
= device_shallow_clone(old_device
, &ret
);
681 r
= device_read_db(ret
);
687 *new_device
= TAKE_PTR(ret
);
692 int device_new_from_synthetic_event(sd_device
**new_device
, const char *syspath
, const char *action
) {
693 _cleanup_(sd_device_unrefp
) sd_device
*ret
= NULL
;
700 r
= sd_device_new_from_syspath(&ret
, syspath
);
704 r
= device_read_uevent_file(ret
);
708 r
= device_set_action(ret
, action
);
712 *new_device
= TAKE_PTR(ret
);
717 int device_new_from_stat_rdev(sd_device
**ret
, const struct stat
*st
) {
723 if (S_ISBLK(st
->st_mode
))
725 else if (S_ISCHR(st
->st_mode
))
730 return sd_device_new_from_devnum(ret
, type
, st
->st_rdev
);
733 int device_copy_properties(sd_device
*device_dst
, sd_device
*device_src
) {
734 const char *property
, *value
;
740 r
= device_properties_prepare(device_src
);
744 ORDERED_HASHMAP_FOREACH_KEY(value
, property
, device_src
->properties_db
) {
745 r
= device_add_property_aux(device_dst
, property
, value
, true);
750 ORDERED_HASHMAP_FOREACH_KEY(value
, property
, device_src
->properties
) {
751 r
= device_add_property_aux(device_dst
, property
, value
, false);
759 void device_cleanup_tags(sd_device
*device
) {
762 device
->all_tags
= set_free_free(device
->all_tags
);
763 device
->current_tags
= set_free_free(device
->current_tags
);
764 device
->property_tags_outdated
= true;
765 device
->tags_generation
++;
768 void device_cleanup_devlinks(sd_device
*device
) {
771 set_free_free(device
->devlinks
);
772 device
->devlinks
= NULL
;
773 device
->property_devlinks_outdated
= true;
774 device
->devlinks_generation
++;
777 void device_remove_tag(sd_device
*device
, const char *tag
) {
781 free(set_remove(device
->current_tags
, tag
));
782 device
->property_tags_outdated
= true;
783 device
->tags_generation
++;
786 static int device_tag(sd_device
*device
, const char *tag
, bool add
) {
794 r
= device_get_id_filename(device
, &id
);
798 path
= strjoina("/run/udev/tags/", tag
, "/", id
);
801 r
= touch_file(path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0444);
806 if (r
< 0 && errno
!= ENOENT
)
813 int device_tag_index(sd_device
*device
, sd_device
*device_old
, bool add
) {
817 if (add
&& device_old
) {
818 /* delete possible left-over tags */
819 FOREACH_DEVICE_TAG(device_old
, tag
) {
820 if (!sd_device_has_tag(device
, tag
)) {
821 k
= device_tag(device_old
, tag
, false);
828 FOREACH_DEVICE_TAG(device
, tag
) {
829 k
= device_tag(device
, tag
, add
);
837 static bool device_has_info(sd_device
*device
) {
840 if (!set_isempty(device
->devlinks
))
843 if (device
->devlink_priority
!= 0)
846 if (!ordered_hashmap_isempty(device
->properties_db
))
849 if (!set_isempty(device
->all_tags
))
852 if (!set_isempty(device
->current_tags
))
855 if (device
->watch_handle
>= 0)
861 void device_set_db_persist(sd_device
*device
) {
864 device
->db_persist
= true;
867 int device_update_db(sd_device
*device
) {
870 _cleanup_fclose_
FILE *f
= NULL
;
871 _cleanup_free_
char *path_tmp
= NULL
;
877 has_info
= device_has_info(device
);
879 r
= device_get_id_filename(device
, &id
);
883 path
= strjoina("/run/udev/data/", id
);
885 /* do not store anything for otherwise empty devices */
886 if (!has_info
&& major(device
->devnum
) == 0 && device
->ifindex
== 0) {
888 if (r
< 0 && errno
!= ENOENT
)
894 /* write a database file */
895 r
= mkdir_parents(path
, 0755);
899 r
= fopen_temporary(path
, &f
, &path_tmp
);
904 * set 'sticky' bit to indicate that we should not clean the
905 * database when we transition from initramfs to the real root
907 if (device
->db_persist
) {
908 r
= fchmod(fileno(f
), 01644);
914 r
= fchmod(fileno(f
), 0644);
922 const char *property
, *value
, *tag
;
924 if (major(device
->devnum
) > 0) {
927 FOREACH_DEVICE_DEVLINK(device
, devlink
)
928 fprintf(f
, "S:%s\n", devlink
+ STRLEN("/dev/"));
930 if (device
->devlink_priority
!= 0)
931 fprintf(f
, "L:%i\n", device
->devlink_priority
);
933 if (device
->watch_handle
>= 0)
934 fprintf(f
, "W:%i\n", device
->watch_handle
);
937 if (device
->usec_initialized
> 0)
938 fprintf(f
, "I:"USEC_FMT
"\n", device
->usec_initialized
);
940 ORDERED_HASHMAP_FOREACH_KEY(value
, property
, device
->properties_db
)
941 fprintf(f
, "E:%s=%s\n", property
, value
);
943 FOREACH_DEVICE_TAG(device
, tag
)
944 fprintf(f
, "G:%s\n", tag
); /* Any tag */
946 SET_FOREACH(tag
, device
->current_tags
)
947 fprintf(f
, "Q:%s\n", tag
); /* Current tag */
950 r
= fflush_and_check(f
);
954 r
= rename(path_tmp
, path
);
960 log_device_debug(device
, "sd-device: Created %s file '%s' for '%s'", has_info
? "db" : "empty",
961 path
, device
->devpath
);
967 (void) unlink(path_tmp
);
969 return log_device_debug_errno(device
, r
, "sd-device: Failed to create %s file '%s' for '%s'", has_info
? "db" : "empty", path
, device
->devpath
);
972 int device_delete_db(sd_device
*device
) {
979 r
= device_get_id_filename(device
, &id
);
983 path
= strjoina("/run/udev/data/", id
);
986 if (r
< 0 && errno
!= ENOENT
)
992 static const char* const device_action_table
[_DEVICE_ACTION_MAX
] = {
993 [DEVICE_ACTION_ADD
] = "add",
994 [DEVICE_ACTION_REMOVE
] = "remove",
995 [DEVICE_ACTION_CHANGE
] = "change",
996 [DEVICE_ACTION_MOVE
] = "move",
997 [DEVICE_ACTION_ONLINE
] = "online",
998 [DEVICE_ACTION_OFFLINE
] = "offline",
999 [DEVICE_ACTION_BIND
] = "bind",
1000 [DEVICE_ACTION_UNBIND
] = "unbind",
1003 DEFINE_STRING_TABLE_LOOKUP(device_action
, DeviceAction
);
1005 void dump_device_action_table(void) {
1006 DUMP_STRING_TABLE(device_action
, DeviceAction
, _DEVICE_ACTION_MAX
);