]>
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 | 14 | |
77defcf5 | 15 | int update_reboot_parameter_and_warn(const char *parameter, bool keep) { |
e3631d1c LP |
16 | int r; |
17 | ||
18 | if (isempty(parameter)) { | |
77defcf5 VJ |
19 | if (keep) |
20 | return 0; | |
21 | ||
e3631d1c LP |
22 | if (unlink("/run/systemd/reboot-param") < 0) { |
23 | if (errno == ENOENT) | |
24 | return 0; | |
25 | ||
26 | return log_warning_errno(errno, "Failed to unlink reboot parameter file: %m"); | |
27 | } | |
28 | ||
29 | return 0; | |
30 | } | |
31 | ||
32 | RUN_WITH_UMASK(0022) { | |
33 | r = write_string_file("/run/systemd/reboot-param", parameter, | |
34 | WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC); | |
35 | if (r < 0) | |
36 | return log_warning_errno(r, "Failed to write reboot parameter file: %m"); | |
37 | } | |
38 | ||
428b296a VJ |
39 | return 0; |
40 | } | |
41 | ||
42 | int read_reboot_parameter(char **parameter) { | |
43 | int r; | |
44 | ||
45 | assert(parameter); | |
46 | ||
47 | r = read_one_line_file("/run/systemd/reboot-param", parameter); | |
48 | if (r < 0 && r != -ENOENT) | |
49 | return log_debug_errno(r, "Failed to read /run/systemd/reboot-param: %m"); | |
50 | ||
e3631d1c LP |
51 | return 0; |
52 | } | |
c01dcddf LP |
53 | |
54 | int reboot_with_parameter(RebootFlags flags) { | |
55 | int r; | |
56 | ||
57 | /* Reboots the system with a parameter that is read from /run/systemd/reboot-param. Returns 0 if REBOOT_DRY_RUN | |
58 | * was set and the actual reboot operation was hence skipped. If REBOOT_FALLBACK is set and the reboot with | |
59 | * parameter doesn't work out a fallback to classic reboot() is attempted. If REBOOT_FALLBACK is not set, 0 is | |
60 | * returned instead, which should be considered indication for the caller to fall back to reboot() on its own, | |
61 | * or somehow else deal with this. If REBOOT_LOG is specified will log about what it is going to do, as well as | |
62 | * all errors. */ | |
63 | ||
64 | if (detect_container() == 0) { | |
65 | _cleanup_free_ char *parameter = NULL; | |
66 | ||
67 | r = read_one_line_file("/run/systemd/reboot-param", ¶meter); | |
68 | if (r < 0 && r != -ENOENT) | |
69 | log_full_errno(flags & REBOOT_LOG ? LOG_WARNING : LOG_DEBUG, r, | |
70 | "Failed to read reboot parameter file, ignoring: %m"); | |
71 | ||
72 | if (!isempty(parameter)) { | |
73 | ||
74 | log_full(flags & REBOOT_LOG ? LOG_INFO : LOG_DEBUG, | |
75 | "Rebooting with argument '%s'.", parameter); | |
76 | ||
77 | if (flags & REBOOT_DRY_RUN) | |
78 | return 0; | |
79 | ||
80 | (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2, parameter); | |
81 | ||
82 | log_full_errno(flags & REBOOT_LOG ? LOG_WARNING : LOG_DEBUG, errno, | |
83 | "Failed to reboot with parameter, retrying without: %m"); | |
84 | } | |
85 | } | |
86 | ||
87 | if (!(flags & REBOOT_FALLBACK)) | |
88 | return 0; | |
89 | ||
90 | log_full(flags & REBOOT_LOG ? LOG_INFO : LOG_DEBUG, "Rebooting."); | |
91 | ||
92 | if (flags & REBOOT_DRY_RUN) | |
93 | return 0; | |
94 | ||
95 | (void) reboot(RB_AUTOBOOT); | |
96 | ||
97 | return log_full_errno(flags & REBOOT_LOG ? LOG_ERR : LOG_DEBUG, errno, "Failed to reboot: %m"); | |
98 | } |