Refactor config.c for generic setter interface (#9644)

This refactors all `CONFIG SET`s and conf file loading arguments go through
the generic config handling interface.

Refactoring changes:
- All config params go through the `standardConfig` interface (some stuff which
  is only related to the config file and not the `CONFIG` command still has special
  handling for rewrite/config file parsing, `loadmodule`, for example.) .
- Added `MULTI_ARG_CONFIG` flag for configs to signify they receive a variable
  number of arguments instead of a single argument. This is used to break up space
  separated arguments to `CONFIG SET` so the generic setter interface can pass
  multiple arguments to the setter function. When parsing the config file we also break
  up anything after the config name into multiple arguments to the setter function.

Interface changes:
- A side effect of the above interface is that the `bind` argument in the config file can
  be empty (no argument at all) this is treated the same as passing an single empty
  string argument (same as `save` already used to work).
- Support rewrite and setting `watchdog-period` from config file (was only supported
  by the CONFIG command till now).
- Another side effect is that the `save T X` config argument now supports multiple
  Time-Changes pairs in a single line like its `CONFIG SET` counterpart. So in the
  config file you can either do:
  ```
  save 3600 1
  save 600 10
  ```
  or do
  ```
  save 3600 1 600 10
  ```

Co-authored-by: Bjorn Svensson <bjorn.a.svensson@est.tech>
This commit is contained in:
yoav-steinberg 2021-11-07 13:40:08 +02:00 committed by GitHub
parent ddb508c0a2
commit 79ac57561f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 368 additions and 420 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2040,43 +2040,33 @@ void watchdogScheduleSignal(int period) {
it.it_interval.tv_usec = 0; it.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &it, NULL); setitimer(ITIMER_REAL, &it, NULL);
} }
void applyWatchdogPeriod() {
struct sigaction act;
/* Enable the software watchdog with the specified period in milliseconds. */ /* Disable watchdog when period is 0 */
void enableWatchdog(int period) {
int min_period;
if (server.watchdog_period == 0) { if (server.watchdog_period == 0) {
struct sigaction act; watchdogScheduleSignal(0); /* Stop the current timer. */
/* Watchdog was actually disabled, so we have to setup the signal /* Set the signal handler to SIG_IGN, this will also remove pending
* handler. */ * signals from the queue. */
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_handler = SIG_IGN;
sigaction(SIGALRM, &act, NULL);
} else {
/* Setup the signal handler. */
sigemptyset(&act.sa_mask); sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO; act.sa_flags = SA_SIGINFO;
act.sa_sigaction = watchdogSignalHandler; act.sa_sigaction = watchdogSignalHandler;
sigaction(SIGALRM, &act, NULL); sigaction(SIGALRM, &act, NULL);
/* If the configured period is smaller than twice the timer period, it is
* too short for the software watchdog to work reliably. Fix it now
* if needed. */
int min_period = (1000/server.hz)*2;
if (server.watchdog_period < min_period) server.watchdog_period = min_period;
watchdogScheduleSignal(server.watchdog_period); /* Adjust the current timer. */
} }
/* If the configured period is smaller than twice the timer period, it is
* too short for the software watchdog to work reliably. Fix it now
* if needed. */
min_period = (1000/server.hz)*2;
if (period < min_period) period = min_period;
watchdogScheduleSignal(period); /* Adjust the current timer. */
server.watchdog_period = period;
}
/* Disable the software watchdog. */
void disableWatchdog(void) {
struct sigaction act;
if (server.watchdog_period == 0) return; /* Already disabled. */
watchdogScheduleSignal(0); /* Stop the current timer. */
/* Set the signal handler to SIG_IGN, this will also remove pending
* signals from the queue. */
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_handler = SIG_IGN;
sigaction(SIGALRM, &act, NULL);
server.watchdog_period = 0;
} }
/* Positive input is sleep time in microseconds. Negative input is fractions /* Positive input is sleep time in microseconds. Negative input is fractions

View File

@ -4362,6 +4362,8 @@ void initServer(void) {
/* Initialize ACL default password if it exists */ /* Initialize ACL default password if it exists */
ACLUpdateDefaultUserPassword(server.requirepass); ACLUpdateDefaultUserPassword(server.requirepass);
applyWatchdogPeriod();
} }
/* Some steps in server initialization need to be done last (after modules /* Some steps in server initialization need to be done last (after modules

View File

@ -3040,8 +3040,7 @@ sds getFullCommandName(struct redisCommand *cmd);
const char *getSafeInfoString(const char *s, size_t len, char **tmp); const char *getSafeInfoString(const char *s, size_t len, char **tmp);
sds genRedisInfoString(const char *section); sds genRedisInfoString(const char *section);
sds genModulesInfoString(sds info); sds genModulesInfoString(sds info);
void enableWatchdog(int period); void applyWatchdogPeriod();
void disableWatchdog(void);
void watchdogScheduleSignal(int period); void watchdogScheduleSignal(int period);
void serverLogHexDump(int level, char *descr, void *value, size_t len); void serverLogHexDump(int level, char *descr, void *value, size_t len);
int memtest_preserving_test(unsigned long *m, size_t bytes, int passes); int memtest_preserving_test(unsigned long *m, size_t bytes, int passes);