[systemd-commits] 2 commits - man/systemd.service.xml src/core src/shared src/systemctl

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Mon Apr 21 07:02:02 PDT 2014


 man/systemd.service.xml               |   13 +++++++++++++
 src/core/dbus-service.c               |    1 +
 src/core/load-fragment-gperf.gperf.m4 |    1 +
 src/core/service.c                    |   16 ++++++++++++++++
 src/core/service.h                    |    1 +
 src/shared/util.c                     |   16 ++++++++++++++++
 src/shared/util.h                     |    6 ++++--
 src/systemctl/systemctl.c             |    9 +++------
 8 files changed, 55 insertions(+), 8 deletions(-)

New commits:
commit efe6e7d33a9feb0b647c77862016284457895fa6
Author: Michael Olbrich <m.olbrich at pengutronix.de>
Date:   Tue Mar 25 14:15:45 2014 +0100

    service: add support for reboot argument when triggered by StartLimitAction=
    
    When rebooting with systemctl, an optional argument can be passed to the
    reboot system call. This makes it possible the specify the argument in a
    service file and use it when the service triggers a restart.
    This is useful to distinguish between manual reboots and reboots caused by
    failing services.

diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 5b3afb8..a2a1b6b 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -1017,6 +1017,19 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 <option>none</option>.</para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><varname>RebootArgument=</varname></term>
+                                <listitem><para>Configure the optional
+                                argument for the
+                                <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                system call if
+                                <varname>StartLimitAction=</varname>
+                                is a reboot action. This works just
+                                like the optional argument to
+                                <command>systemctl reboot</command>
+                                command.</para></listitem>
+                        </varlistentry>
+
                 </variablelist>
 
                 <para>Check
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 0451790..45bfecf 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -50,6 +50,7 @@ const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Service, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Service, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StartLimitAction", "s", property_get_start_limit_action, offsetof(Service, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Service, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST),
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index dbb5d13..cb98c83 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -180,6 +180,7 @@ Service.WatchdogSec,             config_parse_sec,                   0,
 Service.StartLimitInterval,      config_parse_sec,                   0,                             offsetof(Service, start_limit.interval)
 Service.StartLimitBurst,         config_parse_unsigned,              0,                             offsetof(Service, start_limit.burst)
 Service.StartLimitAction,        config_parse_start_limit_action,    0,                             offsetof(Service, start_limit_action)
+Service.RebootArgument,          config_parse_string,                0,                             offsetof(Service, reboot_arg)
 Service.Type,                    config_parse_service_type,          0,                             offsetof(Service, type)
 Service.Restart,                 config_parse_service_restart,       0,                             offsetof(Service, restart)
 Service.PermissionsStartOnly,    config_parse_bool,                  0,                             offsetof(Service, permissions_start_only)
diff --git a/src/core/service.c b/src/core/service.c
index ae3695a..4ebce6a 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -24,6 +24,8 @@
 #include <dirent.h>
 #include <unistd.h>
 #include <sys/reboot.h>
+#include <linux/reboot.h>
+#include <sys/syscall.h>
 
 #include "manager.h"
 #include "unit.h"
@@ -300,6 +302,9 @@ static void service_done(Unit *u) {
         free(s->status_text);
         s->status_text = NULL;
 
+        free(s->reboot_arg);
+        s->reboot_arg = NULL;
+
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
         exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
         s->control_command = NULL;
@@ -2372,6 +2377,10 @@ static int service_start_limit_test(Service *s) {
         if (ratelimit_test(&s->start_limit))
                 return 0;
 
+        if (s->start_limit_action == SERVICE_START_LIMIT_REBOOT ||
+            s->start_limit_action == SERVICE_START_LIMIT_REBOOT_FORCE)
+                update_reboot_param_file(s->reboot_arg);
+
         switch (s->start_limit_action) {
 
         case SERVICE_START_LIMIT_NONE:
@@ -2407,6 +2416,13 @@ static int service_start_limit_test(Service *s) {
                 log_warning_unit(UNIT(s)->id,
                                  "%s start request repeated too quickly, rebooting immediately.", UNIT(s)->id);
                 sync();
+                if (s->reboot_arg) {
+                        log_info("Rebooting with argument '%s'.", s->reboot_arg);
+                        syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+                                LINUX_REBOOT_CMD_RESTART2, s->reboot_arg);
+                }
+
+                log_info("Rebooting.");
                 reboot(RB_AUTOBOOT);
                 break;
 
diff --git a/src/core/service.h b/src/core/service.h
index 1992926..fd05e9b 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -189,6 +189,7 @@ struct Service {
 
         RateLimit start_limit;
         StartLimitAction start_limit_action;
+        char *reboot_arg;
 
         UnitRef accept_socket;
 

commit c5220a940d00fc2520c702104939d0a4cf637254
Author: Michael Olbrich <m.olbrich at pengutronix.de>
Date:   Tue Mar 25 14:15:44 2014 +0100

    systemctl: delete REBOOT_PARAM_FILE if no parameter is specified
    
    And move it to sperate function.

diff --git a/src/shared/util.c b/src/shared/util.c
index c20dff2..b6285ab 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6397,3 +6397,19 @@ void hexdump(FILE *f, const void *p, size_t s) {
                 s -= 16;
         }
 }
+
+int update_reboot_param_file(const char *param)
+{
+        int r = 0;
+
+        if (param) {
+
+                r = write_string_file(REBOOT_PARAM_FILE, param);
+                if (r < 0)
+                        log_error("Failed to write reboot param to "
+                                  REBOOT_PARAM_FILE": %s", strerror(-r));
+        } else
+                unlink(REBOOT_PARAM_FILE);
+
+        return r;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index 891848a..5b060ef 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -917,6 +917,8 @@ char* mount_test_option(const char *haystack, const char *needle);
 void hexdump(FILE *f, const void *p, size_t s);
 
 union file_handle_union {
-  struct file_handle handle;
-  char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
+        struct file_handle handle;
+        char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
 };
+
+int update_reboot_param_file(const char *param);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 1b381f7..1717c19 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -6018,13 +6018,10 @@ static int halt_parse_argv(int argc, char *argv[]) {
                 }
         }
 
-        if (arg_action == ACTION_REBOOT && argc == optind + 1) {
-                r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
-                if (r < 0) {
-                        log_error("Failed to write reboot param to "
-                                  REBOOT_PARAM_FILE": %s", strerror(-r));
+        if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
+                r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
+                if (r < 0)
                         return r;
-                }
         } else if (optind < argc) {
                 log_error("Too many arguments.");
                 return -EINVAL;



More information about the systemd-commits mailing list