From 513e65900c3db6e05ff7a98cfe02d7d253d76bea Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Mon, 8 Dec 2014 17:54:08 +0100 Subject: [PATCH] client: add second form of makestep command The second form configures the automatic stepping, similarly to the 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 burst command to quickly make a new measurement and correct the clock by stepping if needed, without waiting for chronyd to complete the measurement and update the clock. --- candm.h | 13 +++++++++++-- chrony.texi.in | 26 ++++++++++++++++++-------- client.c | 23 +++++++++++++++++++---- cmdmon.c | 17 ++++++++++++++++- pktlength.c | 4 ++++ reference.c | 9 +++++++++ reference.h | 3 +++ 7 files changed, 80 insertions(+), 15 deletions(-) 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);