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