]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/udev-util.c
udev-util: assume system is running on AC power when no battery found
[thirdparty/systemd.git] / src / shared / udev-util.c
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
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 */
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
155 static void device_monitor_data_free(struct DeviceMonitorData *d) {
156 assert(d);
157
158 sd_device_unref(d->device);
159 }
160
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
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
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
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
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
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
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
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
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
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
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
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
571 bool devpath_conflict(const char *a, const char *b) {
572 /* This returns true when two paths are equivalent, or one is a child of another. */
573
574 if (!a || !b)
575 return false;
576
577 for (; *a != '\0' && *b != '\0'; a++, b++)
578 if (*a != *b)
579 return false;
580
581 return *a == '/' || *b == '/' || *a == *b;
582 }
583
584 int udev_queue_is_empty(void) {
585 return access("/run/udev/queue", F_OK) < 0 ?
586 (errno == ENOENT ? true : -errno) : false;
587 }
588
589 int udev_queue_init(void) {
590 _cleanup_close_ int fd = -1;
591
592 fd = inotify_init1(IN_CLOEXEC);
593 if (fd < 0)
594 return -errno;
595
596 if (inotify_add_watch(fd, "/run/udev" , IN_DELETE) < 0)
597 return -errno;
598
599 return TAKE_FD(fd);
600 }
601
602 static int device_is_power_sink(sd_device *device) {
603 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
604 bool found_source = false, found_sink = false;
605 sd_device *parent, *d;
606 int r;
607
608 assert(device);
609
610 /* USB-C power supply device has two power roles: source or sink. See,
611 * https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-class-typec */
612
613 r = sd_device_enumerator_new(&e);
614 if (r < 0)
615 return r;
616
617 r = sd_device_enumerator_allow_uninitialized(e);
618 if (r < 0)
619 return r;
620
621 r = sd_device_enumerator_add_match_subsystem(e, "typec", true);
622 if (r < 0)
623 return r;
624
625 r = sd_device_get_parent(device, &parent);
626 if (r < 0)
627 return r;
628
629 r = sd_device_enumerator_add_match_parent(e, parent);
630 if (r < 0)
631 return r;
632
633 FOREACH_DEVICE(e, d) {
634 const char *val;
635
636 r = sd_device_get_sysattr_value(d, "power_role", &val);
637 if (r < 0) {
638 if (r != -ENOENT)
639 log_device_debug_errno(d, r, "Failed to read 'power_role' sysfs attribute, ignoring: %m");
640 continue;
641 }
642
643 if (strstr(val, "[source]")) {
644 found_source = true;
645 log_device_debug(d, "The USB type-C port is in power source mode.");
646 } else if (strstr(val, "[sink]")) {
647 found_sink = true;
648 log_device_debug(d, "The USB type-C port is in power sink mode.");
649 }
650 }
651
652 if (found_sink)
653 log_device_debug(device, "The USB type-C device has at least one port in power sink mode.");
654 else if (!found_source)
655 log_device_debug(device, "The USB type-C device has no port in power source mode, assuming the device is in power sink mode.");
656 else
657 log_device_debug(device, "All USB type-C ports are in power source mode.");
658
659 return found_sink || !found_source;
660 }
661
662 int on_ac_power(void) {
663 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
664 bool found_offline = false, found_online = false, found_battery = false;
665 sd_device *d;
666 int r;
667
668 r = sd_device_enumerator_new(&e);
669 if (r < 0)
670 return r;
671
672 r = sd_device_enumerator_allow_uninitialized(e);
673 if (r < 0)
674 return r;
675
676 r = sd_device_enumerator_add_match_subsystem(e, "power_supply", true);
677 if (r < 0)
678 return r;
679
680 FOREACH_DEVICE(e, d) {
681 const char *val;
682 unsigned v;
683
684 r = sd_device_get_sysattr_value(d, "type", &val);
685 if (r < 0) {
686 log_device_debug_errno(d, r, "Failed to read 'type' sysfs attribute, ignoring: %m");
687 continue;
688 }
689
690 /* We assume every power source is AC, except for batteries. See
691 * https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176
692 * for defined power source types. Also see:
693 * https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-class-power */
694 if (streq(val, "Battery")) {
695 found_battery = true;
696 log_device_debug(d, "The power supply is battery, ignoring.");
697 continue;
698 }
699
700 /* Ignore USB-C power supply in source mode. See issue #21988. */
701 if (streq(val, "USB")) {
702 r = device_is_power_sink(d);
703 if (r <= 0) {
704 if (r < 0)
705 log_device_debug_errno(d, r, "Failed to determine the current power role, ignoring: %m");
706 else
707 log_device_debug(d, "USB power supply is in source mode, ignoring.");
708 continue;
709 }
710 }
711
712 r = sd_device_get_sysattr_value(d, "online", &val);
713 if (r < 0) {
714 log_device_debug_errno(d, r, "Failed to read 'online' sysfs attribute, ignoring: %m");
715 continue;
716 }
717
718 r = safe_atou(val, &v);
719 if (r < 0) {
720 log_device_debug_errno(d, r, "Failed to parse 'online' attribute, ignoring: %m");
721 continue;
722 }
723
724 if (v > 0) /* At least 1 and 2 are defined as different types of 'online' */
725 found_online = true;
726 else
727 found_offline = true;
728
729 log_device_debug(d, "The power supply is currently %s.", v > 0 ? "online" : "offline");
730 }
731
732 if (found_online)
733 log_debug("Found at least one online non-battery power supply, system is running on AC power.");
734 else if (!found_offline)
735 log_debug("Found no offline non-battery power supply, assuming system is running on AC power.");
736 else if (!found_battery)
737 log_debug("Found no battery, assuming system is running on AC power.");
738 else
739 log_debug("All non-battery power supplies are offline, assuming system is running with battery.");
740
741 return found_online || !found_offline || !found_battery;
742 }
743
744 bool udev_available(void) {
745 static int cache = -1;
746
747 /* The service systemd-udevd is started only when /sys is read write.
748 * See systemd-udevd.service: ConditionPathIsReadWrite=/sys
749 * Also, our container interface (http://systemd.io/CONTAINER_INTERFACE/) states that /sys must
750 * be mounted in read-only mode in containers. */
751
752 if (cache >= 0)
753 return cache;
754
755 return (cache = (path_is_read_only_fs("/sys/") <= 0));
756 }