Line data Source code
1 : /* SPDX-License-Identifier: LGPL-2.1+ */ 2 : 3 : #include <errno.h> 4 : #include <unistd.h> 5 : 6 : #include "alloc-util.h" 7 : #include "fileio.h" 8 : #include "log.h" 9 : #include "raw-reboot.h" 10 : #include "reboot-util.h" 11 : #include "string-util.h" 12 : #include "umask-util.h" 13 : #include "virt.h" 14 : 15 0 : int update_reboot_parameter_and_warn(const char *parameter, bool keep) { 16 : int r; 17 : 18 0 : if (isempty(parameter)) { 19 0 : if (keep) 20 0 : return 0; 21 : 22 0 : if (unlink("/run/systemd/reboot-param") < 0) { 23 0 : if (errno == ENOENT) 24 0 : return 0; 25 : 26 0 : return log_warning_errno(errno, "Failed to unlink reboot parameter file: %m"); 27 : } 28 : 29 0 : return 0; 30 : } 31 : 32 0 : RUN_WITH_UMASK(0022) { 33 0 : r = write_string_file("/run/systemd/reboot-param", parameter, 34 : WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC); 35 0 : if (r < 0) 36 0 : return log_warning_errno(r, "Failed to write reboot parameter file: %m"); 37 : } 38 : 39 0 : return 0; 40 : } 41 : 42 0 : int read_reboot_parameter(char **parameter) { 43 : int r; 44 : 45 0 : assert(parameter); 46 : 47 0 : r = read_one_line_file("/run/systemd/reboot-param", parameter); 48 0 : if (r < 0 && r != -ENOENT) 49 0 : return log_debug_errno(r, "Failed to read /run/systemd/reboot-param: %m"); 50 : 51 0 : return 0; 52 : } 53 : 54 0 : 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 0 : if (detect_container() == 0) { 65 0 : _cleanup_free_ char *parameter = NULL; 66 : 67 0 : r = read_one_line_file("/run/systemd/reboot-param", ¶meter); 68 0 : if (r < 0 && r != -ENOENT) 69 0 : log_full_errno(flags & REBOOT_LOG ? LOG_WARNING : LOG_DEBUG, r, 70 : "Failed to read reboot parameter file, ignoring: %m"); 71 : 72 0 : if (!isempty(parameter)) { 73 : 74 0 : log_full(flags & REBOOT_LOG ? LOG_INFO : LOG_DEBUG, 75 : "Rebooting with argument '%s'.", parameter); 76 : 77 0 : if (flags & REBOOT_DRY_RUN) 78 0 : return 0; 79 : 80 0 : (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2, parameter); 81 : 82 0 : log_full_errno(flags & REBOOT_LOG ? LOG_WARNING : LOG_DEBUG, errno, 83 : "Failed to reboot with parameter, retrying without: %m"); 84 : } 85 : } 86 : 87 0 : if (!(flags & REBOOT_FALLBACK)) 88 0 : return 0; 89 : 90 0 : log_full(flags & REBOOT_LOG ? LOG_INFO : LOG_DEBUG, "Rebooting."); 91 : 92 0 : if (flags & REBOOT_DRY_RUN) 93 0 : return 0; 94 : 95 0 : (void) reboot(RB_AUTOBOOT); 96 : 97 0 : return log_full_errno(flags & REBOOT_LOG ? LOG_ERR : LOG_DEBUG, errno, "Failed to reboot: %m"); 98 : }