watchdog: add setting to configure pretimeout governor

This commit is contained in:
Luca Boccassi
2022-02-22 17:19:54 +00:00
parent 56b96db700
commit aff3a9e1fa
12 changed files with 201 additions and 14 deletions
+33
View File
@@ -22,6 +22,7 @@ static usec_t watchdog_timeout; /* 0 → close device and USEC_INFINITY → don'
static usec_t watchdog_pretimeout; /* 0 → disable pretimeout and USEC_INFINITY → don't change pretimeout */
static usec_t watchdog_last_ping = USEC_INFINITY;
static bool watchdog_supports_pretimeout = false; /* Depends on kernel state that might change at runtime */
static char *watchdog_pretimeout_governor = NULL;
/* Starting from kernel version 4.5, the maximum allowable watchdog timeout is
* UINT_MAX/1000U seconds (since internal calculations are done in milliseconds
@@ -76,6 +77,28 @@ static int get_pretimeout_governor(char **ret_gov) {
return 0;
}
static int set_pretimeout_governor(const char *governor) {
_cleanup_free_ char *sys_fn = NULL;
int r;
if (isempty(governor))
return 0; /* Nothing to do */
r = get_watchdog_sysfs_path("pretimeout_governor", &sys_fn);
if (r < 0)
return r;
log_info("Watchdog: setting pretimeout_governor to '%s' via '%s'", governor, sys_fn);
r = write_string_file(sys_fn,
governor,
WRITE_STRING_FILE_DISABLE_BUFFER | WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE);
if (r < 0)
return log_error_errno(r, "Failed to set pretimeout_governor to '%s': %m", governor);
return r;
}
static int watchdog_set_enable(bool enable) {
int flags = enable ? WDIOS_ENABLECARD : WDIOS_DISABLECARD;
@@ -194,6 +217,9 @@ static int update_pretimeout(void) {
* might have been unloaded. */
watchdog_supports_pretimeout = false;
/* Update the pretimeout governor as well */
(void) set_pretimeout_governor(watchdog_pretimeout_governor);
r = get_pretimeout_governor(&governor);
if (r < 0)
return log_warning_errno(r, "Watchdog: failed to read pretimeout governor: %m");
@@ -362,6 +388,13 @@ int watchdog_setup_pretimeout(usec_t timeout) {
return update_pretimeout();
}
int watchdog_setup_pretimeout_governor(const char *governor) {
if (free_and_strdup(&watchdog_pretimeout_governor, governor) < 0)
return -ENOMEM;
return set_pretimeout_governor(watchdog_pretimeout_governor);
}
static usec_t calc_timeout(void) {
/* Calculate the effective timeout which accounts for the watchdog
* pretimeout if configured and supported. */
+1
View File
@@ -9,6 +9,7 @@
int watchdog_set_device(const char *path);
int watchdog_setup(usec_t timeout);
int watchdog_setup_pretimeout(usec_t usec);
int watchdog_setup_pretimeout_governor(const char *governor);
int watchdog_ping(void);
void watchdog_close(bool disarm);
usec_t watchdog_runtime_wait(void);