diff --git a/candm.h b/candm.h index 2d66997..e0d5140 100644 --- a/candm.h +++ b/candm.h @@ -103,7 +103,8 @@ #define REQ_ONOFFLINE 63 #define REQ_ADD_SOURCE 64 #define REQ_NTP_SOURCE_NAME 65 -#define N_REQUEST_TYPES 66 +#define REQ_RESET 66 +#define N_REQUEST_TYPES 67 /* Structure used to exchange timespecs independent of time_t size */ typedef struct { diff --git a/client.c b/client.c index de08be2..6f0aad2 100644 --- a/client.c +++ b/client.c @@ -1269,6 +1269,7 @@ give_help(void) "cyclelogs\0Close and re-open log files\0" "dump\0Dump all measurements to save files\0" "rekey\0Re-read keys from key file\0" + "reset\0Drop all measurements\0" "shutdown\0Stop daemon\0" "\0\0" "Client commands:\0\0" @@ -1315,7 +1316,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", + "polltarget", "quit", "refresh", "rekey", "reselect", "reselectdist", "reset", "retries", "rtcdata", "serverstats", "settime", "shutdown", "smoothing", "smoothtime", "sourcename", "sources", "sourcestats", "timeout", "tracking", "trimrtc", "waitsync", "writertc", @@ -2835,6 +2836,14 @@ process_cmd_shutdown(CMD_Request *msg, char *line) /* ================================================== */ +static void +process_cmd_reset(CMD_Request *msg, char *line) +{ + msg->command = htons(REQ_RESET); +} + +/* ================================================== */ + static int process_cmd_waitsync(char *line) { @@ -3129,6 +3138,8 @@ process_line(char *line) process_cmd_reselect(&tx_message, line); } else if (!strcmp(command, "reselectdist")) { do_normal_submit = process_cmd_reselectdist(&tx_message, line); + } else if (!strcmp(command, "reset")) { + process_cmd_reset(&tx_message, line); } else if (!strcmp(command, "retries")) { ret = process_cmd_retries(line); do_normal_submit = 0; diff --git a/cmdmon.c b/cmdmon.c index 7950e7a..908977e 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -134,6 +134,7 @@ static const char permissions[] = { PERMIT_AUTH, /* ONOFFLINE */ PERMIT_AUTH, /* ADD_SOURCE */ PERMIT_OPEN, /* NTP_SOURCE_NAME */ + PERMIT_AUTH, /* RESET */ }; /* ================================================== */ @@ -1218,6 +1219,18 @@ handle_ntp_source_name(CMD_Request *rx_message, CMD_Reply *tx_message) sizeof (tx_message->data.ntp_source_name.name)); } +/* ================================================== */ + +static void +handle_reset(CMD_Request *rx_message, CMD_Reply *tx_message) +{ + struct timespec cooked_now, now; + + SRC_ResetSources(); + SCH_GetLastEventTime(&cooked_now, NULL, &now); + LCL_NotifyExternalTimeStep(&now, &cooked_now, 0.0, 0.0); +} + /* ================================================== */ /* Read a packet and process it */ @@ -1595,6 +1608,10 @@ read_from_cmd_socket(int sock_fd, int event, void *anything) handle_ntp_source_name(&rx_message, &tx_message); break; + case REQ_RESET: + handle_reset(&rx_message, &tx_message); + break; + default: DEBUG_LOG("Unhandled command %d", rx_command); tx_message.status = htons(STT_FAILED); diff --git a/doc/chronyc.adoc b/doc/chronyc.adoc index 2a99a16..e97c66f 100644 --- a/doc/chronyc.adoc +++ b/doc/chronyc.adoc @@ -1171,6 +1171,13 @@ running. The *rekey* command causes *chronyd* to re-read the key file specified in the configuration file by the <> directive. +[[reset]]*reset*:: +The *reset* command causes *chronyd* to drop all measurements and switch to the +unsynchronised state. This command can help *chronyd* with recovery when the +measurements are known to be no longer valid or accurate, e.g. due to moving +the computer to a different network, or resuming the computer from a low-power +state (which resets the system clock). + [[shutdown]]*shutdown*:: The *shutdown* command causes *chronyd* to exit. This is equivalent to sending the process the SIGTERM signal. diff --git a/pktlength.c b/pktlength.c index 32b6f5a..911f725 100644 --- a/pktlength.c +++ b/pktlength.c @@ -123,6 +123,7 @@ static const struct request_length request_lengths[] = { REQ_LENGTH_ENTRY(ntp_source, null), /* ADD_SOURCE */ REQ_LENGTH_ENTRY(ntp_source_name, ntp_source_name), /* NTP_SOURCE_NAME */ + REQ_LENGTH_ENTRY(null, null), /* RESET */ }; static const uint16_t reply_lengths[] = { diff --git a/sources.c b/sources.c index b440d9d..2db0299 100644 --- a/sources.c +++ b/sources.c @@ -1252,6 +1252,17 @@ SRC_RemoveDumpFiles(void) /* ================================================== */ +void +SRC_ResetSources(void) +{ + int i; + + for (i = 0; i < n_sources; i++) + SRC_ResetInstance(sources[i]); +} + +/* ================================================== */ + int SRC_IsSyncPeer(SRC_Instance inst) { diff --git a/sources.h b/sources.h index c160029..75f0f23 100644 --- a/sources.h +++ b/sources.h @@ -114,6 +114,8 @@ extern void SRC_DumpSources(void); extern void SRC_ReloadSources(void); extern void SRC_RemoveDumpFiles(void); +extern void SRC_ResetSources(void); + extern int SRC_IsSyncPeer(SRC_Instance inst); extern int SRC_IsReachable(SRC_Instance inst); extern int SRC_ReadNumberOfSources(void); diff --git a/test/simulation/110-chronyc b/test/simulation/110-chronyc index bc6b232..e20cf3d 100755 --- a/test/simulation/110-chronyc +++ b/test/simulation/110-chronyc @@ -138,6 +138,7 @@ for chronyc_conf in \ "rekey" \ "reselect" \ "reselectdist 1e-3" \ + "reset" \ "settime 16:30" \ "settime 16:30:05" \ "settime Nov 21, 2015 16:30:05" \