1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <ctype.h>
4 #include <errno.h>
5 #include <sys/inotify.h>
6 #include <unistd.h>
7 
8 #include "alloc-util.h"
9 #include "device-nodes.h"
10 #include "device-private.h"
11 #include "device-util.h"
12 #include "env-file.h"
13 #include "errno-util.h"
14 #include "escape.h"
15 #include "fd-util.h"
16 #include "id128-util.h"
17 #include "log.h"
18 #include "macro.h"
19 #include "parse-util.h"
20 #include "path-util.h"
21 #include "signal-util.h"
22 #include "socket-util.h"
23 #include "stat-util.h"
24 #include "string-table.h"
25 #include "string-util.h"
26 #include "strxcpyx.h"
27 #include "udev-util.h"
28 #include "utf8.h"
29 
30 static const char* const resolve_name_timing_table[_RESOLVE_NAME_TIMING_MAX] = {
31         [RESOLVE_NAME_NEVER] = "never",
32         [RESOLVE_NAME_LATE] = "late",
33         [RESOLVE_NAME_EARLY] = "early",
34 };
35 
36 DEFINE_STRING_TABLE_LOOKUP(resolve_name_timing, ResolveNameTiming);
37 
udev_parse_config_full(unsigned * ret_children_max,usec_t * ret_exec_delay_usec,usec_t * ret_event_timeout_usec,ResolveNameTiming * ret_resolve_name_timing,int * ret_timeout_signal)38 int udev_parse_config_full(
39                 unsigned *ret_children_max,
40                 usec_t *ret_exec_delay_usec,
41                 usec_t *ret_event_timeout_usec,
42                 ResolveNameTiming *ret_resolve_name_timing,
43                 int *ret_timeout_signal) {
44 
45         _cleanup_free_ char *log_val = NULL, *children_max = NULL, *exec_delay = NULL, *event_timeout = NULL, *resolve_names = NULL, *timeout_signal = NULL;
46         int r;
47 
48         r = parse_env_file(NULL, "/etc/udev/udev.conf",
49                            "udev_log", &log_val,
50                            "children_max", &children_max,
51                            "exec_delay", &exec_delay,
52                            "event_timeout", &event_timeout,
53                            "resolve_names", &resolve_names,
54                            "timeout_signal", &timeout_signal);
55         if (r == -ENOENT)
56                 return 0;
57         if (r < 0)
58                 return r;
59 
60         if (log_val) {
61                 const char *log;
62                 size_t n;
63 
64                 /* unquote */
65                 n = strlen(log_val);
66                 if (n >= 2 &&
67                     ((log_val[0] == '"' && log_val[n-1] == '"') ||
68                      (log_val[0] == '\'' && log_val[n-1] == '\''))) {
69                         log_val[n - 1] = '\0';
70                         log = log_val + 1;
71                 } else
72                         log = log_val;
73 
74                 /* we set the udev log level here explicitly, this is supposed
75                  * to regulate the code in libudev/ and udev/. */
76                 r = log_set_max_level_from_string(log);
77                 if (r < 0)
78                         log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
79                                    "failed to set udev log level '%s', ignoring: %m", log);
80         }
81 
82         if (ret_children_max && children_max) {
83                 r = safe_atou(children_max, ret_children_max);
84                 if (r < 0)
85                         log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
86                                    "failed to parse children_max=%s, ignoring: %m", children_max);
87         }
88 
89         if (ret_exec_delay_usec && exec_delay) {
90                 r = parse_sec(exec_delay, ret_exec_delay_usec);
91                 if (r < 0)
92                         log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
93                                    "failed to parse exec_delay=%s, ignoring: %m", exec_delay);
94         }
95 
96         if (ret_event_timeout_usec && event_timeout) {
97                 r = parse_sec(event_timeout, ret_event_timeout_usec);
98                 if (r < 0)
99                         log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
100                                    "failed to parse event_timeout=%s, ignoring: %m", event_timeout);
101         }
102 
103         if (ret_resolve_name_timing && resolve_names) {
104                 ResolveNameTiming t;
105 
106                 t = resolve_name_timing_from_string(resolve_names);
107                 if (t < 0)
108                         log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
109                                    "failed to parse resolve_names=%s, ignoring.", resolve_names);
110                 else
111                         *ret_resolve_name_timing = t;
112         }
113 
114         if (ret_timeout_signal && timeout_signal) {
115                 r = signal_from_string(timeout_signal);
116                 if (r < 0)
117                         log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
118                                    "failed to parse timeout_signal=%s, ignoring: %m", timeout_signal);
119                 else
120                         *ret_timeout_signal = r;
121         }
122 
123         return 0;
124 }
125 
126 /* Note that if -ENOENT is returned, it will be logged at debug level rather than error,
127  * because it's an expected, common occurrence that the caller will handle with a fallback */
device_new_from_dev_path(const char * devlink,sd_device ** ret_device)128 static int device_new_from_dev_path(const char *devlink, sd_device **ret_device) {
129         struct stat st;
130         int r;
131 
132         assert(devlink);
133 
134         if (stat(devlink, &st) < 0)
135                 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
136                                       "Failed to stat() %s: %m", devlink);
137 
138         if (!S_ISBLK(st.st_mode))
139                 return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
140                                        "%s does not point to a block device: %m", devlink);
141 
142         r = sd_device_new_from_stat_rdev(ret_device, &st);
143         if (r < 0)
144                 return log_error_errno(r, "Failed to initialize device from %s: %m", devlink);
145 
146         return 0;
147 }
148 
149 struct DeviceMonitorData {
150         const char *sysname;
151         const char *devlink;
152         sd_device *device;
153 };
154 
device_monitor_data_free(struct DeviceMonitorData * d)155 static void device_monitor_data_free(struct DeviceMonitorData *d) {
156         assert(d);
157 
158         sd_device_unref(d->device);
159 }
160 
device_monitor_handler(sd_device_monitor * monitor,sd_device * device,void * userdata)161 static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device, void *userdata) {
162         struct DeviceMonitorData *data = userdata;
163         const char *sysname;
164 
165         assert(device);
166         assert(data);
167         assert(data->sysname || data->devlink);
168         assert(!data->device);
169 
170         /* Ignore REMOVE events here. We are waiting for initialization after all, not de-initialization. We
171          * might see a REMOVE event from an earlier use of the device (devices by the same name are recycled
172          * by the kernel after all), which we should not get confused by. After all we cannot distinguish use
173          * cycles of the devices, as the udev queue is entirely asynchronous.
174          *
175          * If we see a REMOVE event here for the use cycle we actually care about then we won't notice of
176          * course, but that should be OK, given the timeout logic used on the wait loop: this will be noticed
177          * by means of -ETIMEDOUT. Thus we won't notice immediately, but eventually, and that should be
178          * sufficient for an error path that should regularly not happen.
179          *
180          * (And yes, we only need to special case REMOVE. It's the only "negative" event type, where a device
181          * ceases to exist. All other event types are "positive": the device exists and is registered in the
182          * udev database, thus whenever we see the event, we can consider it initialized.) */
183         if (device_for_action(device, SD_DEVICE_REMOVE))
184                 return 0;
185 
186         if (data->sysname && sd_device_get_sysname(device, &sysname) >= 0 && streq(sysname, data->sysname))
187                 goto found;
188 
189         if (data->devlink) {
190                 const char *devlink;
191 
192                 FOREACH_DEVICE_DEVLINK(device, devlink)
193                         if (path_equal(devlink, data->devlink))
194                                 goto found;
195 
196                 if (sd_device_get_devname(device, &devlink) >= 0 && path_equal(devlink, data->devlink))
197                         goto found;
198         }
199 
200         return 0;
201 
202 found:
203         data->device = sd_device_ref(device);
204         return sd_event_exit(sd_device_monitor_get_event(monitor), 0);
205 }
206 
device_wait_for_initialization_internal(sd_device * _device,const char * devlink,const char * subsystem,usec_t deadline,sd_device ** ret)207 static int device_wait_for_initialization_internal(
208                 sd_device *_device,
209                 const char *devlink,
210                 const char *subsystem,
211                 usec_t deadline,
212                 sd_device **ret) {
213 
214         _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
215         _cleanup_(sd_event_source_unrefp) sd_event_source *timeout_source = NULL;
216         _cleanup_(sd_event_unrefp) sd_event *event = NULL;
217         /* Ensure that if !_device && devlink, device gets unrefd on errors since it will be new */
218         _cleanup_(sd_device_unrefp) sd_device *device = sd_device_ref(_device);
219         _cleanup_(device_monitor_data_free) struct DeviceMonitorData data = {
220                 .devlink = devlink,
221         };
222         int r;
223 
224         assert(device || (subsystem && devlink));
225 
226         /* Devlink might already exist, if it does get the device to use the sysname filtering */
227         if (!device && devlink) {
228                 r = device_new_from_dev_path(devlink, &device);
229                 if (r < 0 && r != -ENOENT)
230                         return r;
231         }
232 
233         if (device) {
234                 if (sd_device_get_is_initialized(device) > 0) {
235                         if (ret)
236                                 *ret = sd_device_ref(device);
237                         return 0;
238                 }
239                 /* We need either the sysname or the devlink for filtering */
240                 assert_se(sd_device_get_sysname(device, &data.sysname) >= 0 || devlink);
241         }
242 
243         /* Wait until the device is initialized, so that we can get access to the ID_PATH property */
244 
245         r = sd_event_new(&event);
246         if (r < 0)
247                 return log_error_errno(r, "Failed to get default event: %m");
248 
249         r = sd_device_monitor_new(&monitor);
250         if (r < 0)
251                 return log_error_errno(r, "Failed to acquire monitor: %m");
252 
253         if (device && !subsystem) {
254                 r = sd_device_get_subsystem(device, &subsystem);
255                 if (r < 0 && r != -ENOENT)
256                         return log_device_error_errno(device, r, "Failed to get subsystem: %m");
257         }
258 
259         if (subsystem) {
260                 r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, NULL);
261                 if (r < 0)
262                         return log_error_errno(r, "Failed to add %s subsystem match to monitor: %m", subsystem);
263         }
264 
265         r = sd_device_monitor_attach_event(monitor, event);
266         if (r < 0)
267                 return log_error_errno(r, "Failed to attach event to device monitor: %m");
268 
269         r = sd_device_monitor_start(monitor, device_monitor_handler, &data);
270         if (r < 0)
271                 return log_error_errno(r, "Failed to start device monitor: %m");
272 
273         if (deadline != USEC_INFINITY) {
274                 r = sd_event_add_time(
275                                 event, &timeout_source,
276                                 CLOCK_MONOTONIC, deadline, 0,
277                                 NULL, INT_TO_PTR(-ETIMEDOUT));
278                 if (r < 0)
279                         return log_error_errno(r, "Failed to add timeout event source: %m");
280         }
281 
282         /* Check again, maybe things changed. Udev will re-read the db if the device wasn't initialized
283          * yet. */
284         if (!device && devlink) {
285                 r = device_new_from_dev_path(devlink, &device);
286                 if (r < 0 && r != -ENOENT)
287                         return r;
288         }
289         if (device && sd_device_get_is_initialized(device) > 0) {
290                 if (ret)
291                         *ret = sd_device_ref(device);
292                 return 0;
293         }
294 
295         r = sd_event_loop(event);
296         if (r < 0)
297                 return log_error_errno(r, "Failed to wait for device to be initialized: %m");
298 
299         if (ret)
300                 *ret = TAKE_PTR(data.device);
301         return 0;
302 }
303 
device_wait_for_initialization(sd_device * device,const char * subsystem,usec_t deadline,sd_device ** ret)304 int device_wait_for_initialization(sd_device *device, const char *subsystem, usec_t deadline, sd_device **ret) {
305         return device_wait_for_initialization_internal(device, NULL, subsystem, deadline, ret);
306 }
307 
device_wait_for_devlink(const char * devlink,const char * subsystem,usec_t deadline,sd_device ** ret)308 int device_wait_for_devlink(const char *devlink, const char *subsystem, usec_t deadline, sd_device **ret) {
309         return device_wait_for_initialization_internal(NULL, devlink, subsystem, deadline, ret);
310 }
311 
device_is_renaming(sd_device * dev)312 int device_is_renaming(sd_device *dev) {
313         int r;
314 
315         assert(dev);
316 
317         r = sd_device_get_property_value(dev, "ID_RENAMING", NULL);
318         if (r == -ENOENT)
319                 return false;
320         if (r < 0)
321                 return r;
322 
323         return true;
324 }
325 
device_for_action(sd_device * dev,sd_device_action_t a)326 bool device_for_action(sd_device *dev, sd_device_action_t a) {
327         sd_device_action_t b;
328 
329         assert(dev);
330 
331         if (a < 0)
332                 return false;
333 
334         if (sd_device_get_action(dev, &b) < 0)
335                 return false;
336 
337         return a == b;
338 }
339 
log_device_uevent(sd_device * device,const char * str)340 void log_device_uevent(sd_device *device, const char *str) {
341         sd_device_action_t action = _SD_DEVICE_ACTION_INVALID;
342         sd_id128_t event_id = SD_ID128_NULL;
343         uint64_t seqnum = 0;
344 
345         if (!DEBUG_LOGGING)
346                 return;
347 
348         (void) sd_device_get_seqnum(device, &seqnum);
349         (void) sd_device_get_action(device, &action);
350         (void) sd_device_get_trigger_uuid(device, &event_id);
351         log_device_debug(device, "%s%s(SEQNUM=%"PRIu64", ACTION=%s%s%s)",
352                          strempty(str), isempty(str) ? "" : " ",
353                          seqnum, strna(device_action_to_string(action)),
354                          sd_id128_is_null(event_id) ? "" : ", UUID=",
355                          sd_id128_is_null(event_id) ? "" : SD_ID128_TO_UUID_STRING(event_id));
356 }
357 
udev_rule_parse_value(char * str,char ** ret_value,char ** ret_endpos)358 int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) {
359         char *i, *j;
360         bool is_escaped;
361 
362         /* value must be double quotated */
363         is_escaped = str[0] == 'e';
364         str += is_escaped;
365         if (str[0] != '"')
366                 return -EINVAL;
367         str++;
368 
369         if (!is_escaped) {
370                 /* unescape double quotation '\"'->'"' */
371                 for (i = j = str; *i != '"'; i++, j++) {
372                         if (*i == '\0')
373                                 return -EINVAL;
374                         if (i[0] == '\\' && i[1] == '"')
375                                 i++;
376                         *j = *i;
377                 }
378                 j[0] = '\0';
379         } else {
380                 _cleanup_free_ char *unescaped = NULL;
381                 ssize_t l;
382 
383                 /* find the end position of value */
384                 for (i = str; *i != '"'; i++) {
385                         if (i[0] == '\\')
386                                 i++;
387                         if (*i == '\0')
388                                 return -EINVAL;
389                 }
390                 i[0] = '\0';
391 
392                 l = cunescape_length(str, i - str, 0, &unescaped);
393                 if (l < 0)
394                         return l;
395 
396                 assert(l <= i - str);
397                 memcpy(str, unescaped, l + 1);
398         }
399 
400         *ret_value = str;
401         *ret_endpos = i + 1;
402         return 0;
403 }
404 
udev_replace_whitespace(const char * str,char * to,size_t len)405 size_t udev_replace_whitespace(const char *str, char *to, size_t len) {
406         bool is_space = false;
407         size_t i, j;
408 
409         assert(str);
410         assert(to);
411 
412         /* Copy from 'str' to 'to', while removing all leading and trailing whitespace, and replacing
413          * each run of consecutive whitespace with a single underscore. The chars from 'str' are copied
414          * up to the \0 at the end of the string, or at most 'len' chars.  This appends \0 to 'to', at
415          * the end of the copied characters.
416          *
417          * If 'len' chars are copied into 'to', the final \0 is placed at len+1 (i.e. 'to[len] = \0'),
418          * so the 'to' buffer must have at least len+1 chars available.
419          *
420          * Note this may be called with 'str' == 'to', i.e. to replace whitespace in-place in a buffer.
421          * This function can handle that situation.
422          *
423          * Note that only 'len' characters are read from 'str'. */
424 
425         i = strspn(str, WHITESPACE);
426 
427         for (j = 0; j < len && i < len && str[i] != '\0'; i++) {
428                 if (isspace(str[i])) {
429                         is_space = true;
430                         continue;
431                 }
432 
433                 if (is_space) {
434                         if (j + 1 >= len)
435                                 break;
436 
437                         to[j++] = '_';
438                         is_space = false;
439                 }
440                 to[j++] = str[i];
441         }
442 
443         to[j] = '\0';
444         return j;
445 }
446 
udev_replace_ifname(char * str)447 size_t udev_replace_ifname(char *str) {
448         size_t replaced = 0;
449 
450         assert(str);
451 
452         /* See ifname_valid_full(). */
453 
454         for (char *p = str; *p != '\0'; p++)
455                 if (!ifname_valid_char(*p)) {
456                         *p = '_';
457                         replaced++;
458                 }
459 
460         return replaced;
461 }
462 
udev_replace_chars(char * str,const char * allow)463 size_t udev_replace_chars(char *str, const char *allow) {
464         size_t i = 0, replaced = 0;
465 
466         assert(str);
467 
468         /* allow chars in allow list, plain ascii, hex-escaping and valid utf8. */
469 
470         while (str[i] != '\0') {
471                 int len;
472 
473                 if (allow_listed_char_for_devnode(str[i], allow)) {
474                         i++;
475                         continue;
476                 }
477 
478                 /* accept hex encoding */
479                 if (str[i] == '\\' && str[i+1] == 'x') {
480                         i += 2;
481                         continue;
482                 }
483 
484                 /* accept valid utf8 */
485                 len = utf8_encoded_valid_unichar(str + i, SIZE_MAX);
486                 if (len > 1) {
487                         i += len;
488                         continue;
489                 }
490 
491                 /* if space is allowed, replace whitespace with ordinary space */
492                 if (isspace(str[i]) && allow && strchr(allow, ' ')) {
493                         str[i] = ' ';
494                         i++;
495                         replaced++;
496                         continue;
497                 }
498 
499                 /* everything else is replaced with '_' */
500                 str[i] = '_';
501                 i++;
502                 replaced++;
503         }
504         return replaced;
505 }
506 
udev_resolve_subsys_kernel(const char * string,char * result,size_t maxsize,bool read_value)507 int udev_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value) {
508         _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
509         _cleanup_free_ char *temp = NULL;
510         char *subsys, *sysname, *attr;
511         const char *val;
512         int r;
513 
514         assert(string);
515         assert(result);
516 
517         /* handle "[<SUBSYSTEM>/<KERNEL>]<attribute>" format */
518 
519         if (string[0] != '[')
520                 return -EINVAL;
521 
522         temp = strdup(string);
523         if (!temp)
524                 return -ENOMEM;
525 
526         subsys = &temp[1];
527 
528         sysname = strchr(subsys, '/');
529         if (!sysname)
530                 return -EINVAL;
531         sysname[0] = '\0';
532         sysname = &sysname[1];
533 
534         attr = strchr(sysname, ']');
535         if (!attr)
536                 return -EINVAL;
537         attr[0] = '\0';
538         attr = &attr[1];
539         if (attr[0] == '/')
540                 attr = &attr[1];
541         if (attr[0] == '\0')
542                 attr = NULL;
543 
544         if (read_value && !attr)
545                 return -EINVAL;
546 
547         r = sd_device_new_from_subsystem_sysname(&dev, subsys, sysname);
548         if (r < 0)
549                 return r;
550 
551         if (read_value) {
552                 r = sd_device_get_sysattr_value(dev, attr, &val);
553                 if (r < 0 && !ERRNO_IS_PRIVILEGE(r) && r != -ENOENT)
554                         return r;
555                 if (r >= 0)
556                         strscpy(result, maxsize, val);
557                 else
558                         result[0] = '\0';
559                 log_debug("value '[%s/%s]%s' is '%s'", subsys, sysname, attr, result);
560         } else {
561                 r = sd_device_get_syspath(dev, &val);
562                 if (r < 0)
563                         return r;
564 
565                 strscpyl(result, maxsize, val, attr ? "/" : NULL, attr ?: NULL, NULL);
566                 log_debug("path '[%s/%s]%s' is '%s'", subsys, sysname, strempty(attr), result);
567         }
568         return 0;
569 }
570 
udev_queue_is_empty(void)571 int udev_queue_is_empty(void) {
572         return access("/run/udev/queue", F_OK) < 0 ?
573                 (errno == ENOENT ? true : -errno) : false;
574 }
575 
udev_queue_init(void)576 int udev_queue_init(void) {
577         _cleanup_close_ int fd = -1;
578 
579         fd = inotify_init1(IN_CLOEXEC);
580         if (fd < 0)
581                 return -errno;
582 
583         if (inotify_add_watch(fd, "/run/udev" , IN_DELETE) < 0)
584                 return -errno;
585 
586         return TAKE_FD(fd);
587 }
588 
device_is_power_sink(sd_device * device)589 static int device_is_power_sink(sd_device *device) {
590         _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
591         bool found_source = false, found_sink = false;
592         sd_device *parent, *d;
593         int r;
594 
595         assert(device);
596 
597         /* USB-C power supply device has two power roles: source or sink. See,
598          * https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-typec */
599 
600         r = sd_device_enumerator_new(&e);
601         if (r < 0)
602                 return r;
603 
604         r = sd_device_enumerator_allow_uninitialized(e);
605         if (r < 0)
606                 return r;
607 
608         r = sd_device_enumerator_add_match_subsystem(e, "typec", true);
609         if (r < 0)
610                 return r;
611 
612         r = sd_device_get_parent(device, &parent);
613         if (r < 0)
614                 return r;
615 
616         r = sd_device_enumerator_add_match_parent(e, parent);
617         if (r < 0)
618                 return r;
619 
620         FOREACH_DEVICE(e, d) {
621                 const char *val;
622 
623                 r = sd_device_get_sysattr_value(d, "power_role", &val);
624                 if (r < 0) {
625                         if (r != -ENOENT)
626                                 log_device_debug_errno(d, r, "Failed to read 'power_role' sysfs attribute, ignoring: %m");
627                         continue;
628                 }
629 
630                 if (strstr(val, "[source]")) {
631                         found_source = true;
632                         log_device_debug(d, "The USB type-C port is in power source mode.");
633                 } else if (strstr(val, "[sink]")) {
634                         found_sink = true;
635                         log_device_debug(d, "The USB type-C port is in power sink mode.");
636                 }
637         }
638 
639         if (found_sink)
640                 log_device_debug(device, "The USB type-C device has at least one port in power sink mode.");
641         else if (!found_source)
642                 log_device_debug(device, "The USB type-C device has no port in power source mode, assuming the device is in power sink mode.");
643         else
644                 log_device_debug(device, "All USB type-C ports are in power source mode.");
645 
646         return found_sink || !found_source;
647 }
648 
on_ac_power(void)649 int on_ac_power(void) {
650         _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
651         bool found_offline = false, found_online = false;
652         sd_device *d;
653         int r;
654 
655         r = sd_device_enumerator_new(&e);
656         if (r < 0)
657                 return r;
658 
659         r = sd_device_enumerator_allow_uninitialized(e);
660         if (r < 0)
661                 return r;
662 
663         r = sd_device_enumerator_add_match_subsystem(e, "power_supply", true);
664         if (r < 0)
665                 return r;
666 
667         FOREACH_DEVICE(e, d) {
668                 const char *val;
669                 unsigned v;
670 
671                 r = sd_device_get_sysattr_value(d, "type", &val);
672                 if (r < 0) {
673                         log_device_debug_errno(d, r, "Failed to read 'type' sysfs attribute, ignoring: %m");
674                         continue;
675                 }
676 
677                 /* We assume every power source is AC, except for batteries. See
678                  * https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176
679                  * for defined power source types. Also see:
680                  * https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power */
681                 if (streq(val, "Battery")) {
682                         log_device_debug(d, "The power supply is battery, ignoring.");
683                         continue;
684                 }
685 
686                 /* Ignore USB-C power supply in source mode. See issue #21988. */
687                 if (streq(val, "USB")) {
688                         r = device_is_power_sink(d);
689                         if (r <= 0) {
690                                 if (r < 0)
691                                         log_device_debug_errno(d, r, "Failed to determine the current power role, ignoring: %m");
692                                 else
693                                         log_device_debug(d, "USB power supply is in source mode, ignoring.");
694                                 continue;
695                         }
696                 }
697 
698                 r = sd_device_get_sysattr_value(d, "online", &val);
699                 if (r < 0) {
700                         log_device_debug_errno(d, r, "Failed to read 'online' sysfs attribute, ignoring: %m");
701                         continue;
702                 }
703 
704                 r = safe_atou(val, &v);
705                 if (r < 0) {
706                         log_device_debug_errno(d, r, "Failed to parse 'online' attribute, ignoring: %m");
707                         continue;
708                 }
709 
710                 if (v > 0) /* At least 1 and 2 are defined as different types of 'online' */
711                         found_online = true;
712                 else
713                         found_offline = true;
714 
715                 log_device_debug(d, "The power supply is currently %s.", v > 0 ? "online" : "offline");
716         }
717 
718         if (found_online)
719                 log_debug("Found at least one online non-battery power supply, system is running on AC power.");
720         else if (!found_offline)
721                 log_debug("Found no offline non-battery power supply, assuming system is running on AC power.");
722         else
723                 log_debug("All non-battery power supplies are offline, assuming system is running with battery.");
724 
725         return found_online || !found_offline;
726 }
727 
udev_available(void)728 bool udev_available(void) {
729         static int cache = -1;
730 
731         /* The service systemd-udevd is started only when /sys is read write.
732          * See systemd-udevd.service: ConditionPathIsReadWrite=/sys
733          * Also, our container interface (http://systemd.io/CONTAINER_INTERFACE/) states that /sys must
734          * be mounted in read-only mode in containers. */
735 
736         if (cache >= 0)
737                 return cache;
738 
739         return (cache = (path_is_read_only_fs("/sys/") <= 0));
740 }
741