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