mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
Merge pull request #7834 from jkloetzke/disable-watchdog
core: add "disable watchdog " function
This commit is contained in:
commit
8a44b0b849
@ -85,6 +85,7 @@
|
||||
<term><varname>systemd.crash_shell</varname></term>
|
||||
<term><varname>systemd.crash_reboot</varname></term>
|
||||
<term><varname>systemd.confirm_spawn</varname></term>
|
||||
<term><varname>systemd.service_watchdogs</varname></term>
|
||||
<term><varname>systemd.show_status</varname></term>
|
||||
<term><varname>systemd.log_target=</varname></term>
|
||||
<term><varname>systemd.log_level=</varname></term>
|
||||
|
@ -53,7 +53,7 @@
|
||||
|
||||
<refnamediv>
|
||||
<refname>systemd-analyze</refname>
|
||||
<refpurpose>Analyze system boot-up performance</refpurpose>
|
||||
<refpurpose>Analyze and debug system manager</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
@ -131,6 +131,12 @@
|
||||
<arg choice="plain">calendar</arg>
|
||||
<arg choice="plain" rep="repeat"><replaceable>SPECS</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="plain">service-watchdogs</arg>
|
||||
<arg choice="plain"><replaceable>STATE</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
@ -139,7 +145,8 @@
|
||||
<para><command>systemd-analyze</command> may be used to determine
|
||||
system boot-up performance statistics and retrieve other state and
|
||||
tracing information from the system and service manager, and to
|
||||
verify the correctness of unit files.</para>
|
||||
verify the correctness of unit files. It is also used to access
|
||||
special functions useful for advanced system manager debugging.</para>
|
||||
|
||||
<para><command>systemd-analyze time</command> prints the time
|
||||
spent in the kernel before userspace has been reached, the time
|
||||
@ -232,6 +239,13 @@
|
||||
syntax described in
|
||||
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
||||
|
||||
<para><command>systemd-analyze service-watchdogs
|
||||
<replaceable>STATE</replaceable></command> globally enables or disables the service
|
||||
runtime watchdogs (<option>WatchdogSec=</option>) and emergency actions (e.g.
|
||||
<option>OnFailure=</option> or <option>StartLimitAction=</option>); see
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
The hardware watchdog is not affected by this setting.</para>
|
||||
|
||||
<para>If no command is passed, <command>systemd-analyze
|
||||
time</command> is implied.</para>
|
||||
|
||||
|
@ -273,6 +273,15 @@
|
||||
to all zeros.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--service-watchdogs=</option></term>
|
||||
|
||||
<listitem><para>Globally enable/disable all service watchdog timeouts and emergency
|
||||
actions. This setting may also be specified during boot, on the kernel
|
||||
command line via the <varname>systemd.service_watchdogs=</varname>
|
||||
option, see below. Defaults to enabled.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
@ -964,6 +973,19 @@
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>systemd.service_watchdogs=</varname></term>
|
||||
|
||||
<listitem><para>Takes a boolean argument. If disabled, all service runtime
|
||||
watchdogs (<option>WatchdogSec=</option>) and emergency actions (e.g.
|
||||
<option>OnFailure=</option> or <option>StartLimitAction=</option>) are
|
||||
ignored by the system manager (PID 1); see
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
Defaults to enabled, i.e. watchdogs and failure actions are processed
|
||||
normally. The hardware watchdog is not affected by this
|
||||
option.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>systemd.show_status</varname></term>
|
||||
|
||||
|
@ -49,6 +49,7 @@ _systemd_analyze() {
|
||||
[LOG_TARGET]='set-log-target'
|
||||
[VERIFY]='verify'
|
||||
[SECCOMP_FILTER]='syscall-filter'
|
||||
[SERVICE_WATCHDOGS]='service-watchdogs'
|
||||
)
|
||||
|
||||
_init_completion || return
|
||||
@ -124,6 +125,13 @@ _systemd_analyze() {
|
||||
compopt -o filenames
|
||||
fi
|
||||
|
||||
elif __contains_word "$verb" ${VERBS[SERVICE_WATCHDOGS]}; then
|
||||
if [[ $cur = -* ]]; then
|
||||
comps='--help --version --system --user'
|
||||
else
|
||||
comps='on off'
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
||||
|
@ -1521,6 +1521,39 @@ static int test_calendar(int argc, char *argv[], void *userdata) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int service_watchdogs(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
int b, r;
|
||||
|
||||
assert(argc == 2);
|
||||
assert(argv);
|
||||
|
||||
b = parse_boolean(argv[1]);
|
||||
if (b < 0) {
|
||||
log_error("Failed to parse service-watchdogs argument.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = acquire_bus(false, &bus);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create bus connection: %m");
|
||||
|
||||
r = sd_bus_set_property(
|
||||
bus,
|
||||
"org.freedesktop.systemd1",
|
||||
"/org/freedesktop/systemd1",
|
||||
"org.freedesktop.systemd1.Manager",
|
||||
"ServiceWatchdogs",
|
||||
&error,
|
||||
"b",
|
||||
b);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_verify(int argc, char *argv[], void *userdata) {
|
||||
return verify_units(strv_skip(argv, 1),
|
||||
arg_user ? UNIT_FILE_USER : UNIT_FILE_SYSTEM,
|
||||
@ -1563,6 +1596,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
|
||||
" verify FILE... Check unit files for correctness\n"
|
||||
" calendar SPEC... Validate repetitive calendar time events\n"
|
||||
" service-watchdogs on/off Enable/disable service watchdogs\n"
|
||||
, program_invocation_short_name);
|
||||
|
||||
/* When updating this list, including descriptions, apply
|
||||
@ -1708,20 +1742,21 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
static const Verb verbs[] = {
|
||||
{ "help", VERB_ANY, VERB_ANY, 0, help },
|
||||
{ "time", VERB_ANY, 1, VERB_DEFAULT, analyze_time },
|
||||
{ "blame", VERB_ANY, 1, 0, analyze_blame },
|
||||
{ "critical-chain", VERB_ANY, VERB_ANY, 0, analyze_critical_chain },
|
||||
{ "plot", VERB_ANY, 1, 0, analyze_plot },
|
||||
{ "dot", VERB_ANY, VERB_ANY, 0, dot },
|
||||
{ "set-log-level", 2, 2, 0, set_log_level },
|
||||
{ "get-log-level", VERB_ANY, 1, 0, get_log_level },
|
||||
{ "set-log-target", 2, 2, 0, set_log_target },
|
||||
{ "get-log-target", VERB_ANY, 1, 0, get_log_target },
|
||||
{ "dump", VERB_ANY, 1, 0, dump },
|
||||
{ "syscall-filter", VERB_ANY, VERB_ANY, 0, dump_syscall_filters },
|
||||
{ "verify", 2, VERB_ANY, 0, do_verify },
|
||||
{ "calendar", 2, VERB_ANY, 0, test_calendar },
|
||||
{ "help", VERB_ANY, VERB_ANY, 0, help },
|
||||
{ "time", VERB_ANY, 1, VERB_DEFAULT, analyze_time },
|
||||
{ "blame", VERB_ANY, 1, 0, analyze_blame },
|
||||
{ "critical-chain", VERB_ANY, VERB_ANY, 0, analyze_critical_chain },
|
||||
{ "plot", VERB_ANY, 1, 0, analyze_plot },
|
||||
{ "dot", VERB_ANY, VERB_ANY, 0, dot },
|
||||
{ "set-log-level", 2, 2, 0, set_log_level },
|
||||
{ "get-log-level", VERB_ANY, 1, 0, get_log_level },
|
||||
{ "set-log-target", 2, 2, 0, set_log_target },
|
||||
{ "get-log-target", VERB_ANY, 1, 0, get_log_target },
|
||||
{ "dump", VERB_ANY, 1, 0, dump },
|
||||
{ "syscall-filter", VERB_ANY, VERB_ANY, 0, dump_syscall_filters },
|
||||
{ "verify", 2, VERB_ANY, 0, do_verify },
|
||||
{ "calendar", 2, VERB_ANY, 0, test_calendar },
|
||||
{ "service-watchdogs", 2, 2, 0, service_watchdogs },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -2416,6 +2416,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
|
||||
SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
|
||||
SD_BUS_WRITABLE_PROPERTY("ServiceWatchdogs", "b", bus_property_get_bool, bus_property_set_bool, offsetof(Manager, service_watchdogs), 0),
|
||||
SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
|
||||
SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
|
||||
SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned, offsetof(Manager, return_value), 0),
|
||||
|
@ -49,6 +49,11 @@ int emergency_action(
|
||||
if (action == EMERGENCY_ACTION_NONE)
|
||||
return -ECANCELED;
|
||||
|
||||
if (!m->service_watchdogs) {
|
||||
log_warning("Watchdog disabled! Not acting on: %s", reason);
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
if (!MANAGER_IS_SYSTEM(m)) {
|
||||
/* Downgrade all options to simply exiting if we run
|
||||
* in user mode */
|
||||
|
@ -112,6 +112,7 @@ static char *arg_confirm_spawn = NULL;
|
||||
static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
|
||||
static bool arg_switched_root = false;
|
||||
static bool arg_no_pager = false;
|
||||
static bool arg_service_watchdogs = true;
|
||||
static char ***arg_join_controllers = NULL;
|
||||
static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
|
||||
static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
|
||||
@ -396,6 +397,14 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
||||
arg_confirm_spawn = s;
|
||||
}
|
||||
|
||||
} else if (proc_cmdline_key_streq(key, "systemd.service_watchdogs")) {
|
||||
|
||||
r = value ? parse_boolean(value) : true;
|
||||
if (r < 0)
|
||||
log_warning("Failed to parse service watchdog switch %s. Ignoring.", value);
|
||||
else
|
||||
arg_service_watchdogs = r;
|
||||
|
||||
} else if (proc_cmdline_key_streq(key, "systemd.show_status")) {
|
||||
|
||||
if (value) {
|
||||
@ -855,6 +864,7 @@ static void set_manager_settings(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
m->confirm_spawn = arg_confirm_spawn;
|
||||
m->service_watchdogs = arg_service_watchdogs;
|
||||
m->runtime_watchdog = arg_runtime_watchdog;
|
||||
m->shutdown_watchdog = arg_shutdown_watchdog;
|
||||
m->cad_burst_action = arg_cad_burst_action;
|
||||
@ -886,7 +896,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_SWITCHED_ROOT,
|
||||
ARG_DEFAULT_STD_OUTPUT,
|
||||
ARG_DEFAULT_STD_ERROR,
|
||||
ARG_MACHINE_ID
|
||||
ARG_MACHINE_ID,
|
||||
ARG_SERVICE_WATCHDOGS,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -913,6 +924,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
|
||||
{ "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
|
||||
{ "machine-id", required_argument, NULL, ARG_MACHINE_ID },
|
||||
{ "service-watchdogs", required_argument, NULL, ARG_SERVICE_WATCHDOGS },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -1067,6 +1079,13 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return log_error_errno(r, "Failed to parse confirm spawn option: %m");
|
||||
break;
|
||||
|
||||
case ARG_SERVICE_WATCHDOGS:
|
||||
r = parse_boolean(optarg);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse service watchdogs boolean: %s", optarg);
|
||||
arg_service_watchdogs = r;
|
||||
break;
|
||||
|
||||
case ARG_SHOW_STATUS:
|
||||
if (optarg) {
|
||||
r = parse_show_status(optarg, &arg_show_status);
|
||||
|
@ -2659,6 +2659,7 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
|
||||
fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
|
||||
fprintf(f, "ready-sent=%s\n", yes_no(m->ready_sent));
|
||||
fprintf(f, "taint-logged=%s\n", yes_no(m->taint_logged));
|
||||
fprintf(f, "service-watchdogs=%s\n", yes_no(m->service_watchdogs));
|
||||
|
||||
for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
|
||||
/* The userspace and finish timestamps only apply to the host system, hence only serialize them there */
|
||||
@ -2830,6 +2831,15 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
else
|
||||
m->taint_logged = m->taint_logged || b;
|
||||
|
||||
} else if ((val = startswith(l, "service-watchdogs="))) {
|
||||
int b;
|
||||
|
||||
b = parse_boolean(val);
|
||||
if (b < 0)
|
||||
log_notice("Failed to parse service-watchdogs flag %s", val);
|
||||
else
|
||||
m->service_watchdogs = b;
|
||||
|
||||
} else if (startswith(l, "env=")) {
|
||||
r = deserialize_environment(&m->environment, l);
|
||||
if (r == -ENOMEM)
|
||||
|
@ -277,6 +277,7 @@ struct Manager {
|
||||
ShowStatus show_status;
|
||||
char *confirm_spawn;
|
||||
bool no_console_output;
|
||||
bool service_watchdogs;
|
||||
|
||||
ExecOutput default_std_output, default_std_error;
|
||||
|
||||
|
@ -3419,10 +3419,14 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
|
||||
|
||||
watchdog_usec = service_get_watchdog_usec(s);
|
||||
|
||||
log_unit_error(UNIT(s), "Watchdog timeout (limit %s)!",
|
||||
format_timespan(t, sizeof(t), watchdog_usec, 1));
|
||||
if (UNIT(s)->manager->service_watchdogs) {
|
||||
log_unit_error(UNIT(s), "Watchdog timeout (limit %s)!",
|
||||
format_timespan(t, sizeof(t), watchdog_usec, 1));
|
||||
|
||||
service_enter_signal(s, SERVICE_STOP_SIGABRT, SERVICE_FAILURE_WATCHDOG);
|
||||
service_enter_signal(s, SERVICE_STOP_SIGABRT, SERVICE_FAILURE_WATCHDOG);
|
||||
} else
|
||||
log_unit_warning(UNIT(s), "Watchdog disabled! Ignoring watchdog timeout (limit %s)!",
|
||||
format_timespan(t, sizeof(t), watchdog_usec, 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1338,6 +1338,25 @@ int bus_property_get_bool(
|
||||
return sd_bus_message_append_basic(reply, 'b', &b);
|
||||
}
|
||||
|
||||
int bus_property_set_bool(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *value,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
int b, r;
|
||||
|
||||
r = sd_bus_message_read(value, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*(bool *) userdata = !!b;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bus_property_get_id128(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
|
@ -80,6 +80,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
|
||||
int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool value, bool all);
|
||||
|
||||
int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
|
||||
int bus_property_set_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error);
|
||||
int bus_property_get_id128(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
|
||||
|
||||
#define bus_property_get_usec ((sd_bus_property_get_t) NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user