]>
Commit | Line | Data |
---|---|---|
e3631d1c LP |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | ||
3 | #include <errno.h> | |
4 | #include <unistd.h> | |
5 | ||
c01dcddf | 6 | #include "alloc-util.h" |
e3631d1c LP |
7 | #include "fileio.h" |
8 | #include "log.h" | |
c01dcddf | 9 | #include "raw-reboot.h" |
e3631d1c LP |
10 | #include "reboot-util.h" |
11 | #include "string-util.h" | |
12 | #include "umask-util.h" | |
c01dcddf | 13 | #include "virt.h" |
e3631d1c LP |
14 | |
15 | int update_reboot_parameter_and_warn(const char *parameter) { | |
16 | int r; | |
17 | ||
18 | if (isempty(parameter)) { | |
19 | if (unlink("/run/systemd/reboot-param") < 0) { | |
20 | if (errno == ENOENT) | |
21 | return 0; | |
22 | ||
23 | return log_warning_errno(errno, "Failed to unlink reboot parameter file: %m"); | |
24 | } | |
25 | ||
26 | return 0; | |
27 | } | |
28 | ||
29 | RUN_WITH_UMASK(0022) { | |
30 | r = write_string_file("/run/systemd/reboot-param", parameter, | |
31 | WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC); | |
32 | if (r < 0) | |
33 | return log_warning_errno(r, "Failed to write reboot parameter file: %m"); | |
34 | } | |
35 | ||
36 | return 0; | |
37 | } | |
c01dcddf LP |
38 | |
39 | int reboot_with_parameter(RebootFlags flags) { | |
40 | int r; | |
41 | ||
42 | /* Reboots the system with a parameter that is read from /run/systemd/reboot-param. Returns 0 if REBOOT_DRY_RUN | |
43 | * was set and the actual reboot operation was hence skipped. If REBOOT_FALLBACK is set and the reboot with | |
44 | * parameter doesn't work out a fallback to classic reboot() is attempted. If REBOOT_FALLBACK is not set, 0 is | |
45 | * returned instead, which should be considered indication for the caller to fall back to reboot() on its own, | |
46 | * or somehow else deal with this. If REBOOT_LOG is specified will log about what it is going to do, as well as | |
47 | * all errors. */ | |
48 | ||
49 | if (detect_container() == 0) { | |
50 | _cleanup_free_ char *parameter = NULL; | |
51 | ||
52 | r = read_one_line_file("/run/systemd/reboot-param", ¶meter); | |
53 | if (r < 0 && r != -ENOENT) | |
54 | log_full_errno(flags & REBOOT_LOG ? LOG_WARNING : LOG_DEBUG, r, | |
55 | "Failed to read reboot parameter file, ignoring: %m"); | |
56 | ||
57 | if (!isempty(parameter)) { | |
58 | ||
59 | log_full(flags & REBOOT_LOG ? LOG_INFO : LOG_DEBUG, | |
60 | "Rebooting with argument '%s'.", parameter); | |
61 | ||
62 | if (flags & REBOOT_DRY_RUN) | |
63 | return 0; | |
64 | ||
65 | (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2, parameter); | |
66 | ||
67 | log_full_errno(flags & REBOOT_LOG ? LOG_WARNING : LOG_DEBUG, errno, | |
68 | "Failed to reboot with parameter, retrying without: %m"); | |
69 | } | |
70 | } | |
71 | ||
72 | if (!(flags & REBOOT_FALLBACK)) | |
73 | return 0; | |
74 | ||
75 | log_full(flags & REBOOT_LOG ? LOG_INFO : LOG_DEBUG, "Rebooting."); | |
76 | ||
77 | if (flags & REBOOT_DRY_RUN) | |
78 | return 0; | |
79 | ||
80 | (void) reboot(RB_AUTOBOOT); | |
81 | ||
82 | return log_full_errno(flags & REBOOT_LOG ? LOG_ERR : LOG_DEBUG, errno, "Failed to reboot: %m"); | |
83 | } |