Apakah ada cara untuk mendapatkan CLOCK_TAI yang benar di Linux?

7

Mesin Linux saya mendukung CLOCK_TAI, tetapi offsetnya dari CLOCK_REALTIME salah nol (ini adalah default). Apakah ada perangkat lunak atau solusi lain yang akan dipertahankan CLOCK_TAI sebagai TAI?

Dari jawaban sini dan sini , sepertinya juga tidak ntpd maupun chronyd melakukan hal ini.

Saya akan senang mengatur jam perangkat keras saya ke TAI untuk mencapai ini, asalkan CLOCK_REALTIME dan gettimeofday dll. mengembalikan waktu POSIX (dasarnya UTC).

Ashley Yakeley
sumber

Jawaban:

4

Saya pikir kamu mau clock_gettime dengan CLOCK_TAI untuk bekerja dengan baik. Begitu juga aku.

Kalimat kritis dalam jawaban yang direferensikan adalah: "Harap dicatat bahwa offset dari CLOCK_REALTIME diinisialisasi pada boot ke nol dan baik ntpd maupun chronyd tidak menetapkannya secara default ke nilai yang benar (saat ini 35)."

Ini mungkin masih benar, terlepas dari offset yang sekarang menjadi 37, tetapi ntpd baru-baru ini setidaknya dapat dikonfigurasi untuk mengatur 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

Kemudian clock_gettime(CLOCK_TAI, &res) sepertinya bekerja dengan benar.

Saya berpikir bahwa ntp mengatur 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.

Edmund Grimley Evans
sumber
3

Kamu bisa memakai libtai dari djb: https://cr.yp.to/libtai.html

Apa itu?

libtai adalah perpustakaan untuk menyimpan dan memanipulasi tanggal dan   waktu.

libtai mendukung dua skala waktu: (1) TAI64, mencakup beberapa ratus   miliar tahun dengan ketelitian 1 detik; (2) TAI64NA, mencakup hal yang sama   periode dengan presisi 1-attosecond. Kedua skala didefinisikan dalam istilah   TAI, standar waktu nyata internasional saat ini.

libtai menyediakan format internal untuk TAI64, struct tai, dirancang untuk   manipulasi waktu cepat. Rutinitas tai_pack () dan tai_unpack ()   mengkonversi antara struct tai dan format penyimpanan TAI64 8-byte portabel.   libtai menyediakan format internal dan eksternal yang serupa untuk TAI64NA.

libtai menyediakan cal struct date untuk menyimpan tanggal dalam bentuk tahun-bulan-hari.   Itu dapat mengonversi struct caldate, di bawah kalender Gregorian, menjadi a   nomor hari Julian dimodifikasi untuk aritmatika tanggal mudah.

libtai menyediakan waktu untuk menyimpan tanggal dan waktu kalender   dengan offset UTC. Itu dapat mengkonversi dari struct tai ke struct caltime di   UTC, menghitung detik kabisat, untuk tampilan tanggal dan waktu yang akurat.   Itu juga dapat mengkonversi kembali dari struct caltime ke struct tai untuk pengguna   memasukkan. Kecepatan konversi UTC-ke-TAI keseluruhannya 100x lebih baik daripada   implementasi mktime () UNIX biasa.

Versi libtai ini membutuhkan sistem UNIX dengan gettimeofday (). Saya t   akan mudah untuk port ke sistem operasi lain dengan kompiler   mendukung aritmatika 64-bit.

Kode sumber libtai ada di domain publik.

dfc
sumber
Saya pikir ini hanya perpustakaan untuk mengkonversi format waktu. Saya mencari program yang akan menyesuaikan jam Linux.
Ashley Yakeley
Judul pertanyaan Anda mengatakan "dapatkan TAI" itu tidak mengatakan "gunakan TAI untuk jam saya" atau "set sistem ke TAI." Ketika Anda menyebutkan pengaturan jam ke TAI di dalam tubuh, sepertinya Anda setuju dengan opsi ini jika memungkinkan Anda "mendapatkan TAI yang benar dari sistem."
dfc
Saya bertanya tentang jam Linux CLOCK_TAI.
Ashley Yakeley
3

Saat saya berlari chrony bukannya yang lama ntpd, Saya tidak memiliki cara otomatis untuk mendapatkan parameter kernel dengan benar, jadi saya mencari alternatif.

Karena offset antara TAI dan UTC relatif konstan (perubahan & lt; sekali per tahun), dimungkinkan untuk menetapkan parameter kernel secara statis, dan kemudian menggunakan jam CLOCK_TAI dalam aplikasi akan memberikan nilai yang benar.

Ada aplikasi uji untuk mengatur offset kernel di sumber kernel, di tools/testing/selftests/timers/set-tai.c. Dan, anggap Anda memiliki tzdata paket terpasang, ada file dengan offset antara UTC dan TAI di /usr/share/zoneinfo/leap-seconds.list.

Saya memotong aplikasi uji kernel sehingga yang utama menjadi:

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;
}

Kemudian, untuk kasus penggunaan saya, itu hanya masalah mengekstraksi nilai yang benar dari leap-seconds.list file dan berjalan set-tai dengan ini sebagai parameter (dalam /etc/rc.local untuk mewujudkannya pada saat boot). Contoh cara melakukan ini 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

Semoga ini bermanfaat bagi orang lain!

Michael Firth
sumber