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