From d69ac0718366995bdd50066723c746dc0f08f344 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 10 Jun 2020 11:20:43 +0200 Subject: [PATCH] cmdmon: add reload sources command Add the command which reloads the files from the directories specified by the sourcedirs directive. --- candm.h | 3 ++- client.c | 25 ++++++++++++++++++++++++- cmdmon.c | 13 +++++++++++++ doc/chrony.conf.adoc | 8 ++++++-- doc/chronyc.adoc | 5 +++++ pktlength.c | 1 + 6 files changed, 51 insertions(+), 4 deletions(-) diff --git a/candm.h b/candm.h index 6530f14..a786ae7 100644 --- a/candm.h +++ b/candm.h @@ -107,7 +107,8 @@ #define REQ_AUTH_DATA 67 #define REQ_CLIENT_ACCESSES_BY_INDEX3 68 #define REQ_SELECT_DATA 69 -#define N_REQUEST_TYPES 70 +#define REQ_RELOAD_SOURCES 70 +#define N_REQUEST_TYPES 71 /* Structure used to exchange timespecs independent of time_t size */ typedef struct { diff --git a/client.c b/client.c index 6a9ef18..f6652ba 100644 --- a/client.c +++ b/client.c @@ -1234,6 +1234,7 @@ give_help(void) "\0according to network configuration\0" "polltarget
\0Modify poll target\0" "refresh\0Refresh IP addresses\0" + "reload sources\0Re-read *.sources files\0" "sourcename
\0Display original name\0" "\0\0" "Manual time input:\0\0" @@ -1301,6 +1302,7 @@ enum { TAB_COMPLETE_BASE_CMDS, TAB_COMPLETE_ADD_OPTS, TAB_COMPLETE_MANUAL_OPTS, + TAB_COMPLETE_RELOAD_OPTS, TAB_COMPLETE_RESET_OPTS, TAB_COMPLETE_SOURCES_OPTS, TAB_COMPLETE_SOURCESTATS_OPTS, @@ -1321,7 +1323,7 @@ command_name_generator(const char *text, int state) "deny", "dns", "dump", "exit", "help", "keygen", "local", "makestep", "manual", "maxdelay", "maxdelaydevratio", "maxdelayratio", "maxpoll", "maxupdateskew", "minpoll", "minstratum", "ntpdata", "offline", "online", "onoffline", - "polltarget", "quit", "refresh", "rekey", "reselect", "reselectdist", "reset", + "polltarget", "quit", "refresh", "rekey", "reload", "reselect", "reselectdist", "reset", "retries", "rtcdata", "selectdata", "serverstats", "settime", "shutdown", "smoothing", "smoothtime", "sourcename", "sources", "sourcestats", "timeout", "tracking", "trimrtc", "waitsync", "writertc", @@ -1330,12 +1332,14 @@ command_name_generator(const char *text, int state) const char *add_options[] = { "peer", "pool", "server", NULL }; const char *manual_options[] = { "on", "off", "delete", "list", "reset", NULL }; const char *reset_options[] = { "sources", NULL }; + const char *reload_options[] = { "sources", NULL }; const char *common_source_options[] = { "-a", "-v", NULL }; static int list_index, len; names[TAB_COMPLETE_BASE_CMDS] = base_commands; names[TAB_COMPLETE_ADD_OPTS] = add_options; names[TAB_COMPLETE_MANUAL_OPTS] = manual_options; + names[TAB_COMPLETE_RELOAD_OPTS] = reload_options; names[TAB_COMPLETE_RESET_OPTS] = reset_options; names[TAB_COMPLETE_AUTHDATA_OPTS] = common_source_options; names[TAB_COMPLETE_SELECTDATA_OPTS] = common_source_options; @@ -1372,6 +1376,8 @@ command_name_completion(const char *text, int start, int end) tab_complete_index = TAB_COMPLETE_AUTHDATA_OPTS; } else if (!strcmp(first, "manual ")) { tab_complete_index = TAB_COMPLETE_MANUAL_OPTS; + } else if (!strcmp(first, "reload ")) { + tab_complete_index = TAB_COMPLETE_RELOAD_OPTS; } else if (!strcmp(first, "reset ")) { tab_complete_index = TAB_COMPLETE_RESET_OPTS; } else if (!strcmp(first, "selectdata ")) { @@ -3043,6 +3049,21 @@ process_cmd_shutdown(CMD_Request *msg, char *line) /* ================================================== */ +static int +process_cmd_reload(CMD_Request *msg, char *line) +{ + if (!strcmp(line, "sources")) { + msg->command = htons(REQ_RELOAD_SOURCES); + } else { + LOG(LOGS_ERR, "Invalid syntax for reload command"); + return 0; + } + + return 1; +} + +/* ================================================== */ + static int process_cmd_reset(CMD_Request *msg, char *line) { @@ -3351,6 +3372,8 @@ process_line(char *line) process_cmd_refresh(&tx_message, line); } else if (!strcmp(command, "rekey")) { process_cmd_rekey(&tx_message, line); + } else if (!strcmp(command, "reload")) { + do_normal_submit = process_cmd_reload(&tx_message, line); } else if (!strcmp(command, "reselect")) { process_cmd_reselect(&tx_message, line); } else if (!strcmp(command, "reselectdist")) { diff --git a/cmdmon.c b/cmdmon.c index ee6a25d..bdaf711 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -139,6 +139,7 @@ static const char permissions[] = { PERMIT_AUTH, /* AUTH_DATA */ PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX3 */ PERMIT_AUTH, /* SELECT_DATA */ + PERMIT_AUTH, /* RELOAD_SOURCES */ }; /* ================================================== */ @@ -1232,6 +1233,14 @@ handle_ntp_source_name(CMD_Request *rx_message, CMD_Reply *tx_message) /* ================================================== */ +static void +handle_reload_sources(CMD_Request *rx_message, CMD_Reply *tx_message) +{ + CNF_ReloadSources(); +} + +/* ================================================== */ + static void handle_reset_sources(CMD_Request *rx_message, CMD_Reply *tx_message) { @@ -1710,6 +1719,10 @@ read_from_cmd_socket(int sock_fd, int event, void *anything) handle_select_data(&rx_message, &tx_message); break; + case REQ_RELOAD_SOURCES: + handle_reload_sources(&rx_message, &tx_message); + break; + default: DEBUG_LOG("Unhandled command %d", rx_command); tx_message.status = htons(STT_FAILED); diff --git a/doc/chrony.conf.adoc b/doc/chrony.conf.adoc index a3c4321..b038629 100644 --- a/doc/chrony.conf.adoc +++ b/doc/chrony.conf.adoc @@ -2152,8 +2152,12 @@ confdirs @SYSCONFDIR@/chrony.d /var/run/chrony.d /usr/lib/chrony.d [[sourcedirs]]*sourcedirs* _directory_...:: The *sourcedirs* directive is identical to the *confdirs* directive, except the -configuration files have the _.sources_ suffix and they can only specify NTP -sources (i.e. use the *server*, *pool*, and *peer* directive). +configuration files have the _.sources_ suffix, they can only specify NTP +sources (i.e. use the *server*, *pool*, and *peer* directive), and can be +reloaded by the <> command in +*chronyc*. It is particularly useful with dynamic sources like NTP servers +received from a DHCP server, which can be written to a file specific to the +network interface by a networking script. + An example of the directive is: + diff --git a/doc/chronyc.adoc b/doc/chronyc.adoc index 3e32f13..eb7db63 100644 --- a/doc/chronyc.adoc +++ b/doc/chronyc.adoc @@ -928,6 +928,11 @@ Sources that stop responding will be replaced with newly resolved addresses automatically after 8 polling intervals, but this command can still be useful to replace them immediately and not wait until they are marked as unreachable. +[[reload]]*reload* *sources*:: +The *reload sources* command causes *chronyd* to re-read all _*.sources_ files +from the directories specified by the +<> directive. + [[sourcename]]*sourcename* _address_:: The *sourcename* command prints the original hostname or address that was specified for an NTP source in the configuration file, or the *add* command. diff --git a/pktlength.c b/pktlength.c index bc0055f..2547689 100644 --- a/pktlength.c +++ b/pktlength.c @@ -127,6 +127,7 @@ static const struct request_length request_lengths[] = { REQ_LENGTH_ENTRY(client_accesses_by_index, client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX3 */ REQ_LENGTH_ENTRY(select_data, select_data), /* SELECT_DATA */ + REQ_LENGTH_ENTRY(null, null), /* RELOAD_SOURCES */ }; static const uint16_t reply_lengths[] = {