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.
This commit is contained in:
Miroslav Lichvar 2015-08-26 14:45:36 +02:00
parent d73394dde1
commit 770db1fe02
3 changed files with 5 additions and 14 deletions

View file

@ -173,15 +173,13 @@ read_frequency(void)
static void static void
set_leap(int leap) set_leap(int leap)
{ {
int current_leap, applied; int applied;
if (TMX_GetLeap(&current_leap, &applied) < 0) { applied = 0;
if (!leap && TMX_GetLeapApplied(&applied) < 0) {
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed in set_leap"); LOG_FATAL(LOGF_SysLinux, "adjtimex() failed in set_leap");
} }
if (current_leap == leap)
return;
if (TMX_SetLeap(leap) < 0) { if (TMX_SetLeap(leap) < 0) {
LOG_FATAL(LOGF_SysLinux, "adjtimex() failed in set_leap"); LOG_FATAL(LOGF_SysLinux, "adjtimex() failed in set_leap");
} }

View file

@ -124,7 +124,7 @@ TMX_SetLeap(int leap)
} }
int int
TMX_GetLeap(int *leap, int *applied) TMX_GetLeapApplied(int *applied)
{ {
struct timex txc; struct timex txc;
int state; int state;
@ -134,13 +134,6 @@ TMX_GetLeap(int *leap, int *applied)
if (state < 0) if (state < 0)
return -1; return -1;
if (txc.status & STA_INS)
*leap = 1;
else if (txc.status & STA_DEL)
*leap = -1;
else
*leap = 0;
*applied = state == TIME_WAIT; *applied = state == TIME_WAIT;
return 0; return 0;

View file

@ -31,7 +31,7 @@ int TMX_ResetOffset(void);
int TMX_SetFrequency(double *freq, long tick); int TMX_SetFrequency(double *freq, long tick);
int TMX_GetFrequency(double *freq, long *tick); int TMX_GetFrequency(double *freq, long *tick);
int TMX_SetLeap(int leap); 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_SetSync(int sync, double est_error, double max_error);
int TMX_TestStepOffset(void); int TMX_TestStepOffset(void);
int TMX_ApplyStepOffset(double offset); int TMX_ApplyStepOffset(double offset);