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