]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-device/sd-device.c
Merge pull request #24263 from pothos/sysext-for-static-binaries
[thirdparty/systemd.git] / src / libsystemd / sd-device / sd-device.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <ctype.h>
4 #include <net/if.h>
5 #include <sys/ioctl.h>
6 #include <sys/types.h>
7
8 #include "sd-device.h"
9
10 #include "alloc-util.h"
11 #include "chase-symlinks.h"
12 #include "device-internal.h"
13 #include "device-private.h"
14 #include "device-util.h"
15 #include "devnum-util.h"
16 #include "dirent-util.h"
17 #include "env-util.h"
18 #include "fd-util.h"
19 #include "fileio.h"
20 #include "format-util.h"
21 #include "fs-util.h"
22 #include "hashmap.h"
23 #include "id128-util.h"
24 #include "macro.h"
25 #include "missing_magic.h"
26 #include "netlink-util.h"
27 #include "parse-util.h"
28 #include "path-util.h"
29 #include "set.h"
30 #include "socket-util.h"
31 #include "stdio-util.h"
32 #include "string-util.h"
33 #include "strv.h"
34 #include "strxcpyx.h"
35 #include "user-util.h"
36 #include "util.h"
37
38 int device_new_aux(sd_device **ret) {
39 sd_device *device;
40
41 assert(ret);
42
43 device = new(sd_device, 1);
44 if (!device)
45 return -ENOMEM;
46
47 *device = (sd_device) {
48 .n_ref = 1,
49 .watch_handle = -1,
50 .devmode = MODE_INVALID,
51 .devuid = UID_INVALID,
52 .devgid = GID_INVALID,
53 .action = _SD_DEVICE_ACTION_INVALID,
54 };
55
56 *ret = device;
57 return 0;
58 }
59
60 static sd_device *device_free(sd_device *device) {
61 assert(device);
62
63 sd_device_unref(device->parent);
64 free(device->syspath);
65 free(device->sysname);
66 free(device->devtype);
67 free(device->devname);
68 free(device->subsystem);
69 free(device->driver_subsystem);
70 free(device->driver);
71 free(device->device_id);
72 free(device->properties_strv);
73 free(device->properties_nulstr);
74
75 ordered_hashmap_free(device->properties);
76 ordered_hashmap_free(device->properties_db);
77 hashmap_free(device->sysattr_values);
78 set_free(device->sysattrs);
79 set_free(device->all_tags);
80 set_free(device->current_tags);
81 set_free(device->devlinks);
82
83 return mfree(device);
84 }
85
86 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_device, sd_device, device_free);
87
88 int device_add_property_aux(sd_device *device, const char *key, const char *value, bool db) {
89 OrderedHashmap **properties;
90
91 assert(device);
92 assert(key);
93
94 if (db)
95 properties = &device->properties_db;
96 else
97 properties = &device->properties;
98
99 if (value) {
100 _unused_ _cleanup_free_ char *old_value = NULL;
101 _cleanup_free_ char *new_key = NULL, *new_value = NULL, *old_key = NULL;
102 int r;
103
104 r = ordered_hashmap_ensure_allocated(properties, &string_hash_ops_free_free);
105 if (r < 0)
106 return r;
107
108 new_key = strdup(key);
109 if (!new_key)
110 return -ENOMEM;
111
112 new_value = strdup(value);
113 if (!new_value)
114 return -ENOMEM;
115
116 old_value = ordered_hashmap_get2(*properties, key, (void**) &old_key);
117
118 /* ordered_hashmap_replace() does not fail when the hashmap already has the entry. */
119 r = ordered_hashmap_replace(*properties, new_key, new_value);
120 if (r < 0)
121 return r;
122
123 TAKE_PTR(new_key);
124 TAKE_PTR(new_value);
125 } else {
126 _unused_ _cleanup_free_ char *old_value = NULL;
127 _cleanup_free_ char *old_key = NULL;
128
129 old_value = ordered_hashmap_remove2(*properties, key, (void**) &old_key);
130 }
131
132 if (!db) {
133 device->properties_generation++;
134 device->properties_buf_outdated = true;
135 }
136
137 return 0;
138 }
139
140 int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
141 _cleanup_free_ char *syspath = NULL;
142 const char *devpath;
143 int r;
144
145 assert(device);
146 assert(_syspath);
147
148 if (verify) {
149 _cleanup_close_ int fd = -1;
150
151 /* The input path maybe a symlink located outside of /sys. Let's try to chase the symlink at first.
152 * The primary usecase is that e.g. /proc/device-tree is a symlink to /sys/firmware/devicetree/base.
153 * By chasing symlinks in the path at first, we can call sd_device_new_from_path() with such path. */
154 r = chase_symlinks(_syspath, NULL, 0, &syspath, &fd);
155 if (r == -ENOENT)
156 /* the device does not exist (any more?) */
157 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
158 "sd-device: Failed to chase symlinks in \"%s\".", _syspath);
159 if (r < 0)
160 return log_debug_errno(r, "sd-device: Failed to get target of '%s': %m", _syspath);
161
162 if (!path_startswith(syspath, "/sys")) {
163 _cleanup_free_ char *real_sys = NULL, *new_syspath = NULL;
164 char *p;
165
166 /* /sys is a symlink to somewhere sysfs is mounted on? In that case, we convert the path to real sysfs to "/sys". */
167 r = chase_symlinks("/sys", NULL, 0, &real_sys, NULL);
168 if (r < 0)
169 return log_debug_errno(r, "sd-device: Failed to chase symlink /sys: %m");
170
171 p = path_startswith(syspath, real_sys);
172 if (!p)
173 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
174 "sd-device: Canonicalized path '%s' does not starts with sysfs mount point '%s'",
175 syspath, real_sys);
176
177 new_syspath = path_join("/sys", p);
178 if (!new_syspath)
179 return log_oom_debug();
180
181 free_and_replace(syspath, new_syspath);
182 path_simplify(syspath);
183 }
184
185 if (path_startswith(syspath, "/sys/devices/")) {
186 /* For proper devices, stricter rules apply: they must have a 'uevent' file,
187 * otherwise we won't allow them */
188
189 if (faccessat(fd, "uevent", F_OK, 0) < 0) {
190 if (errno == ENOENT)
191 /* This is not a valid device. Note, this condition is quite often
192 * satisfied when enumerating devices or finding a parent device.
193 * Hence, use log_trace_errno() here. */
194 return log_trace_errno(SYNTHETIC_ERRNO(ENODEV),
195 "sd-device: the uevent file \"%s/uevent\" does not exist.", syspath);
196 if (errno == ENOTDIR)
197 /* Not actually a directory. */
198 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
199 "sd-device: the syspath \"%s\" is not a directory.", syspath);
200
201 return log_debug_errno(errno, "sd-device: cannot find uevent file for %s: %m", syspath);
202 }
203 } else {
204 struct stat st;
205
206 /* For everything else lax rules apply: they just need to be a directory */
207
208 if (fstat(fd, &st) < 0)
209 return log_debug_errno(errno, "sd-device: failed to check if syspath \"%s\" is a directory: %m", syspath);
210 if (!S_ISDIR(st.st_mode))
211 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
212 "sd-device: the syspath \"%s\" is not a directory.", syspath);
213 }
214
215 /* Only operate on sysfs, i.e. refuse going down into /sys/fs/cgroup/ or similar places where
216 * things are not arranged as kobjects in kernel, and hence don't necessarily have
217 * kobject/attribute structure. */
218 r = getenv_bool_secure("SYSTEMD_DEVICE_VERIFY_SYSFS");
219 if (r < 0 && r != -ENXIO)
220 log_debug_errno(r, "Failed to parse $SYSTEMD_DEVICE_VERIFY_SYSFS value: %m");
221 if (r != 0) {
222 r = fd_is_fs_type(fd, SYSFS_MAGIC);
223 if (r < 0)
224 return log_debug_errno(r, "sd-device: failed to check if syspath \"%s\" is backed by sysfs.", syspath);
225 if (r == 0)
226 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV),
227 "sd-device: the syspath \"%s\" is outside of sysfs, refusing.", syspath);
228 }
229 } else {
230 /* must be a subdirectory of /sys */
231 if (!path_startswith(_syspath, "/sys/"))
232 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
233 "sd-device: Syspath '%s' is not a subdirectory of /sys",
234 _syspath);
235
236 syspath = strdup(_syspath);
237 if (!syspath)
238 return log_oom_debug();
239
240 path_simplify(syspath);
241 }
242
243 assert_se(devpath = startswith(syspath, "/sys"));
244 if (devpath[0] != '/')
245 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "sd-device: \"/sys\" alone is not a valid device path.");
246
247 r = device_add_property_internal(device, "DEVPATH", devpath);
248 if (r < 0)
249 return log_debug_errno(r, "sd-device: Failed to add \"DEVPATH\" property for device \"%s\": %m", syspath);
250
251 free_and_replace(device->syspath, syspath);
252 device->devpath = devpath;
253 return 0;
254 }
255
256 static int device_new_from_syspath(sd_device **ret, const char *syspath, bool strict) {
257 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
258 int r;
259
260 assert_return(ret, -EINVAL);
261 assert_return(syspath, -EINVAL);
262
263 if (strict && !path_startswith(syspath, "/sys/"))
264 return -EINVAL;
265
266 r = device_new_aux(&device);
267 if (r < 0)
268 return r;
269
270 r = device_set_syspath(device, syspath, /* verify= */ true);
271 if (r < 0)
272 return r;
273
274 *ret = TAKE_PTR(device);
275 return 0;
276 }
277
278 _public_ int sd_device_new_from_syspath(sd_device **ret, const char *syspath) {
279 return device_new_from_syspath(ret, syspath, /* strict = */ true);
280 }
281
282 static int device_new_from_mode_and_devnum(sd_device **ret, mode_t mode, dev_t devnum) {
283 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
284 _cleanup_free_ char *syspath = NULL;
285 const char *t, *subsystem;
286 dev_t n;
287 int r;
288
289 assert(ret);
290
291 if (S_ISCHR(mode))
292 t = "char";
293 else if (S_ISBLK(mode))
294 t = "block";
295 else
296 return -ENOTTY;
297
298 if (major(devnum) == 0)
299 return -ENODEV;
300
301 if (asprintf(&syspath, "/sys/dev/%s/%u:%u", t, major(devnum), minor(devnum)) < 0)
302 return -ENOMEM;
303
304 r = sd_device_new_from_syspath(&dev, syspath);
305 if (r < 0)
306 return r;
307
308 r = sd_device_get_devnum(dev, &n);
309 if (r == -ENOENT)
310 return -ENXIO;
311 if (r < 0)
312 return r;
313 if (n != devnum)
314 return -ENXIO;
315
316 r = sd_device_get_subsystem(dev, &subsystem);
317 if (r < 0 && r != -ENOENT)
318 return r;
319 if (r >= 0 && streq(subsystem, "block") != !!S_ISBLK(mode))
320 return -ENXIO;
321
322 *ret = TAKE_PTR(dev);
323 return 0;
324 }
325
326 _public_ int sd_device_new_from_devnum(sd_device **ret, char type, dev_t devnum) {
327 assert_return(ret, -EINVAL);
328 assert_return(IN_SET(type, 'b', 'c'), -EINVAL);
329
330 return device_new_from_mode_and_devnum(ret, type == 'b' ? S_IFBLK : S_IFCHR, devnum);
331 }
332
333 static int device_new_from_main_ifname(sd_device **ret, const char *ifname) {
334 const char *syspath;
335
336 assert(ret);
337 assert(ifname);
338
339 syspath = strjoina("/sys/class/net/", ifname);
340 return sd_device_new_from_syspath(ret, syspath);
341 }
342
343 _public_ int sd_device_new_from_ifname(sd_device **ret, const char *ifname) {
344 _cleanup_free_ char *main_name = NULL;
345 int r;
346
347 assert_return(ret, -EINVAL);
348 assert_return(ifname, -EINVAL);
349
350 r = parse_ifindex(ifname);
351 if (r > 0)
352 return sd_device_new_from_ifindex(ret, r);
353
354 if (ifname_valid(ifname)) {
355 r = device_new_from_main_ifname(ret, ifname);
356 if (r >= 0)
357 return r;
358 }
359
360 r = rtnl_resolve_link_alternative_name(NULL, ifname, &main_name);
361 if (r < 0)
362 return r;
363
364 return device_new_from_main_ifname(ret, main_name);
365 }
366
367 _public_ int sd_device_new_from_ifindex(sd_device **ret, int ifindex) {
368 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
369 char ifname[IF_NAMESIZE];
370 int r, i;
371
372 assert_return(ret, -EINVAL);
373 assert_return(ifindex > 0, -EINVAL);
374
375 if (format_ifname(ifindex, ifname) < 0)
376 return -ENODEV;
377
378 r = device_new_from_main_ifname(&dev, ifname);
379 if (r < 0)
380 return r;
381
382 r = sd_device_get_ifindex(dev, &i);
383 if (r == -ENOENT)
384 return -ENXIO;
385 if (r < 0)
386 return r;
387 if (i != ifindex)
388 return -ENXIO;
389
390 *ret = TAKE_PTR(dev);
391 return 0;
392 }
393
394 static int device_strjoin_new(
395 const char *a,
396 const char *b,
397 const char *c,
398 const char *d,
399 sd_device **ret) {
400
401 const char *p;
402 int r;
403
404 p = strjoina(a, b, c, d);
405 if (access(p, F_OK) < 0)
406 return IN_SET(errno, ENOENT, ENAMETOOLONG) ? 0 : -errno; /* If this sysfs is too long then it doesn't exist either */
407
408 r = sd_device_new_from_syspath(ret, p);
409 if (r < 0)
410 return r;
411
412 return 1;
413 }
414
415 _public_ int sd_device_new_from_subsystem_sysname(
416 sd_device **ret,
417 const char *subsystem,
418 const char *sysname) {
419
420 char *name;
421 int r;
422
423 assert_return(ret, -EINVAL);
424 assert_return(path_is_normalized(subsystem), -EINVAL);
425 assert_return(path_is_normalized(sysname), -EINVAL);
426
427 /* translate sysname back to sysfs filename */
428 name = strdupa_safe(sysname);
429 string_replace_char(name, '/', '!');
430
431 if (streq(subsystem, "subsystem")) {
432 FOREACH_STRING(s, "/sys/bus/", "/sys/class/") {
433 r = device_strjoin_new(s, name, NULL, NULL, ret);
434 if (r < 0)
435 return r;
436 if (r > 0)
437 return 0;
438 }
439
440 } else if (streq(subsystem, "module")) {
441 r = device_strjoin_new("/sys/module/", name, NULL, NULL, ret);
442 if (r < 0)
443 return r;
444 if (r > 0)
445 return 0;
446
447 } else if (streq(subsystem, "drivers")) {
448 const char *sep;
449
450 sep = strchr(name, ':');
451 if (sep && sep[1] != '\0') { /* Require ":" and something non-empty after that. */
452
453 const char *subsys = memdupa_suffix0(name, sep - name);
454 sep++;
455
456 if (streq(sep, "drivers")) /* If the sysname is "drivers", then it's the drivers directory itself that is meant. */
457 r = device_strjoin_new("/sys/bus/", subsys, "/drivers", NULL, ret);
458 else
459 r = device_strjoin_new("/sys/bus/", subsys, "/drivers/", sep, ret);
460 if (r < 0)
461 return r;
462 if (r > 0)
463 return 0;
464 }
465 }
466
467 r = device_strjoin_new("/sys/bus/", subsystem, "/devices/", name, ret);
468 if (r < 0)
469 return r;
470 if (r > 0)
471 return 0;
472
473 r = device_strjoin_new("/sys/class/", subsystem, "/", name, ret);
474 if (r < 0)
475 return r;
476 if (r > 0)
477 return 0;
478
479 r = device_strjoin_new("/sys/firmware/", subsystem, "/", name, ret);
480 if (r < 0)
481 return r;
482 if (r > 0)
483 return 0;
484
485 return -ENODEV;
486 }
487
488 _public_ int sd_device_new_from_stat_rdev(sd_device **ret, const struct stat *st) {
489 assert_return(ret, -EINVAL);
490 assert_return(st, -EINVAL);
491
492 return device_new_from_mode_and_devnum(ret, st->st_mode, st->st_rdev);
493 }
494
495 _public_ int sd_device_new_from_devname(sd_device **ret, const char *devname) {
496 struct stat st;
497 dev_t devnum;
498 mode_t mode;
499
500 assert_return(ret, -EINVAL);
501 assert_return(devname, -EINVAL);
502
503 /* This function actually accepts both devlinks and devnames, i.e. both symlinks and device
504 * nodes below /dev/. */
505
506 /* Also ignore when the specified path is "/dev". */
507 if (isempty(path_startswith(devname, "/dev")))
508 return -EINVAL;
509
510 if (device_path_parse_major_minor(devname, &mode, &devnum) >= 0)
511 /* Let's shortcut when "/dev/block/maj:min" or "/dev/char/maj:min" is specified.
512 * In that case, we can directly convert the path to syspath, hence it is not necessary
513 * that the specified path exists. So, this works fine without udevd being running. */
514 return device_new_from_mode_and_devnum(ret, mode, devnum);
515
516 if (stat(devname, &st) < 0)
517 return ERRNO_IS_DEVICE_ABSENT(errno) ? -ENODEV : -errno;
518
519 return sd_device_new_from_stat_rdev(ret, &st);
520 }
521
522 _public_ int sd_device_new_from_path(sd_device **ret, const char *path) {
523 assert_return(ret, -EINVAL);
524 assert_return(path, -EINVAL);
525
526 if (path_startswith(path, "/dev"))
527 return sd_device_new_from_devname(ret, path);
528
529 return device_new_from_syspath(ret, path, /* strict = */ false);
530 }
531
532 int device_set_devtype(sd_device *device, const char *devtype) {
533 _cleanup_free_ char *t = NULL;
534 int r;
535
536 assert(device);
537 assert(devtype);
538
539 t = strdup(devtype);
540 if (!t)
541 return -ENOMEM;
542
543 r = device_add_property_internal(device, "DEVTYPE", t);
544 if (r < 0)
545 return r;
546
547 return free_and_replace(device->devtype, t);
548 }
549
550 int device_set_ifindex(sd_device *device, const char *name) {
551 int r, ifindex;
552
553 assert(device);
554 assert(name);
555
556 ifindex = parse_ifindex(name);
557 if (ifindex < 0)
558 return ifindex;
559
560 r = device_add_property_internal(device, "IFINDEX", name);
561 if (r < 0)
562 return r;
563
564 device->ifindex = ifindex;
565
566 return 0;
567 }
568
569 int device_set_devname(sd_device *device, const char *devname) {
570 _cleanup_free_ char *t = NULL;
571 int r;
572
573 assert(device);
574 assert(devname);
575
576 if (devname[0] != '/')
577 t = strjoin("/dev/", devname);
578 else
579 t = strdup(devname);
580 if (!t)
581 return -ENOMEM;
582
583 r = device_add_property_internal(device, "DEVNAME", t);
584 if (r < 0)
585 return r;
586
587 return free_and_replace(device->devname, t);
588 }
589
590 int device_set_devmode(sd_device *device, const char *_devmode) {
591 unsigned devmode;
592 int r;
593
594 assert(device);
595 assert(_devmode);
596
597 r = safe_atou(_devmode, &devmode);
598 if (r < 0)
599 return r;
600
601 if (devmode > 07777)
602 return -EINVAL;
603
604 r = device_add_property_internal(device, "DEVMODE", _devmode);
605 if (r < 0)
606 return r;
607
608 device->devmode = devmode;
609
610 return 0;
611 }
612
613 int device_set_devnum(sd_device *device, const char *major, const char *minor) {
614 unsigned maj, min = 0;
615 int r;
616
617 assert(device);
618 assert(major);
619
620 r = safe_atou(major, &maj);
621 if (r < 0)
622 return r;
623 if (maj == 0)
624 return 0;
625 if (!DEVICE_MAJOR_VALID(maj))
626 return -EINVAL;
627
628 if (minor) {
629 r = safe_atou(minor, &min);
630 if (r < 0)
631 return r;
632 if (!DEVICE_MINOR_VALID(min))
633 return -EINVAL;
634 }
635
636 r = device_add_property_internal(device, "MAJOR", major);
637 if (r < 0)
638 return r;
639
640 if (minor) {
641 r = device_add_property_internal(device, "MINOR", minor);
642 if (r < 0)
643 return r;
644 }
645
646 device->devnum = makedev(maj, min);
647
648 return 0;
649 }
650
651 int device_set_diskseq(sd_device *device, const char *str) {
652 uint64_t diskseq;
653 int r;
654
655 assert(device);
656 assert(str);
657
658 r = safe_atou64(str, &diskseq);
659 if (r < 0)
660 return r;
661 if (diskseq == 0)
662 return -EINVAL;
663
664 r = device_add_property_internal(device, "DISKSEQ", str);
665 if (r < 0)
666 return r;
667
668 device->diskseq = diskseq;
669
670 return 0;
671 }
672
673 static int handle_uevent_line(
674 sd_device *device,
675 const char *key,
676 const char *value,
677 const char **major,
678 const char **minor) {
679
680 assert(device);
681 assert(key);
682 assert(value);
683 assert(major);
684 assert(minor);
685
686 if (streq(key, "DEVTYPE"))
687 return device_set_devtype(device, value);
688 if (streq(key, "IFINDEX"))
689 return device_set_ifindex(device, value);
690 if (streq(key, "DEVNAME"))
691 return device_set_devname(device, value);
692 if (streq(key, "DEVMODE"))
693 return device_set_devmode(device, value);
694 if (streq(key, "DISKSEQ"))
695 return device_set_diskseq(device, value);
696 if (streq(key, "MAJOR"))
697 *major = value;
698 else if (streq(key, "MINOR"))
699 *minor = value;
700 else
701 return device_add_property_internal(device, key, value);
702
703 return 0;
704 }
705
706 int device_read_uevent_file(sd_device *device) {
707 _cleanup_free_ char *uevent = NULL;
708 const char *syspath, *key = NULL, *value = NULL, *major = NULL, *minor = NULL;
709 char *path;
710 size_t uevent_len;
711 int r;
712
713 enum {
714 PRE_KEY,
715 KEY,
716 PRE_VALUE,
717 VALUE,
718 INVALID_LINE,
719 } state = PRE_KEY;
720
721 assert(device);
722
723 if (device->uevent_loaded || device->sealed)
724 return 0;
725
726 r = sd_device_get_syspath(device, &syspath);
727 if (r < 0)
728 return r;
729
730 device->uevent_loaded = true;
731
732 path = strjoina(syspath, "/uevent");
733
734 r = read_full_virtual_file(path, &uevent, &uevent_len);
735 if (r < 0) {
736 /* The uevent files may be write-only, the device may be already removed, or the device
737 * may not have the uevent file. */
738 if (r == -EACCES || ERRNO_IS_DEVICE_ABSENT(r))
739 return 0;
740
741 return log_device_debug_errno(device, r, "sd-device: Failed to read uevent file '%s': %m", path);
742 }
743
744 for (size_t i = 0; i < uevent_len; i++)
745 switch (state) {
746 case PRE_KEY:
747 if (!strchr(NEWLINE, uevent[i])) {
748 key = &uevent[i];
749
750 state = KEY;
751 }
752
753 break;
754 case KEY:
755 if (uevent[i] == '=') {
756 uevent[i] = '\0';
757
758 state = PRE_VALUE;
759 } else if (strchr(NEWLINE, uevent[i])) {
760 uevent[i] = '\0';
761 log_device_debug(device, "sd-device: Invalid uevent line '%s', ignoring", key);
762
763 state = PRE_KEY;
764 }
765
766 break;
767 case PRE_VALUE:
768 value = &uevent[i];
769 state = VALUE;
770
771 _fallthrough_; /* to handle empty property */
772 case VALUE:
773 if (strchr(NEWLINE, uevent[i])) {
774 uevent[i] = '\0';
775
776 r = handle_uevent_line(device, key, value, &major, &minor);
777 if (r < 0)
778 log_device_debug_errno(device, r, "sd-device: Failed to handle uevent entry '%s=%s', ignoring: %m", key, value);
779
780 state = PRE_KEY;
781 }
782
783 break;
784 default:
785 assert_not_reached();
786 }
787
788 if (major) {
789 r = device_set_devnum(device, major, minor);
790 if (r < 0)
791 log_device_debug_errno(device, r, "sd-device: Failed to set 'MAJOR=%s' or 'MINOR=%s' from '%s', ignoring: %m", major, strna(minor), path);
792 }
793
794 return 0;
795 }
796
797 _public_ int sd_device_get_ifindex(sd_device *device, int *ifindex) {
798 int r;
799
800 assert_return(device, -EINVAL);
801
802 r = device_read_uevent_file(device);
803 if (r < 0)
804 return r;
805
806 if (device->ifindex <= 0)
807 return -ENOENT;
808
809 if (ifindex)
810 *ifindex = device->ifindex;
811
812 return 0;
813 }
814
815 _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
816 int r;
817
818 assert_return(ret, -EINVAL);
819 assert_return(id, -EINVAL);
820
821 switch (id[0]) {
822 case 'b':
823 case 'c': {
824 dev_t devt;
825
826 if (isempty(id))
827 return -EINVAL;
828
829 r = parse_devnum(id + 1, &devt);
830 if (r < 0)
831 return r;
832
833 return sd_device_new_from_devnum(ret, id[0], devt);
834 }
835
836 case 'n': {
837 int ifindex;
838
839 ifindex = parse_ifindex(id + 1);
840 if (ifindex < 0)
841 return ifindex;
842
843 return sd_device_new_from_ifindex(ret, ifindex);
844 }
845
846 case '+': {
847 const char *subsys, *sep;
848
849 sep = strchr(id + 1, ':');
850 if (!sep || sep - id - 1 > NAME_MAX)
851 return -EINVAL;
852
853 subsys = memdupa_suffix0(id + 1, sep - id - 1);
854
855 return sd_device_new_from_subsystem_sysname(ret, subsys, sep + 1);
856 }
857
858 default:
859 return -EINVAL;
860 }
861 }
862
863 _public_ int sd_device_get_syspath(sd_device *device, const char **ret) {
864 assert_return(device, -EINVAL);
865
866 assert(path_startswith(device->syspath, "/sys/"));
867
868 if (ret)
869 *ret = device->syspath;
870
871 return 0;
872 }
873
874 _public_ int sd_device_new_child(sd_device **ret, sd_device *device, const char *suffix) {
875 _cleanup_free_ char *path = NULL;
876 const char *s;
877 int r;
878
879 assert_return(ret, -EINVAL);
880 assert_return(device, -EINVAL);
881 assert_return(suffix, -EINVAL);
882
883 if (!path_is_normalized(suffix))
884 return -EINVAL;
885
886 r = sd_device_get_syspath(device, &s);
887 if (r < 0)
888 return r;
889
890 path = path_join(s, suffix);
891 if (!path)
892 return -ENOMEM;
893
894 return sd_device_new_from_syspath(ret, path);
895 }
896
897 static int device_new_from_child(sd_device **ret, sd_device *child) {
898 _cleanup_free_ char *path = NULL;
899 const char *syspath;
900 int r;
901
902 assert(ret);
903 assert(child);
904
905 r = sd_device_get_syspath(child, &syspath);
906 if (r < 0)
907 return r;
908
909 for (;;) {
910 _cleanup_free_ char *p = NULL;
911
912 r = path_extract_directory(path ?: syspath, &p);
913 if (r < 0)
914 return r;
915
916 if (path_equal(p, "/sys"))
917 return -ENODEV;
918
919 r = sd_device_new_from_syspath(ret, p);
920 if (r != -ENODEV)
921 return r;
922
923 free_and_replace(path, p);
924 }
925 }
926
927 _public_ int sd_device_get_parent(sd_device *child, sd_device **ret) {
928 int r;
929
930 assert_return(child, -EINVAL);
931
932 if (!child->parent_set) {
933 r = device_new_from_child(&child->parent, child);
934 if (r < 0 && r != -ENODEV)
935 return r;
936
937 child->parent_set = true;
938 }
939
940 if (!child->parent)
941 return -ENOENT;
942
943 if (ret)
944 *ret = child->parent;
945 return 0;
946 }
947
948 int device_set_subsystem(sd_device *device, const char *subsystem) {
949 _cleanup_free_ char *s = NULL;
950 int r;
951
952 assert(device);
953
954 if (subsystem) {
955 s = strdup(subsystem);
956 if (!s)
957 return -ENOMEM;
958 }
959
960 r = device_add_property_internal(device, "SUBSYSTEM", s);
961 if (r < 0)
962 return r;
963
964 device->subsystem_set = true;
965 return free_and_replace(device->subsystem, s);
966 }
967
968 int device_set_drivers_subsystem(sd_device *device) {
969 _cleanup_free_ char *subsystem = NULL;
970 const char *devpath, *drivers, *p;
971 int r;
972
973 assert(device);
974
975 r = sd_device_get_devpath(device, &devpath);
976 if (r < 0)
977 return r;
978
979 drivers = strstr(devpath, "/drivers/");
980 if (!drivers)
981 drivers = endswith(devpath, "/drivers");
982 if (!drivers)
983 return -EINVAL;
984
985 /* Find the path component immediately before the "/drivers/" string */
986 r = path_find_last_component(devpath, /* accept_dot_dot= */ false, &drivers, &p);
987 if (r < 0)
988 return r;
989 if (r == 0)
990 return -EINVAL;
991
992 subsystem = strndup(p, r);
993 if (!subsystem)
994 return -ENOMEM;
995
996 r = device_set_subsystem(device, "drivers");
997 if (r < 0)
998 return r;
999
1000 return free_and_replace(device->driver_subsystem, subsystem);
1001 }
1002
1003 _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) {
1004 int r;
1005
1006 assert_return(device, -EINVAL);
1007
1008 if (!device->subsystem_set) {
1009 _cleanup_free_ char *subsystem = NULL;
1010 const char *syspath;
1011 char *path;
1012
1013 r = sd_device_get_syspath(device, &syspath);
1014 if (r < 0)
1015 return r;
1016
1017 /* read 'subsystem' link */
1018 path = strjoina(syspath, "/subsystem");
1019 r = readlink_value(path, &subsystem);
1020 if (r < 0 && r != -ENOENT)
1021 return log_device_debug_errno(device, r,
1022 "sd-device: Failed to read subsystem for %s: %m",
1023 device->devpath);
1024
1025 if (subsystem)
1026 r = device_set_subsystem(device, subsystem);
1027 /* use implicit names */
1028 else if (!isempty(path_startswith(device->devpath, "/module/")))
1029 r = device_set_subsystem(device, "module");
1030 else if (strstr(syspath, "/drivers/") || endswith(syspath, "/drivers"))
1031 r = device_set_drivers_subsystem(device);
1032 else if (!isempty(PATH_STARTSWITH_SET(device->devpath, "/class/", "/bus/")))
1033 r = device_set_subsystem(device, "subsystem");
1034 else {
1035 device->subsystem_set = true;
1036 r = 0;
1037 }
1038 if (r < 0)
1039 return log_device_debug_errno(device, r,
1040 "sd-device: Failed to set subsystem for %s: %m",
1041 device->devpath);
1042 }
1043
1044 if (!device->subsystem)
1045 return -ENOENT;
1046
1047 if (ret)
1048 *ret = device->subsystem;
1049 return 0;
1050 }
1051
1052 _public_ int sd_device_get_devtype(sd_device *device, const char **devtype) {
1053 int r;
1054
1055 assert_return(device, -EINVAL);
1056
1057 r = device_read_uevent_file(device);
1058 if (r < 0)
1059 return r;
1060
1061 if (!device->devtype)
1062 return -ENOENT;
1063
1064 if (devtype)
1065 *devtype = device->devtype;
1066
1067 return !!device->devtype;
1068 }
1069
1070 _public_ int sd_device_get_parent_with_subsystem_devtype(sd_device *child, const char *subsystem, const char *devtype, sd_device **ret) {
1071 sd_device *parent = NULL;
1072 int r;
1073
1074 assert_return(child, -EINVAL);
1075 assert_return(subsystem, -EINVAL);
1076
1077 r = sd_device_get_parent(child, &parent);
1078 while (r >= 0) {
1079 const char *parent_subsystem = NULL;
1080
1081 (void) sd_device_get_subsystem(parent, &parent_subsystem);
1082 if (streq_ptr(parent_subsystem, subsystem)) {
1083 const char *parent_devtype = NULL;
1084
1085 if (!devtype)
1086 break;
1087
1088 (void) sd_device_get_devtype(parent, &parent_devtype);
1089 if (streq_ptr(parent_devtype, devtype))
1090 break;
1091 }
1092 r = sd_device_get_parent(parent, &parent);
1093 }
1094
1095 if (r < 0)
1096 return r;
1097
1098 if (ret)
1099 *ret = parent;
1100 return 0;
1101 }
1102
1103 _public_ int sd_device_get_devnum(sd_device *device, dev_t *devnum) {
1104 int r;
1105
1106 assert_return(device, -EINVAL);
1107
1108 r = device_read_uevent_file(device);
1109 if (r < 0)
1110 return r;
1111
1112 if (major(device->devnum) <= 0)
1113 return -ENOENT;
1114
1115 if (devnum)
1116 *devnum = device->devnum;
1117
1118 return 0;
1119 }
1120
1121 int device_set_driver(sd_device *device, const char *driver) {
1122 _cleanup_free_ char *d = NULL;
1123 int r;
1124
1125 assert(device);
1126
1127 if (driver) {
1128 d = strdup(driver);
1129 if (!d)
1130 return -ENOMEM;
1131 }
1132
1133 r = device_add_property_internal(device, "DRIVER", d);
1134 if (r < 0)
1135 return r;
1136
1137 device->driver_set = true;
1138 return free_and_replace(device->driver, d);
1139 }
1140
1141 _public_ int sd_device_get_driver(sd_device *device, const char **ret) {
1142 assert_return(device, -EINVAL);
1143
1144 if (!device->driver_set) {
1145 _cleanup_free_ char *driver = NULL;
1146 const char *syspath;
1147 char *path;
1148 int r;
1149
1150 r = sd_device_get_syspath(device, &syspath);
1151 if (r < 0)
1152 return r;
1153
1154 path = strjoina(syspath, "/driver");
1155 r = readlink_value(path, &driver);
1156 if (r < 0 && r != -ENOENT)
1157 return log_device_debug_errno(device, r,
1158 "sd-device: readlink(\"%s\") failed: %m", path);
1159
1160 r = device_set_driver(device, driver);
1161 if (r < 0)
1162 return log_device_debug_errno(device, r,
1163 "sd-device: Failed to set driver \"%s\": %m", driver);
1164 }
1165
1166 if (!device->driver)
1167 return -ENOENT;
1168
1169 if (ret)
1170 *ret = device->driver;
1171 return 0;
1172 }
1173
1174 _public_ int sd_device_get_devpath(sd_device *device, const char **ret) {
1175 assert_return(device, -EINVAL);
1176
1177 assert(device->devpath);
1178 assert(device->devpath[0] == '/');
1179
1180 if (ret)
1181 *ret = device->devpath;
1182
1183 return 0;
1184 }
1185
1186 _public_ int sd_device_get_devname(sd_device *device, const char **devname) {
1187 int r;
1188
1189 assert_return(device, -EINVAL);
1190
1191 r = device_read_uevent_file(device);
1192 if (r < 0)
1193 return r;
1194
1195 if (!device->devname)
1196 return -ENOENT;
1197
1198 assert(path_startswith(device->devname, "/dev/"));
1199
1200 if (devname)
1201 *devname = device->devname;
1202 return 0;
1203 }
1204
1205 static int device_set_sysname_and_sysnum(sd_device *device) {
1206 _cleanup_free_ char *sysname = NULL;
1207 size_t len, n;
1208 int r;
1209
1210 assert(device);
1211
1212 r = path_extract_filename(device->devpath, &sysname);
1213 if (r < 0)
1214 return r;
1215 if (r == O_DIRECTORY)
1216 return -EINVAL;
1217
1218 /* some devices have '!' in their name, change that to '/' */
1219 string_replace_char(sysname, '!', '/');
1220
1221 n = strspn_from_end(sysname, DIGITS);
1222 len = strlen(sysname);
1223 assert(n <= len);
1224 if (n == len)
1225 n = 0; /* Do not set sysnum for number only sysname. */
1226
1227 device->sysnum = n > 0 ? sysname + len - n : NULL;
1228 return free_and_replace(device->sysname, sysname);
1229 }
1230
1231 _public_ int sd_device_get_sysname(sd_device *device, const char **ret) {
1232 int r;
1233
1234 assert_return(device, -EINVAL);
1235
1236 if (!device->sysname) {
1237 r = device_set_sysname_and_sysnum(device);
1238 if (r < 0)
1239 return r;
1240 }
1241
1242 if (ret)
1243 *ret = device->sysname;
1244 return 0;
1245 }
1246
1247 _public_ int sd_device_get_sysnum(sd_device *device, const char **ret) {
1248 int r;
1249
1250 assert_return(device, -EINVAL);
1251
1252 if (!device->sysname) {
1253 r = device_set_sysname_and_sysnum(device);
1254 if (r < 0)
1255 return r;
1256 }
1257
1258 if (!device->sysnum)
1259 return -ENOENT;
1260
1261 if (ret)
1262 *ret = device->sysnum;
1263 return 0;
1264 }
1265
1266 _public_ int sd_device_get_action(sd_device *device, sd_device_action_t *ret) {
1267 assert_return(device, -EINVAL);
1268
1269 if (device->action < 0)
1270 return -ENOENT;
1271
1272 if (ret)
1273 *ret = device->action;
1274
1275 return 0;
1276 }
1277
1278 _public_ int sd_device_get_seqnum(sd_device *device, uint64_t *ret) {
1279 assert_return(device, -EINVAL);
1280
1281 if (device->seqnum == 0)
1282 return -ENOENT;
1283
1284 if (ret)
1285 *ret = device->seqnum;
1286
1287 return 0;
1288 }
1289
1290 _public_ int sd_device_get_diskseq(sd_device *device, uint64_t *ret) {
1291 int r;
1292
1293 assert_return(device, -EINVAL);
1294
1295 r = device_read_uevent_file(device);
1296 if (r < 0)
1297 return r;
1298
1299 if (device->diskseq == 0)
1300 return -ENOENT;
1301
1302 if (ret)
1303 *ret = device->diskseq;
1304
1305 return 0;
1306 }
1307
1308 static bool is_valid_tag(const char *tag) {
1309 assert(tag);
1310
1311 return !strchr(tag, ':') && !strchr(tag, ' ');
1312 }
1313
1314 int device_add_tag(sd_device *device, const char *tag, bool both) {
1315 int r, added;
1316
1317 assert(device);
1318 assert(tag);
1319
1320 if (!is_valid_tag(tag))
1321 return -EINVAL;
1322
1323 /* Definitely add to the "all" list of tags (i.e. the sticky list) */
1324 added = set_put_strdup(&device->all_tags, tag);
1325 if (added < 0)
1326 return added;
1327
1328 /* And optionally, also add it to the current list of tags */
1329 if (both) {
1330 r = set_put_strdup(&device->current_tags, tag);
1331 if (r < 0) {
1332 if (added > 0)
1333 (void) set_remove(device->all_tags, tag);
1334
1335 return r;
1336 }
1337 }
1338
1339 device->tags_generation++;
1340 device->property_tags_outdated = true;
1341
1342 return 0;
1343 }
1344
1345 int device_add_devlink(sd_device *device, const char *devlink) {
1346 int r;
1347
1348 assert(device);
1349 assert(devlink);
1350
1351 r = set_put_strdup(&device->devlinks, devlink);
1352 if (r < 0)
1353 return r;
1354
1355 device->devlinks_generation++;
1356 device->property_devlinks_outdated = true;
1357
1358 return 0;
1359 }
1360
1361 bool device_has_devlink(sd_device *device, const char *devlink) {
1362 assert(device);
1363 assert(devlink);
1364
1365 return set_contains(device->devlinks, devlink);
1366 }
1367
1368 static int device_add_property_internal_from_string(sd_device *device, const char *str) {
1369 _cleanup_free_ char *key = NULL;
1370 char *value;
1371 int r;
1372
1373 assert(device);
1374 assert(str);
1375
1376 key = strdup(str);
1377 if (!key)
1378 return -ENOMEM;
1379
1380 value = strchr(key, '=');
1381 if (!value)
1382 return -EINVAL;
1383
1384 *value = '\0';
1385
1386 if (isempty(++value))
1387 value = NULL;
1388
1389 /* Add the property to both sd_device::properties and sd_device::properties_db,
1390 * as this is called by only handle_db_line(). */
1391 r = device_add_property_aux(device, key, value, false);
1392 if (r < 0)
1393 return r;
1394
1395 return device_add_property_aux(device, key, value, true);
1396 }
1397
1398 int device_set_usec_initialized(sd_device *device, usec_t when) {
1399 char s[DECIMAL_STR_MAX(usec_t)];
1400 int r;
1401
1402 assert(device);
1403
1404 xsprintf(s, USEC_FMT, when);
1405
1406 r = device_add_property_internal(device, "USEC_INITIALIZED", s);
1407 if (r < 0)
1408 return r;
1409
1410 device->usec_initialized = when;
1411 return 0;
1412 }
1413
1414 static int handle_db_line(sd_device *device, char key, const char *value) {
1415 int r;
1416
1417 assert(device);
1418 assert(value);
1419
1420 switch (key) {
1421 case 'G': /* Any tag */
1422 case 'Q': /* Current tag */
1423 return device_add_tag(device, value, key == 'Q');
1424
1425 case 'S': {
1426 const char *path;
1427
1428 path = strjoina("/dev/", value);
1429 return device_add_devlink(device, path);
1430 }
1431 case 'E':
1432 return device_add_property_internal_from_string(device, value);
1433
1434 case 'I': {
1435 usec_t t;
1436
1437 r = safe_atou64(value, &t);
1438 if (r < 0)
1439 return r;
1440
1441 return device_set_usec_initialized(device, t);
1442 }
1443 case 'L':
1444 return safe_atoi(value, &device->devlink_priority);
1445
1446 case 'W':
1447 /* Deprecated. Previously, watch handle is both saved in database and /run/udev/watch.
1448 * However, the handle saved in database may not be updated when the handle is updated
1449 * or removed. Moreover, it is not necessary to store the handle within the database,
1450 * as its value becomes meaningless when udevd is restarted. */
1451 return 0;
1452
1453 case 'V':
1454 return safe_atou(value, &device->database_version);
1455
1456 default:
1457 log_device_debug(device, "sd-device: Unknown key '%c' in device db, ignoring", key);
1458 return 0;
1459 }
1460 }
1461
1462 int device_get_device_id(sd_device *device, const char **ret) {
1463 assert(device);
1464 assert(ret);
1465
1466 if (!device->device_id) {
1467 _cleanup_free_ char *id = NULL;
1468 const char *subsystem;
1469 dev_t devnum;
1470 int ifindex, r;
1471
1472 r = sd_device_get_subsystem(device, &subsystem);
1473 if (r < 0)
1474 return r;
1475
1476 if (sd_device_get_devnum(device, &devnum) >= 0) {
1477 /* use dev_t — b259:131072, c254:0 */
1478 if (asprintf(&id, "%c%u:%u",
1479 streq(subsystem, "block") ? 'b' : 'c',
1480 major(devnum), minor(devnum)) < 0)
1481 return -ENOMEM;
1482 } else if (sd_device_get_ifindex(device, &ifindex) >= 0) {
1483 /* use netdev ifindex — n3 */
1484 if (asprintf(&id, "n%u", (unsigned) ifindex) < 0)
1485 return -ENOMEM;
1486 } else {
1487 _cleanup_free_ char *sysname = NULL;
1488
1489 /* use $subsys:$sysname — pci:0000:00:1f.2
1490 * sd_device_get_sysname() has '!' translated, get it from devpath */
1491 r = path_extract_filename(device->devpath, &sysname);
1492 if (r < 0)
1493 return r;
1494 if (r == O_DIRECTORY)
1495 return -EINVAL;
1496
1497 if (streq(subsystem, "drivers")) {
1498 /* the 'drivers' pseudo-subsystem is special, and needs the real
1499 * subsystem encoded as well */
1500 assert(device->driver_subsystem);
1501 id = strjoin("+drivers:", device->driver_subsystem, ":", sysname);
1502 } else
1503 id = strjoin("+", subsystem, ":", sysname);
1504 if (!id)
1505 return -ENOMEM;
1506 }
1507
1508 if (!filename_is_valid(id))
1509 return -EINVAL;
1510
1511 device->device_id = TAKE_PTR(id);
1512 }
1513
1514 *ret = device->device_id;
1515 return 0;
1516 }
1517
1518 int device_read_db_internal_filename(sd_device *device, const char *filename) {
1519 _cleanup_free_ char *db = NULL;
1520 const char *value;
1521 size_t db_len;
1522 char key = '\0'; /* Unnecessary initialization to appease gcc-12.0.0-0.4.fc36 */
1523 int r;
1524
1525 enum {
1526 PRE_KEY,
1527 KEY,
1528 PRE_VALUE,
1529 VALUE,
1530 INVALID_LINE,
1531 } state = PRE_KEY;
1532
1533 assert(device);
1534 assert(filename);
1535
1536 r = read_full_file(filename, &db, &db_len);
1537 if (r < 0) {
1538 if (r == -ENOENT)
1539 return 0;
1540
1541 return log_device_debug_errno(device, r, "sd-device: Failed to read db '%s': %m", filename);
1542 }
1543
1544 /* devices with a database entry are initialized */
1545 device->is_initialized = true;
1546
1547 device->db_loaded = true;
1548
1549 for (size_t i = 0; i < db_len; i++)
1550 switch (state) {
1551 case PRE_KEY:
1552 if (!strchr(NEWLINE, db[i])) {
1553 key = db[i];
1554
1555 state = KEY;
1556 }
1557
1558 break;
1559 case KEY:
1560 if (db[i] != ':') {
1561 log_device_debug(device, "sd-device: Invalid db entry with key '%c', ignoring", key);
1562
1563 state = INVALID_LINE;
1564 } else {
1565 db[i] = '\0';
1566
1567 state = PRE_VALUE;
1568 }
1569
1570 break;
1571 case PRE_VALUE:
1572 value = &db[i];
1573
1574 state = VALUE;
1575
1576 break;
1577 case INVALID_LINE:
1578 if (strchr(NEWLINE, db[i]))
1579 state = PRE_KEY;
1580
1581 break;
1582 case VALUE:
1583 if (strchr(NEWLINE, db[i])) {
1584 db[i] = '\0';
1585 r = handle_db_line(device, key, value);
1586 if (r < 0)
1587 log_device_debug_errno(device, r, "sd-device: Failed to handle db entry '%c:%s', ignoring: %m",
1588 key, value);
1589
1590 state = PRE_KEY;
1591 }
1592
1593 break;
1594 default:
1595 return log_device_debug_errno(device, SYNTHETIC_ERRNO(EINVAL), "sd-device: invalid db syntax.");
1596 }
1597
1598 return 0;
1599 }
1600
1601 int device_read_db_internal(sd_device *device, bool force) {
1602 const char *id, *path;
1603 int r;
1604
1605 assert(device);
1606
1607 if (device->db_loaded || (!force && device->sealed))
1608 return 0;
1609
1610 r = device_get_device_id(device, &id);
1611 if (r < 0)
1612 return r;
1613
1614 path = strjoina("/run/udev/data/", id);
1615
1616 return device_read_db_internal_filename(device, path);
1617 }
1618
1619 _public_ int sd_device_get_is_initialized(sd_device *device) {
1620 int r;
1621
1622 assert_return(device, -EINVAL);
1623
1624 r = device_read_db(device);
1625 if (r == -ENOENT)
1626 /* The device may be already removed or renamed. */
1627 return false;
1628 if (r < 0)
1629 return r;
1630
1631 return device->is_initialized;
1632 }
1633
1634 _public_ int sd_device_get_usec_initialized(sd_device *device, uint64_t *ret) {
1635 int r;
1636
1637 assert_return(device, -EINVAL);
1638
1639 r = sd_device_get_is_initialized(device);
1640 if (r < 0)
1641 return r;
1642 if (r == 0)
1643 return -EBUSY;
1644
1645 if (device->usec_initialized == 0)
1646 return -ENODATA;
1647
1648 if (ret)
1649 *ret = device->usec_initialized;
1650
1651 return 0;
1652 }
1653
1654 _public_ int sd_device_get_usec_since_initialized(sd_device *device, uint64_t *ret) {
1655 usec_t now_ts, ts;
1656 int r;
1657
1658 assert_return(device, -EINVAL);
1659
1660 r = sd_device_get_usec_initialized(device, &ts);
1661 if (r < 0)
1662 return r;
1663
1664 now_ts = now(CLOCK_MONOTONIC);
1665
1666 if (now_ts < ts)
1667 return -EIO;
1668
1669 if (ret)
1670 *ret = usec_sub_unsigned(now_ts, ts);
1671
1672 return 0;
1673 }
1674
1675 _public_ const char *sd_device_get_tag_first(sd_device *device) {
1676 void *v;
1677
1678 assert_return(device, NULL);
1679
1680 (void) device_read_db(device);
1681
1682 device->all_tags_iterator_generation = device->tags_generation;
1683 device->all_tags_iterator = ITERATOR_FIRST;
1684
1685 (void) set_iterate(device->all_tags, &device->all_tags_iterator, &v);
1686 return v;
1687 }
1688
1689 _public_ const char *sd_device_get_tag_next(sd_device *device) {
1690 void *v;
1691
1692 assert_return(device, NULL);
1693
1694 (void) device_read_db(device);
1695
1696 if (device->all_tags_iterator_generation != device->tags_generation)
1697 return NULL;
1698
1699 (void) set_iterate(device->all_tags, &device->all_tags_iterator, &v);
1700 return v;
1701 }
1702
1703 static bool device_database_supports_current_tags(sd_device *device) {
1704 assert(device);
1705
1706 (void) device_read_db(device);
1707
1708 /* The current tags (saved in Q field) feature is implemented in database version 1.
1709 * If the database version is 0, then the tags (NOT current tags, saved in G field) are not
1710 * sticky. Thus, we can safely bypass the operations for the current tags (Q) to tags (G). */
1711
1712 return device->database_version >= 1;
1713 }
1714
1715 _public_ const char *sd_device_get_current_tag_first(sd_device *device) {
1716 void *v;
1717
1718 assert_return(device, NULL);
1719
1720 if (!device_database_supports_current_tags(device))
1721 return sd_device_get_tag_first(device);
1722
1723 (void) device_read_db(device);
1724
1725 device->current_tags_iterator_generation = device->tags_generation;
1726 device->current_tags_iterator = ITERATOR_FIRST;
1727
1728 (void) set_iterate(device->current_tags, &device->current_tags_iterator, &v);
1729 return v;
1730 }
1731
1732 _public_ const char *sd_device_get_current_tag_next(sd_device *device) {
1733 void *v;
1734
1735 assert_return(device, NULL);
1736
1737 if (!device_database_supports_current_tags(device))
1738 return sd_device_get_tag_next(device);
1739
1740 (void) device_read_db(device);
1741
1742 if (device->current_tags_iterator_generation != device->tags_generation)
1743 return NULL;
1744
1745 (void) set_iterate(device->current_tags, &device->current_tags_iterator, &v);
1746 return v;
1747 }
1748
1749 _public_ const char *sd_device_get_devlink_first(sd_device *device) {
1750 void *v;
1751
1752 assert_return(device, NULL);
1753
1754 (void) device_read_db(device);
1755
1756 device->devlinks_iterator_generation = device->devlinks_generation;
1757 device->devlinks_iterator = ITERATOR_FIRST;
1758
1759 (void) set_iterate(device->devlinks, &device->devlinks_iterator, &v);
1760 return v;
1761 }
1762
1763 _public_ const char *sd_device_get_devlink_next(sd_device *device) {
1764 void *v;
1765
1766 assert_return(device, NULL);
1767
1768 (void) device_read_db(device);
1769
1770 if (device->devlinks_iterator_generation != device->devlinks_generation)
1771 return NULL;
1772
1773 (void) set_iterate(device->devlinks, &device->devlinks_iterator, &v);
1774 return v;
1775 }
1776
1777 int device_properties_prepare(sd_device *device) {
1778 int r;
1779
1780 assert(device);
1781
1782 r = device_read_uevent_file(device);
1783 if (r < 0)
1784 return r;
1785
1786 r = device_read_db(device);
1787 if (r < 0)
1788 return r;
1789
1790 if (device->property_devlinks_outdated) {
1791 _cleanup_free_ char *devlinks = NULL;
1792
1793 r = set_strjoin(device->devlinks, " ", false, &devlinks);
1794 if (r < 0)
1795 return r;
1796
1797 if (!isempty(devlinks)) {
1798 r = device_add_property_internal(device, "DEVLINKS", devlinks);
1799 if (r < 0)
1800 return r;
1801 }
1802
1803 device->property_devlinks_outdated = false;
1804 }
1805
1806 if (device->property_tags_outdated) {
1807 _cleanup_free_ char *tags = NULL;
1808
1809 r = set_strjoin(device->all_tags, ":", true, &tags);
1810 if (r < 0)
1811 return r;
1812
1813 if (!isempty(tags)) {
1814 r = device_add_property_internal(device, "TAGS", tags);
1815 if (r < 0)
1816 return r;
1817 }
1818
1819 tags = mfree(tags);
1820 r = set_strjoin(device->current_tags, ":", true, &tags);
1821 if (r < 0)
1822 return r;
1823
1824 if (!isempty(tags)) {
1825 r = device_add_property_internal(device, "CURRENT_TAGS", tags);
1826 if (r < 0)
1827 return r;
1828 }
1829
1830 device->property_tags_outdated = false;
1831 }
1832
1833 return 0;
1834 }
1835
1836 _public_ const char *sd_device_get_property_first(sd_device *device, const char **_value) {
1837 const char *key;
1838 int r;
1839
1840 assert_return(device, NULL);
1841
1842 r = device_properties_prepare(device);
1843 if (r < 0)
1844 return NULL;
1845
1846 device->properties_iterator_generation = device->properties_generation;
1847 device->properties_iterator = ITERATOR_FIRST;
1848
1849 (void) ordered_hashmap_iterate(device->properties, &device->properties_iterator, (void**)_value, (const void**)&key);
1850 return key;
1851 }
1852
1853 _public_ const char *sd_device_get_property_next(sd_device *device, const char **_value) {
1854 const char *key;
1855 int r;
1856
1857 assert_return(device, NULL);
1858
1859 r = device_properties_prepare(device);
1860 if (r < 0)
1861 return NULL;
1862
1863 if (device->properties_iterator_generation != device->properties_generation)
1864 return NULL;
1865
1866 (void) ordered_hashmap_iterate(device->properties, &device->properties_iterator, (void**)_value, (const void**)&key);
1867 return key;
1868 }
1869
1870 static int device_sysattrs_read_all_internal(sd_device *device, const char *subdir) {
1871 _cleanup_free_ char *path_dir = NULL;
1872 _cleanup_closedir_ DIR *dir = NULL;
1873 const char *syspath;
1874 int r;
1875
1876 r = sd_device_get_syspath(device, &syspath);
1877 if (r < 0)
1878 return r;
1879
1880 if (subdir) {
1881 _cleanup_free_ char *p = NULL;
1882
1883 p = path_join(syspath, subdir, "uevent");
1884 if (!p)
1885 return -ENOMEM;
1886
1887 if (access(p, F_OK) >= 0)
1888 /* this is a child device, skipping */
1889 return 0;
1890 if (errno != ENOENT) {
1891 log_device_debug_errno(device, errno, "sd-device: Failed to stat %s, ignoring subdir: %m", p);
1892 return 0;
1893 }
1894
1895 path_dir = path_join(syspath, subdir);
1896 if (!path_dir)
1897 return -ENOMEM;
1898 }
1899
1900 dir = opendir(path_dir ?: syspath);
1901 if (!dir)
1902 return -errno;
1903
1904 FOREACH_DIRENT_ALL(de, dir, return -errno) {
1905 _cleanup_free_ char *path = NULL, *p = NULL;
1906 struct stat statbuf;
1907
1908 if (dot_or_dot_dot(de->d_name))
1909 continue;
1910
1911 /* only handle symlinks, regular files, and directories */
1912 if (!IN_SET(de->d_type, DT_LNK, DT_REG, DT_DIR))
1913 continue;
1914
1915 if (subdir) {
1916 p = path_join(subdir, de->d_name);
1917 if (!p)
1918 return -ENOMEM;
1919 }
1920
1921 if (de->d_type == DT_DIR) {
1922 /* read subdirectory */
1923 r = device_sysattrs_read_all_internal(device, p ?: de->d_name);
1924 if (r < 0)
1925 return r;
1926
1927 continue;
1928 }
1929
1930 path = path_join(syspath, p ?: de->d_name);
1931 if (!path)
1932 return -ENOMEM;
1933
1934 if (lstat(path, &statbuf) != 0)
1935 continue;
1936
1937 if ((statbuf.st_mode & (S_IRUSR | S_IWUSR)) == 0)
1938 continue;
1939
1940 r = set_put_strdup(&device->sysattrs, p ?: de->d_name);
1941 if (r < 0)
1942 return r;
1943 }
1944
1945 return 0;
1946 }
1947
1948 static int device_sysattrs_read_all(sd_device *device) {
1949 int r;
1950
1951 assert(device);
1952
1953 if (device->sysattrs_read)
1954 return 0;
1955
1956 r = device_sysattrs_read_all_internal(device, NULL);
1957 if (r < 0)
1958 return r;
1959
1960 device->sysattrs_read = true;
1961
1962 return 0;
1963 }
1964
1965 _public_ const char *sd_device_get_sysattr_first(sd_device *device) {
1966 void *v;
1967 int r;
1968
1969 assert_return(device, NULL);
1970
1971 if (!device->sysattrs_read) {
1972 r = device_sysattrs_read_all(device);
1973 if (r < 0) {
1974 errno = -r;
1975 return NULL;
1976 }
1977 }
1978
1979 device->sysattrs_iterator = ITERATOR_FIRST;
1980
1981 (void) set_iterate(device->sysattrs, &device->sysattrs_iterator, &v);
1982 return v;
1983 }
1984
1985 _public_ const char *sd_device_get_sysattr_next(sd_device *device) {
1986 void *v;
1987
1988 assert_return(device, NULL);
1989
1990 if (!device->sysattrs_read)
1991 return NULL;
1992
1993 (void) set_iterate(device->sysattrs, &device->sysattrs_iterator, &v);
1994 return v;
1995 }
1996
1997 _public_ int sd_device_has_tag(sd_device *device, const char *tag) {
1998 assert_return(device, -EINVAL);
1999 assert_return(tag, -EINVAL);
2000
2001 (void) device_read_db(device);
2002
2003 return set_contains(device->all_tags, tag);
2004 }
2005
2006 _public_ int sd_device_has_current_tag(sd_device *device, const char *tag) {
2007 assert_return(device, -EINVAL);
2008 assert_return(tag, -EINVAL);
2009
2010 if (!device_database_supports_current_tags(device))
2011 return sd_device_has_tag(device, tag);
2012
2013 (void) device_read_db(device);
2014
2015 return set_contains(device->current_tags, tag);
2016 }
2017
2018 _public_ int sd_device_get_property_value(sd_device *device, const char *key, const char **ret_value) {
2019 const char *value;
2020 int r;
2021
2022 assert_return(device, -EINVAL);
2023 assert_return(key, -EINVAL);
2024
2025 r = device_properties_prepare(device);
2026 if (r < 0)
2027 return r;
2028
2029 value = ordered_hashmap_get(device->properties, key);
2030 if (!value)
2031 return -ENOENT;
2032
2033 if (ret_value)
2034 *ret_value = value;
2035 return 0;
2036 }
2037
2038 int device_get_property_bool(sd_device *device, const char *key) {
2039 const char *value;
2040 int r;
2041
2042 assert(device);
2043 assert(key);
2044
2045 r = sd_device_get_property_value(device, key, &value);
2046 if (r < 0)
2047 return r;
2048
2049 return parse_boolean(value);
2050 }
2051
2052 _public_ int sd_device_get_trigger_uuid(sd_device *device, sd_id128_t *ret) {
2053 const char *s;
2054 sd_id128_t id;
2055 int r;
2056
2057 assert_return(device, -EINVAL);
2058
2059 /* Retrieves the UUID attached to a uevent when triggering it from userspace via
2060 * sd_device_trigger_with_uuid() or an equivalent interface. Returns -ENOENT if the record is not
2061 * caused by a synthetic event and -ENODATA if it was but no UUID was specified */
2062
2063 r = sd_device_get_property_value(device, "SYNTH_UUID", &s);
2064 if (r < 0)
2065 return r;
2066
2067 if (streq(s, "0")) /* SYNTH_UUID=0 is set whenever a device is triggered by userspace without specifying a UUID */
2068 return -ENODATA;
2069
2070 r = sd_id128_from_string(s, &id);
2071 if (r < 0)
2072 return r;
2073
2074 if (ret)
2075 *ret = id;
2076
2077 return 0;
2078 }
2079
2080 void device_clear_sysattr_cache(sd_device *device) {
2081 device->sysattr_values = hashmap_free(device->sysattr_values);
2082 }
2083
2084 int device_cache_sysattr_value(sd_device *device, const char *key, char *value) {
2085 _unused_ _cleanup_free_ char *old_value = NULL;
2086 _cleanup_free_ char *new_key = NULL;
2087 int r;
2088
2089 assert(device);
2090 assert(key);
2091
2092 /* This takes the reference of the input value. The input value may be NULL.
2093 * This replaces the value if it already exists. */
2094
2095 /* First, remove the old cache entry. So, we do not need to clear cache on error. */
2096 old_value = hashmap_remove2(device->sysattr_values, key, (void **) &new_key);
2097 if (!new_key) {
2098 new_key = strdup(key);
2099 if (!new_key)
2100 return -ENOMEM;
2101 }
2102
2103 r = hashmap_ensure_put(&device->sysattr_values, &string_hash_ops_free_free, new_key, value);
2104 if (r < 0)
2105 return r;
2106
2107 TAKE_PTR(new_key);
2108
2109 return 0;
2110 }
2111
2112 int device_get_cached_sysattr_value(sd_device *device, const char *key, const char **ret_value) {
2113 const char *k = NULL, *value;
2114
2115 assert(device);
2116 assert(key);
2117
2118 value = hashmap_get2(device->sysattr_values, key, (void **) &k);
2119 if (!k)
2120 return -ESTALE; /* We have not read the attribute. */
2121 if (!value)
2122 return -ENOENT; /* We have looked up the attribute before and it did not exist. */
2123 if (ret_value)
2124 *ret_value = value;
2125 return 0;
2126 }
2127
2128 /* We cache all sysattr lookups. If an attribute does not exist, it is stored
2129 * with a NULL value in the cache, otherwise the returned string is stored */
2130 _public_ int sd_device_get_sysattr_value(sd_device *device, const char *sysattr, const char **ret_value) {
2131 _cleanup_free_ char *value = NULL;
2132 const char *path, *syspath;
2133 struct stat statbuf;
2134 int r;
2135
2136 assert_return(device, -EINVAL);
2137 assert_return(sysattr, -EINVAL);
2138
2139 /* look for possibly already cached result */
2140 r = device_get_cached_sysattr_value(device, sysattr, ret_value);
2141 if (r != -ESTALE)
2142 return r;
2143
2144 r = sd_device_get_syspath(device, &syspath);
2145 if (r < 0)
2146 return r;
2147
2148 path = prefix_roota(syspath, sysattr);
2149 if (lstat(path, &statbuf) < 0) {
2150 int k;
2151
2152 r = -errno;
2153
2154 /* remember that we could not access the sysattr */
2155 k = device_cache_sysattr_value(device, sysattr, NULL);
2156 if (k < 0)
2157 log_device_debug_errno(device, k,
2158 "sd-device: failed to cache attribute '%s' with NULL, ignoring: %m",
2159 sysattr);
2160
2161 return r;
2162 } else if (S_ISLNK(statbuf.st_mode)) {
2163 /* Some core links return only the last element of the target path,
2164 * these are just values, the paths should not be exposed. */
2165 if (STR_IN_SET(sysattr, "driver", "subsystem", "module")) {
2166 r = readlink_value(path, &value);
2167 if (r < 0)
2168 return r;
2169 } else
2170 return -EINVAL;
2171 } else if (S_ISDIR(statbuf.st_mode))
2172 /* skip directories */
2173 return -EISDIR;
2174 else if (!(statbuf.st_mode & S_IRUSR))
2175 /* skip non-readable files */
2176 return -EPERM;
2177 else {
2178 size_t size;
2179
2180 /* Read attribute value, Some attributes contain embedded '\0'. So, it is necessary to
2181 * also get the size of the result. See issue #20025. */
2182 r = read_full_virtual_file(path, &value, &size);
2183 if (r < 0)
2184 return r;
2185
2186 /* drop trailing newlines */
2187 while (size > 0 && strchr(NEWLINE, value[--size]))
2188 value[size] = '\0';
2189 }
2190
2191 /* Unfortunately, we need to return 'const char*' instead of 'char*'. Hence, failure in caching
2192 * sysattr value is critical unlike the other places. */
2193 r = device_cache_sysattr_value(device, sysattr, value);
2194 if (r < 0) {
2195 log_device_debug_errno(device, r,
2196 "sd-device: failed to cache attribute '%s' with '%s'%s: %m",
2197 sysattr, value, ret_value ? "" : ", ignoring");
2198 if (ret_value)
2199 return r;
2200 } else if (ret_value)
2201 *ret_value = TAKE_PTR(value);
2202
2203 return 0;
2204 }
2205
2206 int device_get_sysattr_bool(sd_device *device, const char *sysattr) {
2207 const char *value;
2208 int r;
2209
2210 assert(device);
2211 assert(sysattr);
2212
2213 r = sd_device_get_sysattr_value(device, sysattr, &value);
2214 if (r < 0)
2215 return r;
2216
2217 return parse_boolean(value);
2218 }
2219
2220 static void device_remove_cached_sysattr_value(sd_device *device, const char *_key) {
2221 _cleanup_free_ char *key = NULL;
2222
2223 assert(device);
2224 assert(_key);
2225
2226 free(hashmap_remove2(device->sysattr_values, _key, (void **) &key));
2227 }
2228
2229 _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, const char *_value) {
2230 _cleanup_free_ char *value = NULL;
2231 const char *syspath, *path;
2232 size_t len;
2233 int r;
2234
2235 assert_return(device, -EINVAL);
2236 assert_return(sysattr, -EINVAL);
2237
2238 /* Set the attribute and save it in the cache. */
2239
2240 if (!_value) {
2241 /* If input value is NULL, then clear cache and not write anything. */
2242 device_remove_cached_sysattr_value(device, sysattr);
2243 return 0;
2244 }
2245
2246 r = sd_device_get_syspath(device, &syspath);
2247 if (r < 0)
2248 return r;
2249
2250 path = prefix_roota(syspath, sysattr);
2251
2252 len = strlen(_value);
2253
2254 /* drop trailing newlines */
2255 while (len > 0 && strchr(NEWLINE, _value[len - 1]))
2256 len --;
2257
2258 /* value length is limited to 4k */
2259 if (len > 4096)
2260 return -EINVAL;
2261
2262 value = strndup(_value, len);
2263 if (!value)
2264 return -ENOMEM;
2265
2266 r = write_string_file(path, value, WRITE_STRING_FILE_DISABLE_BUFFER | WRITE_STRING_FILE_NOFOLLOW);
2267 if (r < 0) {
2268 /* On failure, clear cache entry, as we do not know how it fails. */
2269 device_remove_cached_sysattr_value(device, sysattr);
2270 return r;
2271 }
2272
2273 /* Do not cache action string written into uevent file. */
2274 if (streq(sysattr, "uevent"))
2275 return 0;
2276
2277 r = device_cache_sysattr_value(device, sysattr, value);
2278 if (r < 0)
2279 log_device_debug_errno(device, r,
2280 "sd-device: failed to cache attribute '%s' with '%s', ignoring: %m",
2281 sysattr, value);
2282 else
2283 TAKE_PTR(value);
2284
2285 return 0;
2286 }
2287
2288 _public_ int sd_device_set_sysattr_valuef(sd_device *device, const char *sysattr, const char *format, ...) {
2289 _cleanup_free_ char *value = NULL;
2290 va_list ap;
2291 int r;
2292
2293 assert_return(device, -EINVAL);
2294 assert_return(sysattr, -EINVAL);
2295
2296 if (!format) {
2297 device_remove_cached_sysattr_value(device, sysattr);
2298 return 0;
2299 }
2300
2301 va_start(ap, format);
2302 r = vasprintf(&value, format, ap);
2303 va_end(ap);
2304
2305 if (r < 0)
2306 return -ENOMEM;
2307
2308 return sd_device_set_sysattr_value(device, sysattr, value);
2309 }
2310
2311 _public_ int sd_device_trigger(sd_device *device, sd_device_action_t action) {
2312 const char *s;
2313
2314 assert_return(device, -EINVAL);
2315
2316 s = device_action_to_string(action);
2317 if (!s)
2318 return -EINVAL;
2319
2320 /* This uses the simple no-UUID interface of kernel < 4.13 */
2321 return sd_device_set_sysattr_value(device, "uevent", s);
2322 }
2323
2324 _public_ int sd_device_trigger_with_uuid(
2325 sd_device *device,
2326 sd_device_action_t action,
2327 sd_id128_t *ret_uuid) {
2328
2329 const char *s, *j;
2330 sd_id128_t u;
2331 int r;
2332
2333 assert_return(device, -EINVAL);
2334
2335 /* If no one wants to know the UUID, use the simple interface from pre-4.13 times */
2336 if (!ret_uuid)
2337 return sd_device_trigger(device, action);
2338
2339 s = device_action_to_string(action);
2340 if (!s)
2341 return -EINVAL;
2342
2343 r = sd_id128_randomize(&u);
2344 if (r < 0)
2345 return r;
2346
2347 j = strjoina(s, " ", SD_ID128_TO_UUID_STRING(u));
2348
2349 r = sd_device_set_sysattr_value(device, "uevent", j);
2350 if (r < 0)
2351 return r;
2352
2353 *ret_uuid = u;
2354 return 0;
2355 }
2356
2357 _public_ int sd_device_open(sd_device *device, int flags) {
2358 _cleanup_close_ int fd = -1, fd2 = -1;
2359 const char *devname, *subsystem = NULL;
2360 uint64_t q, diskseq = 0;
2361 struct stat st;
2362 dev_t devnum;
2363 int r;
2364
2365 assert_return(device, -EINVAL);
2366 assert_return(FLAGS_SET(flags, O_PATH) || !FLAGS_SET(flags, O_NOFOLLOW), -EINVAL);
2367
2368 r = sd_device_get_devname(device, &devname);
2369 if (r == -ENOENT)
2370 return -ENOEXEC;
2371 if (r < 0)
2372 return r;
2373
2374 r = sd_device_get_devnum(device, &devnum);
2375 if (r == -ENOENT)
2376 return -ENOEXEC;
2377 if (r < 0)
2378 return r;
2379
2380 r = sd_device_get_subsystem(device, &subsystem);
2381 if (r < 0 && r != -ENOENT)
2382 return r;
2383
2384 fd = open(devname, FLAGS_SET(flags, O_PATH) ? flags : O_CLOEXEC|O_NOFOLLOW|O_PATH);
2385 if (fd < 0)
2386 return -errno;
2387
2388 if (fstat(fd, &st) < 0)
2389 return -errno;
2390
2391 if (st.st_rdev != devnum)
2392 return -ENXIO;
2393
2394 if (streq_ptr(subsystem, "block") ? !S_ISBLK(st.st_mode) : !S_ISCHR(st.st_mode))
2395 return -ENXIO;
2396
2397 /* If flags has O_PATH, then we cannot check diskseq. Let's return earlier. */
2398 if (FLAGS_SET(flags, O_PATH))
2399 return TAKE_FD(fd);
2400
2401 r = device_get_property_bool(device, "ID_IGNORE_DISKSEQ");
2402 if (r < 0 && r != -ENOENT)
2403 return r;
2404 if (r <= 0) {
2405 r = sd_device_get_diskseq(device, &diskseq);
2406 if (r < 0 && r != -ENOENT)
2407 return r;
2408 }
2409
2410 fd2 = open(FORMAT_PROC_FD_PATH(fd), flags);
2411 if (fd2 < 0)
2412 return -errno;
2413
2414 if (diskseq == 0)
2415 return TAKE_FD(fd2);
2416
2417 r = fd_get_diskseq(fd2, &q);
2418 if (r < 0)
2419 return r;
2420
2421 if (q != diskseq)
2422 return -ENXIO;
2423
2424 return TAKE_FD(fd2);
2425 }