Myslím, že chcete clock_gettime
s CLOCK_TAI
správně fungovat. Já také.
Kritická věta v odkazované odpovědi je:"Upozorňujeme, že offset od CLOCK_REALTIME je při bootování inicializován na nulu a ani ntpd ani chronyd jej ve výchozím nastavení nenastaví na správnou hodnotu (aktuálně 35)."
To může být stále pravda, kromě toho, že offset je nyní 37, ale poslední ntpd lze alespoň nakonfigurovat tak, aby nastavil offset. Na počítači openSUSE jsem provedl následující:
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
Potom clock_gettime(CLOCK_TAI, &res)
zdálo se, že funguje správně.
Myslím, že ntp nastavuje offset pomocí ntp_adjtime
s MOD_TAI
. Vyhledávání chrony zdroje pomocí grep -P '(ADJ|MOD)_TAI'
nenajde žádné shody, takže se zdá, že chrony zatím tuto schopnost nemá.
Můžete použít libtai
od djb:https://cr.yp.to/libtai.html
Co to je?
libtai je knihovna pro ukládání a manipulaci s daty a časy.
libtai podporuje dvě časová měřítka:(1) TAI64, pokrývající několik set miliard let s přesností na 1 sekundu; (2) TAI64NA, pokrývající stejné období s přesností na 1 attosekundu. Obě stupnice jsou definovány v podmínkách TAI, současného mezinárodního standardu v reálném čase.
libtai poskytuje interní formát pro TAI64, struct tai, navržený pro rychlé časové manipulace. Rutiny tai_pack() a tai_unpack() převádějí mezi struct tai a přenosným 8bajtovým úložištěm formátu TAI64.libtai poskytují podobné interní a externí formáty pro TAI64NA.
libtai poskytuje struct caldate k ukládání dat ve formě rok-měsíc-den. Dokáže převést struct caldate podle gregoriánského kalendáře na upravené juliánské číslo dne pro snadnou aritmetiku data.
libtai poskytuje struct caltime pro ukládání kalendářních dat a časů spolu s offsety UTC. Umí konvertovat ze struct tai na struct caltime inUTC, počítajíce s přestupnými sekundami, pro přesné zobrazení data a času. Může také konvertovat zpět ze struct caltime na struct tai pro zadání uživatele. Jeho celková rychlost konverze z UTC na TAI je 100x vyšší než u obvyklé implementace UNIX mktime().
Tato verze libtai vyžaduje systém UNIX s gettimeofday(). Bude snadné jej přenést na jiné operační systémy s kompilátory podporujícími 64bitovou aritmetiku.
Zdrojový kód libtai je ve veřejné doméně.
Protože používám chrony
místo starého ntpd
, Neměl jsem automatizovaný způsob, jak správně nastavit parametry jádra, tak jsem se podíval po alternativě.
Protože offset mezi TAI a UTC je relativně konstantní (změny
Existuje testovací aplikace pro nastavení posunu jádra ve zdrojích jádra v
Zrušil jsem testovací aplikaci jádra, takže hlavní se stala:
Pak pro můj případ použití šlo jen o extrahování správné hodnoty z
Doufám, že to bude užitečné pro někoho jiného!tools/testing/selftests/timers/set-tai.c
. A za předpokladu, že máte tzdata
Pokud je balíček nainstalován, existuje soubor s posunem mezi UTC a TAI v /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
soubor a spuštěn set-tai
s tímto jako parametrem (v /etc/rc.local
aby se to stalo při spouštění). Příkladem je: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