มีสองวิธีในการทำเช่นนี้
หากคอนเทนเนอร์ที่คุณใช้งานมีการใช้งาน systemd เต็มรูปแบบ ดังนั้น วันที่เวลา
โปรแกรมสามารถแจ้งให้คุณทราบว่าโฮสต์ซิงโครไนซ์หรือไม่
วิธีจัดการภายในคือผ่าน dbus ซึ่งพูดกับ systemd-หมดเวลา
ภูต สิ่งที่กำลังทำอยู่คือการเรียกระบบ: adjtimex
ซึ่งเป็นไปได้ที่จะได้รับข้อมูลกลับเพื่อระบุสถานะปัจจุบันของการปรับในเคอร์เนล (ถ้ามี) ที่กำลังดำเนินการอยู่
ดังนั้น วิธีที่สองในการดำเนินการนี้ด้วยตัวเองโดยไม่ต้องดำเนินการอย่างเต็มรูปแบบคือการใช้ adjtimex()
การโทรของระบบ
เคอร์เนลไม่ต้องการให้มีการข้ามเวลาในการรายงานเวลา (หรือแย่กว่านั้นคือเวลาเดินทางย้อนกลับ) เนื่องจากมันใช้การเบ้ในเวลาซึ่งในช่วงเวลาไม่กี่ชั่วโมงจะแก้ไขเวลาของระบบ (เสร็จแล้ว โดยเพิ่มหรือหน่วงเวลาไม่กี่มิลลิวินาทีต่อวินาทีจนกว่าการปรับจะเสร็จสมบูรณ์)
เดอะ adjtimex
โดยทั่วไปแล้วการเรียกระบบจะใช้โดยระบบ NTP เพื่อเปลี่ยนความเอียงปัจจุบันที่นาฬิกาเผชิญอยู่เพื่อให้ซิงโครไนซ์อย่างถูกต้องกับแหล่งสัญญาณนาฬิกาจริง -- แต่ นอกจากนี้ยังสามารถใช้เพื่อดึงสถานะปัจจุบันของการเอียงของแหล่งสัญญาณนาฬิกา ดังนั้นจึงช่วยให้คุณสามารถมองเข้าไปในแนวคิดของเมล็ดพืชว่ากำลังทำการซิงค์อะไรอยู่ (ถ้ามี)
หน้าคนสำหรับ adjtimex
ให้ส่วนที่น่าสนใจสองสามส่วนที่เกี่ยวข้องกับสิ่งที่คุณถาม:
ฟิลด์ buf.status เป็นบิตมาสก์ที่ใช้เพื่อตั้งค่าและ/หรือดึงสถานะบิตที่เกี่ยวข้องกับการนำ NTP ไปใช้ บางส่วนในหน้ากาก
มีทั้งแบบอ่านได้และตั้งค่าได้ ในขณะที่แบบอื่นเป็นแบบอ่านอย่างเดียว
...
STA_UNSYNC (อ่าน-เขียน)
นาฬิกาไม่ตรงกัน
และ
มูลค่าผลตอบแทน
เมื่อสำเร็จ adjtimex() และ ntp_adjtime() จะคืนสถานะนาฬิกา นั่นคือหนึ่งในค่าต่อไปนี้:
...
TIME_ERROR นาฬิการะบบไม่ซิงโครไนซ์กับเซิร์ฟเวอร์ที่เชื่อถือได้ ค่านี้จะถูกส่งกลับเมื่อข้อใดข้อหนึ่งต่อไปนี้เป็นจริง:
* ตั้งค่า STA_UNSYNC หรือ STA_CLOCKERR อย่างใดอย่างหนึ่ง
* STA_PPSSIGNAL ชัดเจนและตั้งค่า STA_PPSFREQ หรือ STA_PPSTIME อย่างใดอย่างหนึ่ง
* ตั้งค่า STA_PPSTIME และ STA_PPSJITTER แล้ว
* มีการตั้งค่า STA_PPSFREQ และ STA_PPSWANDER หรือ STA_PPSJITTER อย่างใดอย่างหนึ่ง
ชื่อสัญลักษณ์ TIME_BAD เป็นคำพ้องความหมายสำหรับ TIME_ERROR ซึ่งจัดเตรียมไว้สำหรับความเข้ากันได้แบบย้อนหลัง
ดังนั้น หากคุณไม่มีคอนเทนเนอร์ที่สมบูรณ์ คุณก็ยังได้รับข้อมูลนี้อยู่ ฉันเขียนโปรแกรมง่าย ๆ ที่จะดึงสถานะของเมล็ดที่เอียงผ่าน adjtimex
ในซีคุณสามารถรวบรวมได้เช่น gcc -o timex timex.c
#รวม <stdio.h>
#รวม <stdlib.h>
#รวม <unistd.h>
#รวม <errno.h>
#รวม <string.h>
#รวม <sys/timex.h>
/* เขียนสำหรับ https://serverfault.com/questions/1077601/how-to-check-whether-the-system-time-is-synchronised-to-ntp-server-without-knowi */
เป็นโมฆะ test_status(
int เซนต์)
{
ถ้า (st & STA_PLL)
printf("เฟสล็อกลูป\n");
ถ้า (เซนต์ & STA_PPSFREQ)
printf("ชีพจรต่อความถี่ความถี่\n");
ถ้า (เซนต์ & STA_FLL)
printf("วินัยเวลา PPS\n");
ถ้า (เซนต์ & STA_INS)
printf("แทรกอธิกวินาทีและสิ้นวัน\n");
ถ้า (เซนต์ & STA_DEL)
printf("ลบอธิกวินาทีและสิ้นวัน\n");
ถ้า (st & STA_UNSYNC)
printf("นาฬิกาไม่ตรงกัน\n");
ถ้า (เซนต์ & STA_FREQHOLD)
printf("ความถี่ค้าง\n");
ถ้า (เซนต์ & STA_PPSSIGNAL)
printf("มีสัญญาณ PPS ที่ถูกต้อง\n");
ถ้า (เซนต์ & STA_PPSJITTER)
printf("เกินสัญญาณ PPS กระวนกระวายใจ\n");
ถ้า (เซนต์ & STA_PPSWANDER)
printf("สัญญาณ PPS เกิน\n");
ถ้า (เซนต์ & STA_PPSERROR)
printf("ข้อผิดพลาดในการปรับเทียบสัญญาณ PPS\n");
ถ้า (เซนต์ & STA_CLOCKERR)
printf("ความผิดพลาดของฮาร์ดแวร์นาฬิกา\n");
ถ้า (เซนต์ & STA_NANO)
printf("ความละเอียดระดับนาโนวินาที\n");
อื่น
printf("ความละเอียดไมโครวินาที\n");
ถ้า (เซนต์ & STA_MODE)
printf("ความถี่ล็อคลูป\n");
อื่น
printf("เฟสล็อคลูป\n");
}
int หลัก () {
โครงสร้าง timex tx = {};
tx.modes = ADJ_OFFSET_SS_READ;
int err = adjtimex(&tx);
สวิตช์ (ผิดพลาด) {
กรณี -1:
printf("เวลาผิดพลาด: %s\n", strerror(errno));
หยุดพัก;
กรณี TIME_WAIT:
printf("ใส่/ลบ Leap วินาทีเสร็จ\n");
หยุดพัก;
กรณี TIME_INS:
printf("อธิกวินาทีที่จะเพิ่มในวัน UTC ถัดไป\n");
หยุดพัก;
กรณี TIME_DEL:
printf("อธิกวินาทีจะถูกลบในวัน UTC ถัดไป\n");
หยุดพัก;
กรณี TIME_OOP:
printf("กำลังแทรก Leap วินาที\n");
หยุดพัก;
กรณี TIME_ERROR:
printf("เวลารับผิดพลาด\n");
หยุดพัก;
กรณี TIME_OK:
printf("เวลาตกลง\n");
หยุดพัก;
ค่าเริ่มต้น:
printf("ค่าเริ่มต้นของเวลา: %x (%d)\n", err, err);
หยุดพัก;
}
test_status (tx.status);
ทางออก (0);
}
ทำงานบนระบบที่ไม่ได้ซิงโครไนซ์:
$ ./timex
เกิดข้อผิดพลาดในการหาเวลา
นาฬิกาไม่ซิงโครไนซ์
ความละเอียดระดับไมโครวินาที
เฟสล็อคลูป
ทำงานในคอนเทนเนอร์บนโฮสต์เดียวกันที่ไม่ได้ซิงโครไนซ์:
# พ็อดแมนรัน -v /tmp/timex/timex:/timex docker.io/gammabytehosting/rockylinux /timex
เกิดข้อผิดพลาดในการหาเวลา
นาฬิกาไม่ซิงโครไนซ์
ความละเอียดระดับไมโครวินาที
เฟสล็อคลูป
การตั้งเวลาในระบบโฮสต์ที่จะซิงโครไนซ์:
# systemctl เริ่ม chronyd
# แหล่งที่มา chronyc
210 จำนวนแหล่งที่มา = 9
ชื่อ MS/ที่อยู่ IP Stratum Poll ถึง LastRx ตัวอย่างสุดท้าย
================================================== =============================
^* _เกตเวย์ 2 6 7 1 +5568ns[ -720ms] +/- 32ms
# ./timex
เวลาตกลง
ความละเอียดระดับไมโครวินาที
เฟสล็อคลูป
ทำการตรวจสอบทางโปรแกรมเดียวกันในคอนเทนเนอร์บนโฮสต์เดียวกัน:
# พ็อดแมนรัน -v /tmp/timex/timex:/timex docker.io/gammabytehosting/rockylinux /timex
เวลาตกลง
ความละเอียดระดับไมโครวินาที
เฟสล็อคลูป
อาจมีปัญหากับเนมสเปซเวลาที่ฉันยังไม่ได้ทดสอบ (แม้ว่ามันจะใหม่มากก็ตาม) เพื่อดูว่าแตกต่างหรือให้เกียรติ adjtimex
ในบริบทที่แยกต่างหาก (ดู ผู้ชาย 7 time_namespaces
) แต่จากที่ฉันได้อ่านมา มันน่าจะยังใช้ได้อยู่ -- ฉันจะปล่อยให้คุณตัดสินใจเอง