mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
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.
This commit is contained in:
parent
c5220a940d
commit
efe6e7d33a
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -189,6 +189,7 @@ struct Service {
|
||||
|
||||
RateLimit start_limit;
|
||||
StartLimitAction start_limit_action;
|
||||
char *reboot_arg;
|
||||
|
||||
UnitRef accept_socket;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user