Saya pikir Anda ingin clock_gettime
dengan CLOCK_TAI
untuk bekerja dengan benar. Saya juga.
Kalimat penting dalam jawaban yang direferensikan adalah:"Harap perhatikan bahwa offset dari CLOCK_REALTIME diinisialisasi saat boot ke nol dan baik ntpd maupun chronyd tidak menyetelnya secara default ke nilai yang benar (saat ini 35)."
Ini mungkin masih benar, terlepas dari offset sekarang menjadi 37, tetapi ntpd terbaru setidaknya dapat dikonfigurasi untuk menyetel offset. Saya melakukan hal berikut pada mesin openSUSE:
vi /etc/ntp.conf # Add the line: leapfile /var/lib/ntp/etc/ntp.leapseconds
update-leap
service ntpd restart
less /var/log/ntp # Check for errors
Lalu clock_gettime(CLOCK_TAI, &res)
tampaknya bekerja dengan benar.
Saya pikir ntp menyetel offset menggunakan ntp_adjtime
dengan MOD_TAI
. Mencari sumber kroni dengan grep -P '(ADJ|MOD)_TAI'
tidak menemukan kecocokan, jadi sepertinya chrony belum memiliki kemampuan ini.
Anda dapat menggunakan libtai
dari djb:https://cr.yp.to/libtai.html
Apa itu?
libtai adalah pustaka untuk menyimpan dan memanipulasi tanggal dan waktu.
libtai mendukung dua skala waktu:(1) TAI64, mencakup beberapa ratus miliar tahun dengan presisi 1 detik; (2) TAI64NA, mencakup periode yang sama dengan presisi 1 attodetik. Kedua skala ditentukan dalam istilah TAI, standar waktu nyata internasional saat ini.
libtai menyediakan format internal untuk TAI64, struct tai, yang dirancang untuk manipulasi waktu cepat. Rutin tai_pack() dan tai_unpack() mengonversi antara struct tai dan format penyimpanan portabel 8-byte TAI64.libtai menyediakan format internal dan eksternal yang serupa untuk TAI64NA.
libtai menyediakan struct caldate untuk menyimpan tanggal dalam bentuk tahun-bulan-hari. Itu dapat mengonversi struct caldate, di bawah kalender Gregorian, menjadi nomor hari Julian yang dimodifikasi untuk aritmatika tanggal yang mudah.
libtai menyediakan struct caltime untuk menyimpan tanggal dan waktu kalender bersama dengan offset UTC. Itu dapat mengkonversi dari struct tai ke struct caltime inUTC, menghitung detik kabisat, untuk tampilan tanggal dan waktu yang akurat. Itu juga dapat mengkonversi kembali dari struct caltime ke struct tai untuk input pengguna. Kecepatan konversi UTC-ke-TAI keseluruhannya 100x lebih baik daripada implementasi mktime() UNIX biasa.
Versi libtai ini memerlukan sistem UNIX dengan gettimeofday(). Akan mudah untuk melakukan porting ke sistem operasi lain dengan kompiler yang mendukung aritmatika 64-bit.
Kode sumber libtai ada di domain publik.
Saat saya menjalankan chrony
bukan ntpd
yang lama , saya tidak memiliki cara otomatis untuk memperbaiki parameter kernel, jadi saya mencari alternatif.
Karena offset antara TAI dan UTC relatif konstan (berubah
Ada aplikasi pengujian untuk menyetel offset kernel di sumber kernel, di
Saya menebang aplikasi pengujian kernel sehingga yang utama menjadi:
Kemudian, untuk kasus penggunaan saya, itu hanya masalah mengekstraksi nilai yang benar dari
Semoga ini bermanfaat bagi orang lain!tools/testing/selftests/timers/set-tai.c
. Dan, dengan asumsi Anda memiliki tzdata
paket terinstal, ada file dengan offset antara UTC dan TAI di /usr/share/zoneinfo/leap-seconds.list
.int main(int argc, char **argv)
{
int i, ret;
ret = get_tai();
printf("tai offset started at %i\n", ret);
if (argc < 2)
{
printf("New offset not given, not setting\n");
}
else
{
i = strtol(argv[1],NULL,10);
printf("Attempting to set TAI offset to %d\n",i);
printf("Checking tai offsets can be properly set: ");
ret = set_tai(i);
ret = get_tai();
if (ret != i) {
printf("[FAILED] expected: %i got %i\n", i, ret);
return EXIT_FAILURE;
}
}
printf("[OK]\n");
return EXIT_SUCCESS;
}
leap-seconds.list
file dan menjalankan set-tai
dengan ini sebagai parameter (dalam /etc/rc.local
untuk mewujudkannya saat boot). Contoh cara melakukannya adalah:TAI_OFFSET=$(grep -v '^#' /usr/share/zoneinfo/leap-seconds.list | tail -1 | awk '{ print $2 }')
if [ -x /usr/local/sbin/set-tai ]; then
/usr/local/sbin/set-tai $TAI_OFFSET
fi