]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
reboot-util: unify reboot with parameter in a single implementation
authorLennart Poettering <lennart@poettering.net>
Wed, 21 Feb 2018 17:48:49 +0000 (18:48 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 22 Feb 2018 09:46:26 +0000 (10:46 +0100)
So far, we had two implementations of reboot-with-parameter doing pretty
much the same. Let's unify that in a generic implementation used by
both.

This is particulary nice as it unifies all /run/systemd/reboot-param
handling in a single .c file.

src/basic/reboot-util.c
src/basic/reboot-util.h
src/core/shutdown.c
src/systemctl/systemctl.c

index 68910a6a34ed8eeb14124d11892df1d818def8ac..ca40159b96631d98cbcf9c15617a7ada5d7dddb4 100644 (file)
@@ -3,11 +3,14 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include "alloc-util.h"
 #include "fileio.h"
 #include "log.h"
+#include "raw-reboot.h"
 #include "reboot-util.h"
 #include "string-util.h"
 #include "umask-util.h"
+#include "virt.h"
 
 int update_reboot_parameter_and_warn(const char *parameter) {
         int r;
@@ -32,3 +35,49 @@ int update_reboot_parameter_and_warn(const char *parameter) {
 
         return 0;
 }
+
+int reboot_with_parameter(RebootFlags flags) {
+        int r;
+
+        /* Reboots the system with a parameter that is read from /run/systemd/reboot-param. Returns 0 if REBOOT_DRY_RUN
+         * was set and the actual reboot operation was hence skipped. If REBOOT_FALLBACK is set and the reboot with
+         * parameter doesn't work out a fallback to classic reboot() is attempted. If REBOOT_FALLBACK is not set, 0 is
+         * returned instead, which should be considered indication for the caller to fall back to reboot() on its own,
+         * or somehow else deal with this. If REBOOT_LOG is specified will log about what it is going to do, as well as
+         * all errors. */
+
+        if (detect_container() == 0) {
+                _cleanup_free_ char *parameter = NULL;
+
+                r = read_one_line_file("/run/systemd/reboot-param", &parameter);
+                if (r < 0 && r != -ENOENT)
+                        log_full_errno(flags & REBOOT_LOG ? LOG_WARNING : LOG_DEBUG, r,
+                                       "Failed to read reboot parameter file, ignoring: %m");
+
+                if (!isempty(parameter)) {
+
+                        log_full(flags & REBOOT_LOG ? LOG_INFO : LOG_DEBUG,
+                                 "Rebooting with argument '%s'.", parameter);
+
+                        if (flags & REBOOT_DRY_RUN)
+                                return 0;
+
+                        (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2, parameter);
+
+                        log_full_errno(flags & REBOOT_LOG ? LOG_WARNING : LOG_DEBUG, errno,
+                                       "Failed to reboot with parameter, retrying without: %m");
+                }
+        }
+
+        if (!(flags & REBOOT_FALLBACK))
+                return 0;
+
+        log_full(flags & REBOOT_LOG ? LOG_INFO : LOG_DEBUG, "Rebooting.");
+
+        if (flags & REBOOT_DRY_RUN)
+                return 0;
+
+        (void) reboot(RB_AUTOBOOT);
+
+        return log_full_errno(flags & REBOOT_LOG ? LOG_ERR : LOG_DEBUG, errno, "Failed to reboot: %m");
+}
index 6f1d24c1f5e4354d3620615504a4eb27896935c5..d4aa44129066e941c5b3ef14ace9cacda6a23f6e 100644 (file)
@@ -2,3 +2,11 @@
 #pragma once
 
 int update_reboot_parameter_and_warn(const char *parameter);
+
+typedef enum RebootFlags {
+        REBOOT_LOG      = 1U << 0,  /* log about what we are going to do and all errors */
+        REBOOT_DRY_RUN  = 1U << 1,  /* return 0 right before actually doing the reboot */
+        REBOOT_FALLBACK = 1U << 2,  /* fallback to plain reboot() if argument-based reboot doesn't work, isn't configured or doesn't apply otherwise */
+} RebootFlags;
+
+int reboot_with_parameter(RebootFlags flags);
index 33751c5ff55ccc9b8b4859eeaffd30fcc69c1bff..de689aea3111f6f84c5f403a6317fbfc85164d34 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <errno.h>
 #include <getopt.h>
+#include <linux/reboot.h>
 #include <signal.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -41,7 +42,7 @@
 #include "missing.h"
 #include "parse-util.h"
 #include "process-util.h"
-#include "raw-reboot.h"
+#include "reboot-util.h"
 #include "signal-util.h"
 #include "string-util.h"
 #include "switch-root.h"
@@ -517,22 +518,9 @@ int main(int argc, char *argv[]) {
 
                 cmd = RB_AUTOBOOT;
                 _fallthrough_;
-        case RB_AUTOBOOT:
-
-                if (!in_container) {
-                        _cleanup_free_ char *param = NULL;
-
-                        r = read_one_line_file("/run/systemd/reboot-param", &param);
-                        if (r < 0 && r != -ENOENT)
-                                log_warning_errno(r, "Failed to read reboot parameter file: %m");
-
-                        if (!isempty(param)) {
-                                log_info("Rebooting with argument '%s'.", param);
-                                (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2, param);
-                                log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
-                        }
-                }
 
+        case RB_AUTOBOOT:
+                (void) reboot_with_parameter(REBOOT_LOG);
                 log_info("Rebooting.");
                 break;
 
index 0d3d0d0daa51bb35af786e73fc9a42750a8b6b20..6eec0171c6b465fb33d85af0c1049c707f65995c 100644 (file)
@@ -72,7 +72,6 @@
 #include "path-lookup.h"
 #include "path-util.h"
 #include "process-util.h"
-#include "raw-reboot.h"
 #include "reboot-util.h"
 #include "rlimit-util.h"
 #include "set.h"
@@ -8473,11 +8472,9 @@ static int start_with_fallback(void) {
 }
 
 static int halt_now(enum action a) {
-        int r;
 
-        /* The kernel will automaticall flush ATA disks and suchlike
-         * on reboot(), but the file systems need to be synce'd
-         * explicitly in advance. */
+        /* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need to be
+         * synce'd explicitly in advance. */
         if (!arg_no_sync && !arg_dry_run)
                 (void) sync();
 
@@ -8504,29 +8501,10 @@ static int halt_now(enum action a) {
                 return -errno;
 
         case ACTION_KEXEC:
-        case ACTION_REBOOT: {
-                _cleanup_free_ char *param = NULL;
-
-                r = read_one_line_file("/run/systemd/reboot-param", &param);
-                if (r < 0 && r != -ENOENT)
-                        log_warning_errno(r, "Failed to read reboot parameter file: %m");
-
-                if (!isempty(param)) {
-                        if (!arg_quiet)
-                                log_info("Rebooting with argument '%s'.", param);
-                        if (!arg_dry_run) {
-                                (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2, param);
-                                log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
-                        }
-                }
-
-                if (!arg_quiet)
-                        log_info("Rebooting.");
-                if (arg_dry_run)
-                        return 0;
-                (void) reboot(RB_AUTOBOOT);
-                return -errno;
-        }
+        case ACTION_REBOOT:
+                return reboot_with_parameter(REBOOT_FALLBACK |
+                                             (arg_quiet ? 0 : REBOOT_LOG) |
+                                             (arg_dry_run ? REBOOT_DRY_RUN : 0));
 
         default:
                 assert_not_reached("Unknown action.");