최근에 Prometheus에서 NTP Sync fail 알람을 계속 띄워서 분석하기 위해 공부했던 내용을 기록해 보았습니다.
목차
- NTPv4(RFC 5905)의 NTP 아키텍쳐, 알고리즘, 패킷 헤더
- Leap Second와 ntpd vs chronyd
- chronyd와 timedatectl, node-exporter - NTP sync 상태를 어떻게 알 수 있을까?
- timex 구조체와 adjtimex 시스템 콜
NTP는 시스템의 시계를 동기화하기 위한 프로토콜(NTPv4)로 RFC5905에 정의되어 있습니다. 서버의 시간은 오실레이터의 클럭 카운트로 계산되며, 이는 저항에 의한 온도 상승에 영향을 받아 일정하지 않을 수 있습니다. 그리고 서버에 문제가 생겼을 때 발생하는 알람이나 로그는 시스템 시계를 기준으로 기록되므로 서버 간에 시간이 맞지 않으면 트러블슈팅에 혼동을 줄 수 있습니다.
- NTP Architecture
NTP는 시각의 정확도와 신뢰도에 따라 Stratum이라는 값을 기준으로 Hierarchy를 가집니다.
- Stratum 0 : 원자시계나 GPS와 같이 정밀한 시계로 네트워크 망에서 가장 근원이 되는 referece clock입니다. NTP 서버 자체로는 Stratum 0가 될 수 없기 때문에, 서버와 클라이언트 간 주고받은 NTP 패킷에서 Stratum 0는 'unspecified or invalid'로 정의됩니다.
- Stratum 1 : Stratum 0에 다이렉트로 연결되어 동기화된 서버로 NTP에서 최상위 계층이 됩니다.(primary server)
- Stratum 2 ~ 15 : 네트워크 망을 통해 상위 NTP 서버와 동기화된 서버입니다. 서버에 Peer가 되어 동기화된 클라이언트 들은 Stratum 값이 1씩 증가합니다. (secondary server or client)
- Stratum 16 : NTPv4 기준 Stratum의 최댓값이며 'unsynchrnized'를 의미합니다.
- NTP 알고리즘
NTP는 UDP 기반으로 123 포트를 통해 패킷을 주고받습니다. 시간 동기화를 원하는 클라이언트에서 먼저 자신의 Timestamp를 찍어서 서버로 전송하면, 서버는 자신의 시간과 비교해서 시간 오차(Offset)와 패킷 왕복 시간(Round-trip delay) 계산합니다. 여기서 Origin(T1), Receive(T2), Trasimit(T3), Destiniation(T4) 4개의 Timestamp가 사용됩니다. 각 Timestamp는 Server와 Client가 패킷을 보내거나 수신한 시간을 기준으로 합니다.
이렇게 계산된 Offset과 Delay 그리고 여기서 파생되어 계산되는 Dispersion, Jitter 등의 변수들을 각 알고리즘에 적용하여 Client는 가장 신뢰할 수 있는 서버를 선정하고 거기에 동기화합니다.
규격을 기준으로 자세하게 들여다보자면, NTP Client는 Clock Filter, Selection, Cluster, Combine, Clock Discipline 5개의 알고리즘을 사용합니다.
- Clock Filter 알고리즘 : Client에서 Server들로부터 수신한 데이터로 이후에 사용할 Offset, Delay, Dispersion, Jitter, Arrival time 5가지 변수를 계산합니다.
- Selection & Cluster 알고리즘 : Clock Filter 알고리즘에 의해 계산된 값으로 신뢰도가 적은 Server(Falseticker)를 걸러내고, 신뢰도가 높은 Server(truechimer 또는 survivor)에 대한 List(majority clique)를 만들고 그 중 최적의 NTP server를 골라냅니다. 신뢰도가 높다는 것은 Stratum과 Delay가 낮다는 것을 의미합니다. 만약 여기서 신뢰할 수 있는 서버가 없다면 NTP Unsync 상태가 됩니다.
- Combine 알고리즘 : Client에서 시스템 시간을 조정하기 위한 최종 Offset을 계산하며, 계산된 Offset 값에 따라 다른 동작을합니다.
* PANIC Threshold(default 1000s) < Offset
→ PANIC 상태로 간주하고 프로그램을 종료합니다.
* STEP Threshold(default 125ms) < Offset < PANIC Threshold
→ NTP 데이터에 이상이 있는것으로 간주하고 모든 NTP 연동을 초기화합니다.
* Offset < STEP Shreshold
→ 일반적인 상태(SLEW)로 NTP 서버로부터 받은 패킷의 변수를 시스템 변수로 업데이트합니다. time loop이나 clockhopping(time jump?)를 방지하기위해 offset 값이 clamp(default 100ms)보다 큰 경우에 시간 조정을 수행합니다.
- Clock Discipline 알고리즘 : adjtime() 시스템 콜을 통해 Client의 Local Clock을 조정하고, Server로 동기화를 요청하는 간격인 Polling Interval을 계산합니다.
* Dispersion : Server와 Client 간 최대 오차(Offset)입니다.
received precision + system precision + clock frequency * (T4 – T1)으로 계산됩니다.
* Jitter (Estimated error) : 최근 Offset 통계의 분산 값으로 Network의 혼잡 상태와 Timekeeping 성능에 대한 지표가 됩니다.
* Syncronization distance (Maximum error) : (Root dispersion + Root delay / 2)으로 계산되는 값으로, 시간을 동기화하기 적합한 Server인지 판단하는 기준이 됩니다.
- NTP Packet Header Variables
* 패킷을 떠서 보니 클라이언트의 Trasimit Timestamp가 1970년부터 2070년까지 아주 다양하게 찍혀 있어서 당황했네요... 찾아보니 chrony의 Default 보안 기능으로 랜덤 한 값을 찍어서 보내는 것이었네요.
- Leap Indicator : 윤초(Lead Second)에 따른 시간을 계산하기 위한 플래그입니다. 윤초란 지구 자전과 원자시계의 차이가 0.9초 이상일 때 반영되는 시간입니다.
- Version number : NTP 프로토콜 버전
- Mode : sysmmetric, client/server, broadcast 모드 3가지가 있습니다. 아래 테이블처럼 NTP Server는 모든 패킷을 Discard하며, NTP Client는 Server의 패킷만 받아들입니다.
- [Delta Time] : RFC에 정의된 필드는 아니며, Wireshark에서 계산해서 보여주는 Offset 값입니다. 클라이언트의 요청 시간과 서버의 응답시간으로 계산됩니다.
- Peer Polling Interval : 클라이언트가 NTP 메세지를 보내는 간격입니다. log2로 계산되며 Polling Interval이 6인 경우 2^6으로 64초가 됩니다. (최소 6 ~ 최대 10)
- Peer Clock Precision : log2 초 단위로 Peer의 시간 정밀도를 나타냅니다. 최초로 NTP 서비스가 동작할 때, 시스템 시간을 읽는 최소 실행 시간으로 산출됩니다. 위 패킷의 경우 4294967296에 log2를 취하면 32가 됩니다.
- Root Delay / Dispersion : Delay와 Dispersion은 Reference clock부터 Stratum을 거칠수록 축적되며, 이 축적된 값이 Root delay(또는 dispersion)입니다.
- Reference ID : Reference clock 또는 NTP server의 IP를 나타냅니다. 그러나 Stratum이 0인 경우 Client의 NTP Request 메세지의 빈도를 제어하거나 서버 자신의 상태를 나타내는 kiss code를 찍어 보낼 수 있습니다.
- Reference Timestamp : 시스템 시계가 마지막으로 업데이트된 시간입니다.
- Origin Timstamp : 클라이언트에서 NTP Req 메세지를 전송한 시간으로, Req 메세지의 Transimit Timestamp와 동일한 값입니다.
- Receive Timestamp : 서버에서 클라이언트의 NTP Req 메세지를 수신한 시간입니다.
- Trasimit Timestamp : 클라이언트 또는 서버에서 NTP 메세지를 전송한 시간입니다.
전 세계의 표준 시간인 UTC(Coordinated Universal Time)는 TAI(Temps Atomique International, 국제원자시)를 기반으로 윤초를 더하거나 빼서 지구의 자전 운동과 오차를 1초 이내로 보정합니다. 문제는 윤초에 대한 보정으로 UTC에 1초가 추가되는 경우, 즉 Stratum 0인 원자시계(TAI)와 UTC에 대한 offset이 변경되는 경우에 NTP의 시계는 갑자기 UTC와 1초의 offset을 가지게 됩니다.
여기서 갑자시 발생한 시간차에 대한 offset을 보정하기 위해 시간을 한번에 보정하는 STEP mode와 서서히 보정하는 SLEW mode, 2가지 방법이 있습니다.
그리고 SLEW mode로 동작하는 ntpd와 chrony가 1초의 offset을 보정하기위해 소요되는 시간을 비교해보면 아래 그래프처럼 됩니다.
ntpd의 경우에 polling interval 1,024초를 기준으로 1초의 offset을 정확하게 보정하기위해 약 1일정도의 시간이 소요됩니다. 반면 chronyd는 config의 maxslewrate 옵션으로 보정에 소요되는 최대 시간을 지정할 수 있으며, default로 12초가 소요됩니다.
* SLEW vs STEP
Client가 STEP mode로 운용되어 Server와의 offset을 갑자기 한 번에 맞추게 된다면, Logging과 Alarm, monitoring metric 등의 시간 혼동부터, 인증 실패와 분산 DB의 data replication error, Transaction 순서 문제 등등 여러 문제가 발생할 수 있습니다.
CLOCK_REALTIME - NTP 또는 사용자의 cli 명령어에 의해 조정될 수 있는 시간으로 대부분의 어플리케이션이 이 시간을 참조합니다. UTC를 의미합니다. (forward jump, backward jump 모두 가능)CLOCK_MONOTONIC - 시스템이 부팅 된 이후 측정되는 시간으로 사용자에 의해 조정될 수 없고, NTP에 의한 시간 조정만 가능하지만, 과거의 시간으로 조정될 수 없습니다. (forward jump 만 가능)CLOCK_TAI - 원자시이므로 윤초를 계산하지 않으며, NTP에 의해서도 조정되지 않습니다.
그렇다면 리눅스에서 시간과 관련된 어플리케이션들은 시스템 시간을 어떻게 조작하는 것 일까요?
chrony와 timedated, node-exporter 3가지 데몬으로 알아보도록 하겠습니다.
- Chrony / timedated / node-exporter
1. Chrony
Chrony는 Redhat 8 / SUSE 15 부터 ntpd를 대체하는 Default NTP 데몬입니다. /etc/chrony.conf 또는 /etc/chrony.d/*.conf 를 참조하여 실행됩니다. 아래는 chrony.conf의 default 설정이며 이는 NTPv4 규격의 Combine 알고리즘을 따라 구현되었습니다. 그리고 NTP 메세지를 주고 받으면서 산출된 통계 데이터 확인할 수도 있습니다.
# /etc/chrony.conf
...
# SLEW case의 clamp에 해당하는 값으로 offset이 threshold 값보다 크고,
# 데몬 시작 이후 최초 limit 횟수 이내의 clock update인 경우 시스템 시간을 조정합니다.
# threshold limit
makestep 0.1 3
# 데몬 시작 이후 start 횟수 만큼의 clock update 이후값으로
# offset이 1000초 (PANIC threshold)이상인 경우 ignore 값 만큼의 torealance를 주고
# 이후에도 offset이 1000초 이상인 경우 데몬을 종료합니다.
# offset start ignore
maxchange 1000 1 2
# ignore 값을 음수로 설정하면 데몬을 종료하지 않도록 합니다.
* chrony의 NTP 통계 확인 명령어
$ chronyc sources -v
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current best, '+' = combined, '-' = not combined,
| / 'x' = may be in error, '~' = too variable, '?' = unusable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* NTP Server 4 5 377 19 +1739ns[ +15us] +/- 775ms
$ chronyc sourcestats -v
.- Number of sample points in measurement set.
/ .- Number of residual runs with same sign.
| / .- Length of measurement set (time).
| | / .- Est. clock freq error (ppm).
| | | / .- Est. error in freq.
| | | | / .- Est. offset.
| | | | | | On the -.
| | | | | | samples. \
| | | | | | |
Name/IP Address NP NR Span Frequency Freq Skew Offset Std Dev
==============================================================================
NTP Server 15 8 32m -0.001 0.044 -38ns 20us
$ chronyc ntpdata
Remote address : x.x.x.x (AC32040A)
Remote port : 123
Local address : x.x.x.x (AC320406)
Leap status : Normal
Version : 4
Mode : Server
Stratum : 4
Poll interval : 6 (64 seconds)
Precision : -26 (0.000000015 seconds)
Root delay : 0.000015 seconds
Root dispersion : 0.781891 seconds
Reference ID : AC32040A ()
Reference time : Sun Jul 14 06:25:31 2023
Offset : +0.000007917 seconds
Peer delay : 0.000088382 seconds
Peer dispersion : 0.000000066 seconds
Response time : 0.000077616 seconds
Jitter asymmetry: +0.00
NTP tests : 111 111 1111
Interleaved : No
Authenticated : No
TX timestamping : Kernel
RX timestamping : Kernel
Total TX : 948
Total RX : 948
Total valid RX : 948
chrony는 sys_timex.c의 set_sync_status() 함수로 NTP sync 상태를 확인합니다.
시스템이 NTP 서버와 동기화가 되어있지 않다면 timex 구조체의 est_error(jitter)와 max_error(syncronization distance) 값에 MAX_SYNC_ERROR 값을 반영하고 timex에 STA_UNSYNC falg를 반영하여 SYS_Timex_Adjrust() 함수를 호출합니다. 반대로 이미 동기화가 되어 있었다면 현재의 jitter와 syncronization distance 값을 timex에 반영하여 SYS_Timex_Adjust() 함수를 호출합니다.
// chonry/sys_timex.c
/* Threshold for the timex maxerror when the kernel sets the UNSYNC flag */
#define MAX_SYNC_ERROR 16.0
…
static void set_sync_status(int synchronised, double est_error, double max_error) {
struct timex txc;
if (synchronised) {
if (est_error > MAX_SYNC_ERROR)
est_error = MAX_SYNC_ERROR;
if (max_error >= MAX_SYNC_ERROR) {
max_error = MAX_SYNC_ERROR;
synchronised = 0;
}
} else {
est_error = max_error = MAX_SYNC_ERROR;
}
#ifdef LINUX
/* On Linux clear the UNSYNC flag only if rtcsync is enabled */
if (!CNF_GetRtcSync())
synchronised = 0;
#endif
if (synchronised)
sys_status &= ~STA_UNSYNC;
else
sys_status |= STA_UNSYNC;
txc.modes = MOD_STATUS | MOD_ESTERROR | MOD_MAXERROR;
txc.status = sys_status;
txc.esterror = est_error * 1.0e6;
txc.maxerror = max_error * 1.0e6;
if (SYS_Timex_Adjust(&txc, 1) < 0)
;
}
그리고 SYS_Timex_Adjust() 함수는 jitter와 sync distance 값이 반영된 timex를 받아 NTP_ADJTIME() 함수로 adjtimex 시스템 콜을 호출하여 시스템 시간을 동기화하고 state를 반환합니다.
#ifdef LINUX
#define NTP_ADJTIME adjtimex
#define NTP_ADJTIME_NAME "adjtimex"
int SYS_Timex_Adjust(struct timex *txc, int ignore_error) {
int state;
...
state = NTP_ADJTIME(txc);
...
return state;
}
2. timedated (timedatectl)
timedated는 systemd에 포함된 데몬으로 D-Bus 인터페이스를 통해 TimeZone, Local Time 등을 조회하거나 직접 설정할 수 있으며, 현재 시스템이 사용하는 NTP client 데몬의 시간 동기화 여부 또한 확인할 수 있습니다.
$ timedatectl
Local time: Tue 2023-07-23 14:46:15 KST
Universal time: Tue 2023-07-23 05:46:15 UTC
RTC time: Tue 2023-07-23 05:46:15
Time zone: Asia/Seoul (KST, +0900)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
* Local time과 RTC(Real Time Clock)
리눅스에서 Local time은 커널에서 관리하는 시간으로 대부분의 어플리케이션은 Local time을 참조합니다. RTC는 메인보드의 CMOS를 의미합니다. CPU의 개입 없이 동작하며, 전원이 없어도 카운터를 통해 시간을 유지합니다.
static bool ntp_synced(void) {
struct timex txc = {};
if (adjtimex(&txc) < 0)
return false;
/* Consider the system clock synchronized if the reported maximum error is smaller than the maximum
* value (16 seconds). Ignore the STA_UNSYNC flag as it may have been set to prevent the kernel from
* touching the RTC. */
return txc.maxerror < 16000000;
}
timedated 또한 adjtimex() 함수를 통해 NTP 동기화 여부를 확인합니다.
3. node-exporter
프로메테우스의 node exporter는 timex collector를 통해 각 Node의 NTP Sync 상태에 대한 alert을 제공합니다.
node-exporter와 chrony를 함께 사용하기 위해 chrony의 config에서 rtcsync를 선언해야합니다. 그렇게 되면 chrony는 매 11분마다 Local time 값을 RTC로 복사합니다.
// release-1.4/collector/timex.go
const (
timeError = 5
staNano = 0x2000
nanoSeconds = 1000000000
microSeconds = 1000000
)
…
syncStatus: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "sync_status"),
"Is clock synchronized to a reliable server (1 = yes, 0 = no).",
nil, nil,
…
// NTP 관련 변수를 가진 timex 구조체를 선언하고 adjtimex() 시스템 콜을 호출합니다.
var timex = new(unix.Timex)
status, err := unix.Adjtimex(timex)
if status == timeError {
syncStatus = 0
} else {
syncStatus = 1
node-expoerter도 adjtimex()함수를 통해 NTP sync 정보를 받아옵니다.
- timex 구조체와 adjtimex 시스템 콜
timex 구조체는 NTP의 규격에 정의된 각 파라미터들을 변수로 가지고 있습니다. 그리고 mode의 flag(ADJ_OFFSET, ADJ_MAXERROR, ADJ_ESTERROR 등)에 따라 어떤 파라미터가 어떻게 반영될지 결정하는 듯 합니다.
/* include/uapi/linux/timex.h */
// timex 구조체
struct timex {
unsigned int modes; /* mode selector */
__kernel_long_t offset; /* time offset (usec) */
__kernel_long_t freq; /* frequency offset (scaled ppm) */
__kernel_long_t maxerror;/* maximum error (usec) */
__kernel_long_t esterror;/* estimated error (usec) */
int status; /* clock command/status */
...
struct timeval time; /* (read only, except for ADJ_SETOFFSET) */
...
};
adjtimex()에 의해 호출되는 do_adjtimex() 함수는 기존의 NTP 데이터들을 audit_ntp_data 구조체의 oldval 저장합니다. 그리고 NTP에 의해 반영된 timex의 각 변수를 process_adjtimex_modes()함수에 받아 각 mode(flag)에 맞게 ntp_update_offset(), ntp_update_frequency() 함수 등을 호출하여 커널 시간을 조정합니다. 새롭게 계산된 offset과 NTP sync 상태 등을 audit_ntp_data 구조체의 newval에 업데이트하고, 이를 timex 구조체에도 갱신하여 NTP 데몬과 node-exporter 등이 NTP sync 상태나 offset 값 등을 알 수 있도록 합니다.
// kernel/time/ntp.c
int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts, s32 *time_tai, struct audit_ntp_data *ad) {
int result;
if (txc->modes & ADJ_ADJTIME) {
...
} else {
if (txc->modes) { // 현재 NTP value들을 ad[NTP_AUDIT_Type].oldval에 저장
audit_ntp_set_old(ad, AUDIT_NTP_OFFSET, time_offset);
audit_ntp_set_old(ad, AUDIT_NTP_FREQ, time_freq);
audit_ntp_set_old(ad, AUDIT_NTP_STATUS, time_status);
audit_ntp_set_old(ad, AUDIT_NTP_TAI, *time_tai);
audit_ntp_set_old(ad, AUDIT_NTP_TICK, tick_usec);
process_adjtimex_modes(txc, time_tai); // 각 flag에 맞게 ntp_update_offset(), ntp_update_frequency()등을 호출하여
// 커널 시간을 조정하고, 그 결과에 따라 NTP sync 상태 업데이트
// NTP의 timex에 의해 조정된 값들을 ad[AUDIT_NTP_Type].newval에 저장
audit_ntp_set_new(ad, AUDIT_NTP_OFFSET, time_offset);
audit_ntp_set_new(ad, AUDIT_NTP_FREQ, time_freq);
audit_ntp_set_new(ad, AUDIT_NTP_STATUS, time_status);
audit_ntp_set_new(ad, AUDIT_NTP_TAI, *time_tai);
audit_ntp_set_new(ad, AUDIT_NTP_TICK, tick_usec);
}
...
result = time_state; /* mostly `TIME_OK' */
/* check for errors */
if (is_error_status(time_status))
result = TIME_ERROR;
// timex 구조체의 각 변수에 조정된 업데이트 된 값을 반영
txc->freq = shift_right((time_freq >> PPM_SCALE_INV_SHIFT) * PPM_SCALE_INV, NTP_SCALE_SHIFT);
txc->maxerror = time_maxerror;
txc->esterror = time_esterror;
txc->status = time_status;
txc->constant = time_constant;
txc->precision = 1;
txc->tolerance = MAXFREQ_SCALED / PPM_SCALE;
txc->tick = tick_usec;
txc->tai = *time_tai;
...
return result;
}
static inline void process_adjtimex_modes(const struct __kernel_timex *txc, s32 *time_tai) {
if (txc->modes & ADJ_STATUS)
process_adj_status(txc);
...
if (txc->modes & ADJ_MAXERROR)
time_maxerror = txc->maxerror;
if (txc->modes & ADJ_ESTERROR)
time_esterror = txc->esterror;
...
if (txc->modes & ADJ_OFFSET)
ntp_update_offset(txc->offset);
...
if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET))
ntp_update_frequency();
}
잘 못 된 정보에 대한 지적은 언제든 환영입니다.
부족한 긴 글 읽어주셔서 감사드리며 좋은 하루 되세요:)
https://datatracker.ietf.org/doc/html/rfc5905
RFC 5905: Network Time Protocol Version 4: Protocol and Algorithms Specification
The Network Time Protocol (NTP) is widely used to synchronize computer clocks in the Internet. This document describes NTP version 4 (NTPv4), which is backwards compatible with NTP version 3 (NTPv3), described in RFC 1305, as well as previous versions of t
datatracker.ietf.org
https://sookocheff.com/post/time/how-does-ntp-work/
How Does NTP Work?
The Network Time Protocol (NTP) is a system for synchronizing the clocks of hosts and clients across the Internet. NTP is a protocol intended to synchronize all computers participating in the network to within a few milliseconds of Coordinated Universal Ti
sookocheff.com
https://en.wikipedia.org/wiki/Network_Time_Protocol
Network Time Protocol - Wikipedia
From Wikipedia, the free encyclopedia Standard protocol for synchronizing time across devices Network Time ProtocolInternational standardRFC 5905Developed byDavid L. Mills, Network Time FoundationIntroduced1985 (1985) The Network Time Protocol (NTP) is a
en.wikipedia.org
https://github.com/mlichvar/chrony
GitHub - mlichvar/chrony: Mirror of git.tuxfamily.org/gitroot/chrony/chrony.git
Mirror of git.tuxfamily.org/gitroot/chrony/chrony.git - GitHub - mlichvar/chrony: Mirror of git.tuxfamily.org/gitroot/chrony/chrony.git
github.com
https://github.com/prometheus/node_exporter/blob/master/docs/TIME.md
https://www.rfc-editor.org/rfc/rfc1129.pdf
[linux] RTC, UTC, Local time 개념 정리.
RTC (real time clock, hardware clock) 전자기기에 존재하는 하드웨어 시계. 디지털 회로의 카운터에 의존하여 시간을 계산. CPU 개입없이 동작하며, 전원이 인가되지 않아도 시간을 유지함. 리눅스에서는
gomu92.tistory.com
https://developers.redhat.com/blog/2015/06/01/five-different-ways-handle-leap-seconds-ntp
Five different ways to handle leap seconds with NTP | Red Hat Developer
A leap second is an adjustment that is once in a while applied to the Coordinated Universal Time (UTC) to keep it close to the mean solar time. The concept is
developers.redhat.com
https://man7.org/linux/man-pages/man2/clock_gettime.2.html
clock_getres(2) - Linux manual page
clock_getres(2) — Linux manual page clock_getres(2) System Calls Manual clock_getres(2) NAME top clock_getres, clock_gettime, clock_settime - clock and time functions LIBRARY top Standard C library (libc, -lc), since glibc 2.17 Be
man7.org
https://www.seiko-sol.co.jp/leap-second/no-03/
セイコーの「うるう秒」対策(第3回) タイムサーバーによる「うるう秒」対策の実例 | セ
今回は、Windows、Linuxなどの主要OSの「うるう秒」動作や対策についてと、タイムサーバーシリーズによる簡単・確実な「うるう秒」対策の実例についてご紹介したいと思います。
www.seiko-sol.co.jp
https://access.redhat.com/articles/15145
Resolve Leap Second Issues in Red Hat Enterprise Linux - Red Hat Customer Portal
Red Hat has put together a comprehensive guide on the 2016 leap second issue to prepare and prevent any problems or downtime while using Red Hat Enterprise Linux.
access.redhat.com
https://stackoverflow.com/questions/13256232/how-does-ntpdate-update-the-time
How does ntpdate update the time?
I used strace on ntpdate command which calls adjtimex to adjust time. I got this: adjtimex({modes=ADJ_OFFSET|0x8000, offset=-479139, freq=0, maxerror=16000000, esterror=16000000, status=STA_UNSYNC,
stackoverflow.com
'System Engineering > Linux' 카테고리의 다른 글
[커널이야기] TCP Keepalive와 Retransmission (0) | 2023.09.26 |
---|---|
[커널이야기] TCP handshake와 TIME_WAIT 소켓 (0) | 2023.09.23 |
[커널이야기] 리눅스 더티 페이지와 I/O Throttling (0) | 2023.07.06 |
[커널이야기] 리눅스 메모리 1 - 메모리를 확인하는 방법과 slab/swap 메모리 (2) | 2023.06.15 |
[커널이야기] Load Average로 시스템 콜 추적하기 (0) | 2023.06.09 |