Branch data 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 : : }