From: Miroslav Lichvar Date: Wed, 26 Aug 2015 12:45:36 +0000 (+0200) Subject: sys_linux: always call TMX_SetLeap() in set_leap() X-Git-Tag: 2.2-pre1~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=770db1fe02b775f0ef1da8dad79ef26e7af01c2b;p=thirdparty%2Fchrony.git sys_linux: always call TMX_SetLeap() in set_leap() The optimization avoiding unnecessary setting of the kernel leap status can cause a problem when something outside chronyd sets the status to the new expected value. There will be no TMX_SetLeap() call which would update the saved status and the kernel status will be overwritten with the old (incorrect) value in a later TMX_*() call. Always call TMX_SetLeap() to save the new value and for the log message selection just check if a leap second has been applied. --- diff --git a/sys_linux.c b/sys_linux.c index d1849ca9..c3150156 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -173,15 +173,13 @@ read_frequency(void) static void set_leap(int leap) { - int current_leap, applied; + int applied; - if (TMX_GetLeap(¤t_leap, &applied) < 0) { + applied = 0; + if (!leap && TMX_GetLeapApplied(&applied) < 0) { LOG_FATAL(LOGF_SysLinux, "adjtimex() failed in set_leap"); } - if (current_leap == leap) - return; - if (TMX_SetLeap(leap) < 0) { LOG_FATAL(LOGF_SysLinux, "adjtimex() failed in set_leap"); } diff --git a/wrap_adjtimex.c b/wrap_adjtimex.c index ce6f2679..b5437185 100644 --- a/wrap_adjtimex.c +++ b/wrap_adjtimex.c @@ -124,7 +124,7 @@ TMX_SetLeap(int leap) } int -TMX_GetLeap(int *leap, int *applied) +TMX_GetLeapApplied(int *applied) { struct timex txc; int state; @@ -134,13 +134,6 @@ TMX_GetLeap(int *leap, int *applied) if (state < 0) return -1; - if (txc.status & STA_INS) - *leap = 1; - else if (txc.status & STA_DEL) - *leap = -1; - else - *leap = 0; - *applied = state == TIME_WAIT; return 0; diff --git a/wrap_adjtimex.h b/wrap_adjtimex.h index 217d0608..97d4164a 100644 --- a/wrap_adjtimex.h +++ b/wrap_adjtimex.h @@ -31,7 +31,7 @@ int TMX_ResetOffset(void); int TMX_SetFrequency(double *freq, long tick); int TMX_GetFrequency(double *freq, long *tick); int TMX_SetLeap(int leap); -int TMX_GetLeap(int *leap, int *applied); +int TMX_GetLeapApplied(int *applied); int TMX_SetSync(int sync, double est_error, double max_error); int TMX_TestStepOffset(void); int TMX_ApplyStepOffset(double offset);