diff --git a/candm.h b/candm.h index f3eb433..eceb305 100644 --- a/candm.h +++ b/candm.h @@ -88,7 +88,8 @@ #define REQ_MODIFY_MAXDELAYDEVRATIO 47 #define REQ_RESELECT 48 #define REQ_RESELECTDISTANCE 49 -#define N_REQUEST_TYPES 50 +#define REQ_MODIFY_MAKESTEP 50 +#define N_REQUEST_TYPES 51 /* Special utoken value used to log on with first exchange being the password. (This time value has long since gone by) */ @@ -187,6 +188,12 @@ typedef struct { int32_t EOR; } REQ_Modify_Maxupdateskew; +typedef struct { + int32_t limit; + Float threshold; + int32_t EOR; +} REQ_Modify_Makestep; + typedef struct { Timeval ts; int32_t EOR; @@ -362,7 +369,8 @@ typedef struct { subnets accessed and client accesses Version 6 : added padding to requests to prevent amplification attack, - changed maximum number of samples in manual list to 16 + changed maximum number of samples in manual list to 16, new commands: modify + makestep */ #define PROTO_VERSION_NUMBER 6 @@ -407,6 +415,7 @@ typedef struct { REQ_Modify_Minstratum modify_minstratum; REQ_Modify_Polltarget modify_polltarget; REQ_Modify_Maxupdateskew modify_maxupdateskew; + REQ_Modify_Makestep modify_makestep; REQ_Logon logon; REQ_Settime settime; REQ_Local local; diff --git a/chrony.texi.in b/chrony.texi.in index cb81ef1..c8f66ca 100644 --- a/chrony.texi.in +++ b/chrony.texi.in @@ -3231,7 +3231,7 @@ interface. * exit command:: Exit from chronyc * help command:: Generate help summary * local command:: Let computer be a server when it is unsynchronised -* makestep command:: Immediately correct the system clock instead of slewing +* makestep command:: Correct the system clock by stepping instead of slewing * manual command:: Enable/disable/configure options for settime * maxdelay command:: Set max measurement delay for a source * maxdelaydevratio command:: Set max measurement delay for a source as ratio to deviation @@ -3702,17 +3702,27 @@ offset, by slowing down or speeding up the clock as required. In certain situations, the system clock may be so far adrift that this slewing process would take a very long time to correct the system clock. -The @code{makestep} command can be used in this situation. It cancels -any remaining correction that was being slewed, and jumps the system -clock by the equivalent amount, making it correct immediately. +The @code{makestep} command can be used in this situation. There are two forms +of the command. The first form has no parameters. It tells @code{chronyd} to +cancel any remaining correction that was being slewed and jump the system clock +by the equivalent amount, making it correct immediately. + +The second form configures the automatic stepping, similarly to the +@code{makestep} directive (@pxref{makestep directive}). It has two parameters, +stepping threshold (in seconds) and number of future clock updates for which +will be the threshold active. This can be used with the @code{burst} command +to quickly make a new measurement and correct the clock by stepping if needed, +without waiting for @code{chronyd} to complete the measurement and update the +clock. + +@example +makestep 0.1 1 +burst 1/2 +@end example BE WARNED - certain software will be seriously affected by such jumps to the system time. (That is the reason why chronyd uses slewing normally.) - -The @code{makestep} directive in the configuration file can be used -to step the clock automatically when the adjustment is larger than a -specified threshold, see @ref{makestep directive}. @c }}} @c {{{ manual @node manual command diff --git a/client.c b/client.c index 3822dd4..2de99c0 100644 --- a/client.c +++ b/client.c @@ -1210,7 +1210,7 @@ give_help(void) printf("dump : Dump all measurements to save files\n"); printf("local off : Disable server capability for unsynchronised clock\n"); printf("local stratum : Enable server capability for unsynchronised clock\n"); - printf("makestep : Jump the time to remove any correction being slewed\n"); + printf("makestep [ ] : Correct clock by stepping\n"); printf("manual off|on|reset : Disable/enable/reset settime command and statistics\n"); printf("manual list : Show previous settime entries\n"); printf("maxdelay
: Modify maximum round-trip valid sample delay for source\n"); @@ -2230,10 +2230,25 @@ process_cmd_rekey(CMD_Request *msg, char *line) /* ================================================== */ -static void +static int process_cmd_makestep(CMD_Request *msg, char *line) { - msg->command = htons(REQ_MAKESTEP); + int limit; + double threshold; + + if (*line) { + if (sscanf(line, "%lf %d", &threshold, &limit) != 2) { + fprintf(stderr, "Bad syntax for makestep command\n"); + return 0; + } + msg->command = htons(REQ_MODIFY_MAKESTEP); + msg->data.modify_makestep.limit = htonl(limit); + msg->data.modify_makestep.threshold = UTI_FloatHostToNetwork(threshold); + } else { + msg->command = htons(REQ_MAKESTEP); + } + + return 1; } /* ================================================== */ @@ -2512,7 +2527,7 @@ process_line(char *line, int *quit) } else if (!strcmp(command, "local")) { do_normal_submit = process_cmd_local(&tx_message, line); } else if (!strcmp(command, "makestep")) { - process_cmd_makestep(&tx_message, line); + do_normal_submit = process_cmd_makestep(&tx_message, line); } else if (!strcmp(command, "manual")) { if (!strncmp(line, "list", 4)) { do_normal_submit = 0; diff --git a/cmdmon.c b/cmdmon.c index 74e1ee4..0db4f1f 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -160,7 +160,8 @@ static const char permissions[] = { PERMIT_AUTH, /* MODIFY_POLLTARGET */ PERMIT_AUTH, /* MODIFY_MAXDELAYDEVRATIO */ PERMIT_AUTH, /* RESELECT */ - PERMIT_AUTH /* RESELECTDISTANCE */ + PERMIT_AUTH, /* RESELECTDISTANCE */ + PERMIT_AUTH, /* MODIFY_MAKESTEP */ }; /* ================================================== */ @@ -908,6 +909,16 @@ handle_modify_maxupdateskew(CMD_Request *rx_message, CMD_Reply *tx_message) /* ================================================== */ +static void +handle_modify_makestep(CMD_Request *rx_message, CMD_Reply *tx_message) +{ + REF_ModifyMakestep(ntohl(rx_message->data.modify_makestep.limit), + UTI_FloatNetworkToHost(rx_message->data.modify_makestep.threshold)); + tx_message->status = htons(STT_SUCCESS); +} + +/* ================================================== */ + static void handle_settime(CMD_Request *rx_message, CMD_Reply *tx_message) { @@ -1940,6 +1951,10 @@ read_from_cmd_socket(void *anything) handle_modify_maxupdateskew(&rx_message, &tx_message); break; + case REQ_MODIFY_MAKESTEP: + handle_modify_makestep(&rx_message, &tx_message); + break; + case REQ_LOGON: /* If the log-on fails, record the reason why */ if (!issue_token) { diff --git a/pktlength.c b/pktlength.c index 03a5a7e..2bd03b0 100644 --- a/pktlength.c +++ b/pktlength.c @@ -67,6 +67,8 @@ command_unpadded_length(CMD_Request *r) return offsetof(CMD_Request, data.modify_maxdelaydevratio.EOR); case REQ_MODIFY_MAXUPDATESKEW: return offsetof(CMD_Request, data.modify_maxupdateskew.EOR); + case REQ_MODIFY_MAKESTEP: + return offsetof(CMD_Request, data.modify_makestep.EOR); case REQ_LOGON : return offsetof(CMD_Request, data.logon.EOR); case REQ_SETTIME : @@ -215,6 +217,8 @@ PKL_CommandPaddingLength(CMD_Request *r) return PADDING_LENGTH(data.modify_maxdelaydevratio.EOR, data.null.EOR); case REQ_MODIFY_MAXUPDATESKEW: return PADDING_LENGTH(data.modify_maxupdateskew.EOR, data.null.EOR); + case REQ_MODIFY_MAKESTEP: + return PADDING_LENGTH(data.modify_makestep.EOR, data.null.EOR); case REQ_LOGON: return PADDING_LENGTH(data.logon.EOR, data.null.EOR); case REQ_SETTIME: diff --git a/reference.c b/reference.c index 62489f0..0103c38 100644 --- a/reference.c +++ b/reference.c @@ -1125,6 +1125,15 @@ REF_ModifyMaxupdateskew(double new_max_update_skew) /* ================================================== */ +void +REF_ModifyMakestep(int limit, double threshold) +{ + make_step_limit = limit; + make_step_threshold = threshold; +} + +/* ================================================== */ + void REF_EnableLocal(int stratum) { diff --git a/reference.h b/reference.h index fc91840..287a4c1 100644 --- a/reference.h +++ b/reference.h @@ -157,6 +157,9 @@ extern int REF_GetOurStratum(void); /* Modify the setting for the maximum skew we are prepared to allow updates on (in ppm). */ extern void REF_ModifyMaxupdateskew(double new_max_update_skew); +/* Modify makestep settings */ +extern void REF_ModifyMakestep(int limit, double threshold); + extern void REF_EnableLocal(int stratum); extern void REF_DisableLocal(void); extern int REF_IsLocalActive(void);