Gibt es eine Möglichkeit, unter Linux die korrekte CLOCK_TAI zu erhalten?

8

Mein Linux-Rechner unterstützt CLOCK_TAI, aber sein Versatz von CLOCK_REALTIMEist fälschlicherweise Null (dies ist die Standardeinstellung). Gibt es eine Software oder eine andere Lösung, die CLOCK_TAIals TAI beibehalten wird ?

Von Antworten hier und hier scheint es weder ntpdnoch zu chronydtun.

Ich würde gerne meine Hardware-Uhr auf TAI stellen, um dies zu erreichen, vorausgesetzt, CLOCK_REALTIMEund gettimeofdayusw. POSIX-Zeit (im Wesentlichen UTC) zurückgeben.

Ashley Yakeley
quelle

Antworten:

4

Ich glaube , Sie wollen 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 ihn standardmäßig auf den korrekten Wert setzen (derzeit 35)."

Dies mag immer noch zutreffen, abgesehen davon, dass der Versatz jetzt 37 ist, aber ein aktueller ntpd kann zumindest so konfiguriert werden, dass der Versatz eingestellt wird. Auf einem openSUSE-Computer habe ich Folgendes ausgeführt:

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 ntp_adjtimemit setzt MOD_TAI. Beim Durchsuchen der Chronikquelle wurden grep -P '(ADJ|MOD)_TAI'keine Übereinstimmungen gefunden, sodass Chronik anscheinend noch nicht über diese Funktion verfügt.

Edmund Grimley Evans
quelle
3

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

Was ist es?

libtai ist eine Bibliothek zum Speichern und Bearbeiten von Datums- und Uhrzeitangaben.

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

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

libtai bietet eine Struktur zum Speichern von Daten in Form von Jahr-Monat-Tag. Es kann die Struktur nach dem gregorianischen Kalender in eine geänderte julianische Tageszahl konvertieren, um die Datumsberechnung zu vereinfachen.

libtai bietet eine Zeitstruktur zum Speichern von Kalenderdaten und -zeiten sowie von UTC-Offsets. Es kann in UTC von struct tai in struct caltime konvertiert werden, wobei Schaltsekunden berücksichtigt werden, um eine genaue Anzeige von Datum und Uhrzeit zu gewährleisten. Es kann auch für Benutzereingaben von struct caltime zurück in struct tai konvertiert werden. Die UTC-TAI-Konvertierungsgeschwindigkeit ist insgesamt 100-mal besser als bei der üblichen Implementierung von UNIX mktime ().

Diese Version von libtai benötigt ein UNIX-System mit gettimeofday (). Mit Compilern, die 64-Bit-Arithmetik unterstützen, ist die Portierung auf andere Betriebssysteme problemlos möglich.

Der libtai-Quellcode ist gemeinfrei.

dfc
quelle
Ich denke, dies ist nur eine Bibliothek zum Konvertieren von Zeitformaten. Ich bin auf der Suche nach einem Programm, mit dem sich die Linux-Uhren einstellen lassen.
Ashley Yakeley
In Ihrem Fragentitel steht "TAI erhalten", nicht "TAI für meine Uhr verwenden" oder "System auf TAI setzen". Wenn Sie erwähnen, dass die Uhr im Körper auf TAI eingestellt ist, scheint es, als wären Sie für diese Option zugänglich, wenn Sie "den korrekten TAI vom System erhalten".
dfc
Ich frage nach der Linux-Uhr CLOCK_TAI.
Ashley Yakeley
3

Da ich chronyanstelle des alten laufe ntpd, hatte ich keine automatisierte Methode, um den Kernel-Parameter richtig zu machen, und suchte nach einer Alternative.

Da der Versatz zwischen TAI und UTC relativ konstant ist (Änderungen <einmal pro Jahr), kann der Kernel-Parameter statisch festgelegt werden, und die Verwendung der CLOCK_TAI-Uhr in einer Anwendung liefert den korrekten Wert.

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

Ich habe die Kernel-Testanwendung heruntergefahren, sodass die Hauptanwendung wie folgt aussah:

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

In meinem Anwendungsfall ging es nur darum, den richtigen Wert aus der leap-seconds.listDatei zu extrahieren und set-taimit diesem Parameter auszuführen ( /etc/rc.localdamit dies beim Booten geschieht). 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 nützlich für jemand anderen!

Michael Firth
quelle