2 This file is part of systemd.
4 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
5 Copyright 2014 Tom Gundersen <teg@jklm.no>
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/types.h>
28 #include "path-util.h"
36 #include "sd-device.h"
38 #include "device-util.h"
39 #include "device-internal.h"
40 #include "device-private.h"
42 int device_add_property(sd_device *device, const char *key, const char *value) {
48 r = device_add_property_aux(device, key, value, false);
53 r = device_add_property_aux(device, key, value, true);
61 static int device_add_property_internal_from_string(sd_device *device, const char *str) {
62 _cleanup_free_ char *key = NULL;
72 value = strchr(key, '=');
81 return device_add_property_internal(device, key, value);
84 static int handle_db_line(sd_device *device, char key, const char *value) {
93 path = strjoina("/dev/", value);
94 r = device_add_devlink(device, path);
100 r = safe_atoi(value, &device->devlink_priority);
106 r = device_add_property_internal_from_string(device, value);
112 r = device_add_tag(device, value);
118 r = safe_atoi(value, &device->watch_handle);
124 r = device_set_usec_initialized(device, value);
130 log_debug("device db: unknown key '%c'", key);
136 void device_set_devlink_priority(sd_device *device, int priority) {
139 device->devlink_priority = priority;
142 void device_set_is_initialized(sd_device *device) {
145 device->is_initialized = true;
148 int device_ensure_usec_initialized(sd_device *device, sd_device *device_old) {
149 char num[DECIMAL_STR_MAX(usec_t)];
150 usec_t usec_initialized;
155 if (device_old && device_old->usec_initialized > 0)
156 usec_initialized = device_old->usec_initialized;
158 usec_initialized = now(CLOCK_MONOTONIC);
160 r = snprintf(num, sizeof(num), USEC_FMT, usec_initialized);
164 r = device_set_usec_initialized(device, num);
171 static int device_read_db(sd_device *device) {
172 _cleanup_free_ char *db = NULL;
174 const char *id, *value;
190 if (device->db_loaded || device->sealed)
193 r = device_get_id_filename(device, &id);
197 path = strjoina("/run/udev/data/", id);
199 r = read_full_file(path, &db, &db_len);
204 log_debug("sd-device: failed to read db '%s': %s", path, strerror(-r));
209 /* devices with a database entry are initialized */
210 device_set_is_initialized(device);
212 for (i = 0; i < db_len; i++) {
215 if (!strchr(NEWLINE, db[i])) {
224 log_debug("sd-device: ignoring invalid db entry with key '%c'", key);
226 state = INVALID_LINE;
241 if (strchr(NEWLINE, db[i]))
246 if (strchr(NEWLINE, db[i])) {
248 r = handle_db_line(device, key, value);
250 log_debug("sd-device: failed to handle db entry '%c:%s': %s", key, value, strerror(-r));
257 assert_not_reached("invalid state when parsing db");
261 device->db_loaded = true;
266 uint64_t device_get_properties_generation(sd_device *device) {
269 return device->properties_generation;
272 uint64_t device_get_tags_generation(sd_device *device) {
275 return device->tags_generation;
278 uint64_t device_get_devlinks_generation(sd_device *device) {
281 return device->devlinks_generation;
284 int device_get_devnode_mode(sd_device *device, mode_t *mode) {
290 r = device_read_db(device);
294 *mode = device->devmode;
299 int device_get_devnode_uid(sd_device *device, uid_t *uid) {
305 r = device_read_db(device);
309 *uid = device->devuid;
314 static int device_set_devuid(sd_device *device, const char *uid) {
321 r = safe_atou(uid, &u);
325 r = device_add_property_internal(device, "DEVUID", uid);
334 int device_get_devnode_gid(sd_device *device, gid_t *gid) {
340 r = device_read_db(device);
344 *gid = device->devgid;
349 static int device_set_devgid(sd_device *device, const char *gid) {
356 r = safe_atou(gid, &g);
360 r = device_add_property_internal(device, "DEVGID", gid);
369 static int device_amend(sd_device *device, const char *key, const char *value) {
376 if (streq(key, "DEVPATH")) {
379 path = strjoina("/sys", value);
381 /* the caller must verify or trust this data (e.g., if it comes from the kernel) */
382 r = device_set_syspath(device, path, false);
384 return log_debug_errno(r, "sd-device: could not set syspath to '%s': %m", path);
385 } else if (streq(key, "SUBSYSTEM")) {
386 r = device_set_subsystem(device, value);
388 return log_debug_errno(r, "sd-device: could not set subsystem to '%s': %m", value);
389 } else if (streq(key, "DEVTYPE")) {
390 r = device_set_devtype(device, value);
392 return log_debug_errno(r, "sd-device: could not set devtype to '%s': %m", value);
393 } else if (streq(key, "DEVNAME")) {
394 r = device_set_devname(device, value);
396 return log_debug_errno(r, "sd-device: could not set devname to '%s': %m", value);
397 } else if (streq(key, "USEC_INITIALIZED")) {
398 r = device_set_usec_initialized(device, value);
400 return log_debug_errno(r, "sd-device: could not set usec-initialized to '%s': %m", value);
401 } else if (streq(key, "DRIVER")) {
402 r = device_set_driver(device, value);
404 return log_debug_errno(r, "sd-device: could not set driver to '%s': %m", value);
405 } else if (streq(key, "IFINDEX")) {
406 r = device_set_ifindex(device, value);
408 return log_debug_errno(r, "sd-device: could not set ifindex to '%s': %m", value);
409 } else if (streq(key, "DEVMODE")) {
410 r = device_set_devmode(device, value);
412 return log_debug_errno(r, "sd-device: could not set devmode to '%s': %m", value);
413 } else if (streq(key, "DEVUID")) {
414 r = device_set_devuid(device, value);
416 return log_debug_errno(r, "sd-device: could not set devuid to '%s': %m", value);
417 } else if (streq(key, "DEVGID")) {
418 r = device_set_devgid(device, value);
420 return log_debug_errno(r, "sd-device: could not set devgid to '%s': %m", value);
421 } else if (streq(key, "DEVLINKS")) {
422 const char *word, *state;
425 FOREACH_WORD(word, l, value, state) {
428 strncpy(devlink, word, l);
431 r = device_add_devlink(device, devlink);
433 return log_debug_errno(r, "sd-device: could not add devlink '%s': %m", devlink);
435 } else if (streq(key, "TAGS")) {
436 const char *word, *state;
439 FOREACH_WORD_SEPARATOR(word, l, value, ":", state) {
442 (void)strncpy(tag, word, l);
445 r = device_add_tag(device, tag);
447 return log_debug_errno(r, "sd-device: could not add tag '%s': %m", tag);
450 r = device_add_property_internal(device, key, value);
452 return log_debug_errno(r, "sd-device: could not add property '%s=%s': %m", key, value);
458 static const char* const device_action_table[_DEVICE_ACTION_MAX] = {
459 [DEVICE_ACTION_ADD] = "add",
460 [DEVICE_ACTION_REMOVE] = "remove",
461 [DEVICE_ACTION_CHANGE] = "change",
462 [DEVICE_ACTION_MOVE] = "move",
463 [DEVICE_ACTION_ONLINE] = "online",
464 [DEVICE_ACTION_OFFLINE] = "offline",
467 DEFINE_STRING_TABLE_LOOKUP(device_action, DeviceAction);
469 static int device_append(sd_device *device, char *key, const char **_major, const char **_minor, uint64_t *_seqnum,
470 DeviceAction *_action) {
471 DeviceAction action = _DEVICE_ACTION_INVALID;
473 const char *major = NULL, *minor = NULL;
484 value = strchr(key, '=');
486 log_debug("sd-device: not a key-value pair: '%s'", key);
494 if (streq(key, "MAJOR"))
496 else if (streq(key, "MINOR"))
499 if (streq(key, "ACTION")) {
500 action = device_action_from_string(value);
501 if (action == _DEVICE_ACTION_INVALID)
503 } else if (streq(key, "SEQNUM")) {
504 r = safe_atou64(value, &seqnum);
507 else if (seqnum == 0)
508 /* kernel only sends seqnum > 0 */
512 r = device_amend(device, key, value);
523 if (action != _DEVICE_ACTION_INVALID)
532 void device_seal(sd_device *device) {
535 device->sealed = true;
538 static int device_verify(sd_device *device, DeviceAction action, uint64_t seqnum) {
541 if (!device->devpath || !device->subsystem || action == _DEVICE_ACTION_INVALID || seqnum == 0) {
542 log_debug("sd-device: device created from strv lacks devpath, subsystem, action or seqnum");
546 device->sealed = true;
551 int device_new_from_strv(sd_device **ret, char **strv) {
552 _cleanup_device_unref_ sd_device *device = NULL;
554 const char *major = NULL, *minor = NULL;
555 DeviceAction action = _DEVICE_ACTION_INVALID;
562 r = device_new_aux(&device);
566 STRV_FOREACH(key, strv) {
567 r = device_append(device, *key, &major, &minor, &seqnum, &action);
573 r = device_set_devnum(device, major, minor);
575 return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor);
578 r = device_verify(device, action, seqnum);
588 int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
589 _cleanup_device_unref_ sd_device *device = NULL;
590 const char *major = NULL, *minor = NULL;
591 DeviceAction action = _DEVICE_ACTION_INVALID;
600 r = device_new_aux(&device);
608 key = (char*)&nulstr[i];
609 end = memchr(key, '\0', len - i);
611 log_debug("sd-device: failed to parse nulstr");
616 r = device_append(device, key, &major, &minor, &seqnum, &action);
622 r = device_set_devnum(device, major, minor);
624 return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor);
627 r = device_verify(device, action, seqnum);
637 static int device_update_properties_bufs(sd_device *device) {
638 const char *val, *prop;
639 char **buf_strv = NULL;
640 uint8_t *buf_nulstr = NULL;
641 size_t allocated_nulstr = 0, allocated_strv = 0;
642 size_t nulstr_len = 0, strv_size = 0;
646 if (!device->properties_buf_outdated)
649 FOREACH_DEVICE_PROPERTY(device, prop, val) {
652 len = strlen(prop) + 1 + strlen(val);
654 buf_nulstr = GREEDY_REALLOC0(buf_nulstr, allocated_nulstr, nulstr_len + len + 2);
658 buf_strv = GREEDY_REALLOC0(buf_strv, allocated_strv, strv_size + 2);
662 buf_strv[strv_size ++] = (char *)&buf_nulstr[nulstr_len];
663 strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
664 nulstr_len += len + 1;
667 free(device->properties_nulstr);
668 free(device->properties_strv);
669 device->properties_nulstr = buf_nulstr;
670 device->properties_nulstr_len = nulstr_len;
671 device->properties_strv = buf_strv;
673 device->properties_buf_outdated = false;
678 int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len) {
685 r = device_update_properties_bufs(device);
689 *nulstr = device->properties_nulstr;
690 *len = device->properties_nulstr_len;
695 int device_get_properties_strv(sd_device *device, char ***strv) {
701 r = device_update_properties_bufs(device);
705 *strv = device->properties_strv;
710 int device_get_devlink_priority(sd_device *device, int *priority) {
716 r = device_read_db(device);
720 *priority = device->devlink_priority;
725 int device_get_watch_handle(sd_device *device, int *handle) {
731 r = device_read_db(device);
735 *handle = device->watch_handle;
740 void device_set_watch_handle(sd_device *device, int handle) {
743 device->watch_handle = handle;
746 int device_rename(sd_device *device, const char *name) {
747 _cleanup_free_ char *dirname = NULL;
749 const char *interface;
755 dirname = dirname_malloc(device->syspath);
759 new_syspath = strjoina(dirname, "/", name);
761 /* the user must trust that the new name is correct */
762 r = device_set_syspath(device, new_syspath, false);
766 r = sd_device_get_property_value(device, "INTERFACE", &interface);
768 r = device_add_property_internal(device, "INTERFACE", name);
772 /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
773 r = device_add_property_internal(device, "INTERFACE_OLD", interface);
776 } else if (r != -ENOENT)
782 int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
783 _cleanup_device_unref_ sd_device *ret = NULL;
789 r = device_new_aux(&ret);
793 r = device_set_syspath(ret, old_device->syspath, false);
797 r = device_set_subsystem(ret, old_device->subsystem);
801 ret->devnum = old_device->devnum;
809 int device_clone_with_db(sd_device *old_device, sd_device **new_device) {
810 _cleanup_device_unref_ sd_device *ret = NULL;
816 r = device_shallow_clone(old_device, &ret);
820 r = device_read_db(ret);
832 int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, const char *action) {
833 _cleanup_device_unref_ sd_device *ret = NULL;
840 r = sd_device_new_from_syspath(&ret, syspath);
844 r = device_read_uevent_file(ret);
848 r = device_add_property_internal(ret, "ACTION", action);
858 int device_copy_properties(sd_device *device_dst, sd_device *device_src) {
859 const char *property, *value;
865 FOREACH_DEVICE_PROPERTY(device_src, property, value) {
866 r = device_add_property(device_dst, property, value);
874 void device_cleanup_tags(sd_device *device) {
877 set_free_free(device->tags);
879 device->property_tags_outdated = true;
880 device->tags_generation ++;
883 void device_cleanup_devlinks(sd_device *device) {
886 set_free_free(device->devlinks);
887 device->devlinks = NULL;
888 device->property_devlinks_outdated = true;
889 device->devlinks_generation ++;
892 void device_remove_tag(sd_device *device, const char *tag) {
896 free(set_remove(device->tags, tag));
897 device->property_tags_outdated = true;
898 device->tags_generation ++;
901 static int device_tag(sd_device *device, const char *tag, bool add) {
909 r = device_get_id_filename(device, &id);
913 path = strjoina("/run/udev/tags/", tag, "/", id);
916 r = touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444);
921 if (r < 0 && errno != ENOENT)
928 int device_tag_index(sd_device *device, sd_device *device_old, bool add) {
932 if (add && device_old) {
933 /* delete possible left-over tags */
934 FOREACH_DEVICE_TAG(device_old, tag) {
935 if (!sd_device_has_tag(device, tag)) {
936 k = device_tag(device_old, tag, false);
943 FOREACH_DEVICE_TAG(device, tag) {
944 k = device_tag(device, tag, add);
952 static bool device_has_info(sd_device *device) {
955 if (!set_isempty(device->devlinks))
958 if (device->devlink_priority != 0)
961 if (!ordered_hashmap_isempty(device->properties_db))
964 if (!set_isempty(device->tags))
967 if (device->watch_handle >= 0)
973 void device_set_db_persist(sd_device *device) {
976 device->db_persist = true;
979 int device_update_db(sd_device *device) {
982 _cleanup_fclose_ FILE *f = NULL;
983 _cleanup_free_ char *path_tmp = NULL;
989 has_info = device_has_info(device);
991 r = device_get_id_filename(device, &id);
995 path = strjoina("/run/udev/data/", id);
997 /* do not store anything for otherwise empty devices */
998 if (!has_info && major(device->devnum) == 0 && device->ifindex == 0) {
1000 if (r < 0 && errno != ENOENT)
1006 /* write a database file */
1007 r = mkdir_parents(path, 0755);
1011 r = fopen_temporary(path, &f, &path_tmp);
1016 * set 'sticky' bit to indicate that we should not clean the
1017 * database when we transition from initramfs to the real root
1019 if (device->db_persist) {
1020 r = fchmod(fileno(f), 01644);
1026 r = fchmod(fileno(f), 0644);
1034 const char *property, *value, *tag;
1037 if (major(device->devnum) > 0) {
1038 const char *devlink;
1040 FOREACH_DEVICE_DEVLINK(device, devlink)
1041 fprintf(f, "S:%s\n", devlink + strlen("/dev/"));
1043 if (device->devlink_priority != 0)
1044 fprintf(f, "L:%i\n", device->devlink_priority);
1046 if (device->watch_handle >= 0)
1047 fprintf(f, "W:%i\n", device->watch_handle);
1050 if (device->usec_initialized > 0)
1051 fprintf(f, "I:"USEC_FMT"\n", device->usec_initialized);
1053 ORDERED_HASHMAP_FOREACH_KEY(value, property, device->properties_db, i)
1054 fprintf(f, "E:%s=%s\n", property, value);
1056 FOREACH_DEVICE_TAG(device, tag)
1057 fprintf(f, "G:%s\n", tag);
1060 r = fflush_and_check(f);
1064 r = rename(path_tmp, path);
1070 log_debug("created %s file '%s' for '%s'", has_info ? "db" : "empty",
1071 path, device->devpath);
1076 log_error_errno(r, "failed to create %s file '%s' for '%s'", has_info ? "db" : "empty",
1077 path, device->devpath);
1084 int device_delete_db(sd_device *device) {
1091 r = device_get_id_filename(device, &id);
1095 path = strjoina("/run/udev/data/", id);
1098 if (r < 0 && errno != ENOENT)
1104 int device_read_db_force(sd_device *device) {
1107 return device_read_db_aux(device, true);