Gibt es eine Möglichkeit, den korrekten CLOCK_TAI unter Linux zu erhalten?

1452
Ashley Yakeley

Meine Linux-Maschine unterstützt CLOCK_TAI, aber der Versatz von CLOCK_REALTIMEist falsch Null (dies ist die Standardeinstellung). Gibt es eine Software oder eine andere Lösung, die CLOCK_TAIals TAI erhalten bleibt ?

Aus den Antworten hier und hier scheint es weder ntpdnoch zu chronydtun.

Ich würde gerne meine Hardware - Uhr auf TAI setzen, dies zu erreichen, zur Verfügung gestellt CLOCK_REALTIMEund gettimeofdayusw. Rückkehr POSIX Zeit ( im Wesentlichen UTC).

7

3 Antworten auf die Frage

4
Edmund Grimley Evans

Ich denke du willst clock_gettimemit CLOCK_TAIrichtig arbeiten. Ich habe das auch so gemacht.

Der kritische Satz in der Antwort, auf die verwiesen wird, lautet: "Bitte beachten Sie, dass der Offset von CLOCK_REALTIME beim Booten auf Null initialisiert wird und weder ntpd noch chronyd standardmäßig auf den korrekten Wert setzen (derzeit 35)."

Dies kann immer noch wahr sein, abgesehen davon, dass der Versatz jetzt 37 ist, aber ein aktuelles ntpd kann zumindest so konfiguriert werden, dass es den Versatz festlegt. Ich habe folgendes auf einem openSUSE-Rechner gemacht:

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 

Dann clock_gettime(CLOCK_TAI, &res)schien es richtig zu funktionieren.

Ich denke, dass NTP den Offset mit ntp_adjtimemit setzt MOD_TAI. Durchsuchen der Chrony-Quelle mit grep -P '(ADJ|MOD)_TAI'findet keine Übereinstimmungen, daher scheint Chrony diese Funktion noch nicht zu haben.

3
dfc

Sie können libtaivon djb verwenden: https://cr.yp.to/libtai.html

Was ist es?

libtai ist eine Bibliothek zum Speichern und Bearbeiten von Datum und Uhrzeit.

libtai unterstützt zwei Zeitskalen: (1) TAI64, die einige hundert Milliarden Jahre mit einer Genauigkeit von einer Sekunde abdeckt; (2) TAI64NA, die den gleichen Zeitraum mit einer Genauigkeit von 1 Attosekunde abdeckt. Beide Skalen werden in Bezug auf TAI, den aktuellen internationalen Echtzeitstandard, definiert.

libtai bietet ein internes Format für TAI64, struct tai, das für schnelle Zeitmanipulationen konzipiert ist. Die Routinen tai_pack () und tai_unpack () konvertieren zwischen struct tai und einem tragbaren 8-Byte-TAI64-Speicherformat. libtai bietet ähnliche interne und externe Formate für TAI64NA.

libtai bietet ein Kontrollkästchen zur Speicherung von Datumsangaben in Form von Jahr-Monat-Tag. Es kann struct caldate gemäß dem Gregorianischen Kalender in eine modifizierte julianische Tagesnummer umwandeln, um eine einfache Datumsberechnung zu ermöglichen.

libtai bietet struct caltime zum Speichern von Kalenderdaten und -zeiten sowie UTC-Offsets. Es kann von struct tai in struct caltime in UTC umgerechnet werden, wobei Schaltsekunden für genaue Datums- und Uhrzeitanzeige berücksichtigt werden. Es kann auch von struct caltime in struct tai für Benutzereingaben konvertiert werden. Die Umsetzungsgeschwindigkeit von UTC in TAI ist insgesamt 100x besser als die übliche UNIX-Implementierung mktime ().

Diese Version von libtai erfordert ein UNIX-System mit gettimeofday (). Die Portierung auf andere Betriebssysteme ist mit Compilern, die 64-Bit-Arithmetik unterstützen, einfach.

Der libtai-Quellcode ist gemeinfrei.

Ich denke, das ist nur eine Bibliothek zum Konvertieren von Zeitformaten. Ich suche ein Programm, das die Linux-Uhren anpassen wird. Ashley Yakeley vor 7 Jahren 0
Der Titel Ihrer Frage lautet "Holen Sie sich TAI", es heißt nicht "TAI für meine Uhr verwenden" oder "System auf TAI setzen". Wenn Sie die Einstellung der Uhr auf TAI im Körper erwähnen, schien es, als wären Sie für diese Option geeignet, wenn Sie "den richtigen TAI vom System erhalten" ließen. dfc vor 7 Jahren 0
Ich frage nach der Linux-Uhr "CLOCK_TAI". Ashley Yakeley vor 7 Jahren 0
3
Michael Firth

Da ich chronyanstelle des alten laufe ntpd, hatte ich keine automatisierte Möglichkeit, den Kernel-Parameter richtig einzustellen, also suchte ich nach einer Alternative.

Da der Versatz zwischen TAI und UTC relativ konstant ist (Änderungen <einmal pro Jahr), ist es möglich, den Kernel-Parameter statisch festzulegen. Wenn Sie dann die CLOCK_TAI-Uhr in einer Anwendung verwenden, erhalten Sie den korrekten Wert.

Es gibt eine Testanwendung zum Einstellen des Kernel-Offsets in den Kernel-Quellen in tools/testing/selftests/timers/set-tai.c. Vorausgesetzt, Sie haben das tzdataPaket installiert, gibt es eine Datei mit dem Versatz zwischen UTC und TAI in /usr/share/zoneinfo/leap-seconds.list.

Ich habe die Kernel-Testanwendung heruntergehackt.

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

Für meinen Anwendungsfall war es nur eine Frage des Extrahierens des korrekten Werts aus der leap-seconds.listDatei und Ausführen set-taimit diesem als Parameter (in /etc/rc.local, damit er beim Booten ausgeführt wird). Ein Beispiel dafür ist:

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 

Hoffe, das ist jemand anderem nützlich!