Có hai cách để làm điều này.
Nếu vùng chứa bạn đang chạy có triển khai systemd đầy đủ, thì timedatectl
chương trình có thể thông báo cho bạn nếu máy chủ được đồng bộ hóa hay không.
Cách mà điều này được quản lý nội bộ là thông qua dbus nói với systemd-thời gian
yêu tinh. Những gì nó đang làm là thực hiện một cuộc gọi hệ thống: adjtimex
từ đó có thể lấy lại dữ liệu cho biết trạng thái hiện tại của việc điều chỉnh trong kernel (nếu có) đang được thực hiện.
Do đó, cách thứ hai để tự làm điều này mà không cần triển khai đầy đủ là sử dụng adjtimex()
cuộc gọi hệ thống.
Hạt nhân không muốn thời gian nhảy vọt trong báo cáo thời gian của nó (hoặc tệ hơn là thời gian quay ngược lại) vì vậy nó thực hiện một sai lệch về thời gian mà trong vài giờ sẽ điều chỉnh thời gian của hệ thống (xong rồi bằng cách thêm hoặc trì hoãn vài mili giây trên giây cho đến khi điều chỉnh hoàn tất).
Các adjtimex
cuộc gọi hệ thống thường được các hệ thống NTP sử dụng để thay đổi độ lệch hiện tại mà đồng hồ đang phải đối mặt để đồng bộ hóa chính xác với nguồn đồng hồ thực -- nhưng nó cũng có thể được sử dụng để lấy trạng thái hiện tại của độ lệch của nguồn đồng hồ. Do đó, nó cung cấp cho bạn khả năng xem qua ý tưởng của nhân về quá trình đồng bộ hóa đang được thực hiện (nếu có).
trang người đàn ông cho adjtimex
cung cấp một vài phần thú vị liên quan đến những gì bạn đang hỏi:
Trường buf.status là một mặt nạ bit được sử dụng để đặt và/hoặc truy xuất các bit trạng thái liên quan đến việc triển khai NTP. Một số bit trong mặt nạ
đều có thể đọc được và có thể cài đặt được, trong khi những cái khác là chỉ đọc.
...
STA_UNSYNC (đọc-ghi)
Đồng hồ không được đồng bộ hóa.
và
GIÁ TRỊ TRẢ LẠI
Khi thành công, adjtimex() và ntp_adjtime() trả về trạng thái đồng hồ; nghĩa là, một trong các giá trị sau:
...
TIME_ERROR Đồng hồ hệ thống không được đồng bộ hóa với máy chủ đáng tin cậy. Giá trị này được trả về khi bất kỳ điều nào sau đây đúng:
* Đã đặt STA_UNSYNC hoặc STA_CLOCKERR.
* STA_PPSSIGNAL bị xóa và STA_PPSFREQ hoặc STA_PPSTIME được đặt.
* STA_PPSTIME và STA_PPSJITTER đều được thiết lập.
* STA_PPSFREQ được đặt và STA_PPSWANDER hoặc STA_PPSJITTER được đặt.
Tên tượng trưng TIME_BAD là từ đồng nghĩa với TIME_ERROR, được cung cấp để tương thích ngược.
Như vậy, nếu bạn không có vùng chứa chính thức, bạn vẫn có thể lấy dữ liệu này. Tôi đã viết một chương trình đơn giản sẽ tìm nạp trạng thái của các nhân bị lệch thông qua adjtimex
trong CBạn có thể biên dịch nó chẳng hạn gcc -o timex timex.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/timex.h>
/* Viết cho https://serverfault.com/questions/1077601/how-to-check-whether-the-system-time-is-synchronised-to-ntp-server-without-knowi */
làm mất hiệu lực test_status(
số nguyên)
{
nếu (st & STA_PLL)
printf("Vòng khóa pha\n");
nếu (st & STA_PPSFREQ)
printf("Tần số xung trên giây\n");
nếu (st & STA_FLL)
printf("Kỷ luật thời gian PPS\n");
nếu (st & STA_INS)
printf("Chèn giây nhuận và ngày cuối\n");
nếu (st & STA_DEL)
printf("Xóa giây nhuận và ngày cuối\n");
nếu (st & STA_UNSYNC)
printf("Chưa đồng bộ\n");
nếu (st & STA_FREQHOLD)
printf("Tần số giữ\n");
nếu (st & STA_PPSSIGNAL)
printf("Có tín hiệu PPS hợp lệ\n");
nếu (st & STA_PPSJITTER)
printf("Vượt quá jitter tín hiệu PPS\n");
nếu (st & STA_PPSWANDER)
printf("Vượt quá trôi dạt tín hiệu PPS\n");
nếu (st & STA_PPSERROR)
printf("Lỗi cân chỉnh tín hiệu PPS\n");
nếu (st & STA_CLOCKERR)
printf("Lỗi phần cứng đồng hồ\n");
nếu (st & STA_NANO)
printf("Độ phân giải nano giây\n");
khác
printf("Độ phân giải micro giây\n");
nếu (st & STA_MODE)
printf("Vòng lặp bị khóa tần số\n");
khác
printf("Vòng khóa pha\n");
}
int main() {
cấu trúc thời gian tx = {};
tx.modes = ADJ_OFFSET_SS_READ;
int err = adjtimex(&tx);
công tắc (lỗi) {
trường hợp 1:
printf("Lỗi thời gian: %s\n", strerror(errno));
nghỉ;
trường hợp TIME_WAIT:
printf("\n");
nghỉ;
trường hợp TIME_INS:
printf("Giây nhuận sẽ được thêm vào ngày UTC tiếp theo\n");
nghỉ;
trường hợp TIME_DEL:
printf("Giây nhuận sẽ bị xóa vào ngày UTC tiếp theo\n");
nghỉ;
trường hợp TIME_OOP:
printf("Đang chèn bước nhảy thứ hai\n");
nghỉ;
trường hợp TIME_ERROR:
printf("Lỗi nhận thời gian\n");
nghỉ;
trường hợp TIME_OK:
printf("Thời gian OK\n");
nghỉ;
mặc định:
printf("Thời gian mặc định: %x (%d)\n", err, err);
nghỉ;
}
test_status(tx.status);
thoát (0);
}
Chạy trên một hệ thống không được đồng bộ hóa:
$ ./thời gian
Lỗi nhận thời gian
Đồng hồ không được đồng bộ hóa
độ phân giải micro giây
Giai đoạn khóa vòng lặp
Chạy trong một vùng chứa trên cùng một máy chủ không được đồng bộ hóa:
# podman run -v /tmp/timex/timex:/timex docker.io/gammabytehosting/rockylinux /timex
Lỗi nhận thời gian
Đồng hồ không được đồng bộ hóa
độ phân giải micro giây
Giai đoạn khóa vòng lặp
Đặt thời gian trong hệ thống máy chủ được đồng bộ hóa:
# systemctl bắt đầu chronyd
# nguồn chronyc
210 Số nguồn = 9
Tên MS/địa chỉ IP Stratum Poll Reach LastRx Mẫu cuối cùng
================================================================= ============================================
^* _gateway 2 6 7 1 +5568ns[ -720ms] +/- 32ms
# ./timex
Thời gian OK
độ phân giải micro giây
Giai đoạn khóa vòng lặp
Thực hiện kiểm tra theo chương trình tương tự trong vùng chứa trên cùng một máy chủ:
# podman run -v /tmp/timex/timex:/timex docker.io/gammabytehosting/rockylinux /timex
Thời gian OK
độ phân giải micro giây
Giai đoạn khóa vòng lặp
Có khả năng xảy ra một số vấn đề với các không gian tên thời gian mà tôi chưa kiểm tra (mặc dù chúng thực sự rất mới) để xem liệu chúng có khác biệt hay tôn trọng không adjtimex
trong một bối cảnh riêng biệt (xem người đàn ông 7 time_namespaces
) nhưng từ những gì tôi đã đọc, nó có thể vẫn hoạt động - tôi sẽ để điều đó cho bạn xác định.