Je pense que vous voulez clock_gettime
avec CLOCK_TAI
pour fonctionner correctement. Moi aussi.
La phrase critique dans la réponse référencée est :"Veuillez noter que le décalage de CLOCK_REALTIME est initialisé au démarrage à zéro et que ni ntpd ni chronyd ne l'ont défini par défaut sur la valeur correcte (actuellement 35)."
Cela peut toujours être vrai, à part le décalage qui est maintenant de 37, mais un ntpd récent peut au moins être configuré pour définir le décalage. J'ai fait ce qui suit sur une machine 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
Puis clock_gettime(CLOCK_TAI, &res)
semblait fonctionner correctement.
Je pense que ntp définit le décalage en utilisant ntp_adjtime
avec MOD_TAI
. Recherche de la source chrony avec grep -P '(ADJ|MOD)_TAI'
ne trouve aucune correspondance, il semble donc que chrony n'ait pas encore cette capacité.
Vous pouvez utiliser libtai
de djb :https://cr.yp.to/libtai.html
Qu'est-ce que c'est ?
libtai est une bibliothèque pour stocker et manipuler des dates et des heures.
libtai prend en charge deux échelles de temps :(1) TAI64, couvrant quelques centaines de milliards d'années avec une précision d'une seconde; (2) TAI64NA, couvrant la même période avec une précision de 1 attoseconde. Les deux échelles sont définies en termes de TAI, la norme internationale actuelle en temps réel.
libtai fournit un format interne pour TAI64, struct tai, conçu pour des manipulations temporelles rapides. Les routines tai_pack() et tai_unpack() convertissent entre la structure tai et un format de stockage portable TAI64 de 8 octets. libtai fournit des formats internes et externes similaires pour TAI64NA.
libtai fournit struct caldate pour stocker les dates sous la forme année-mois-jour. Il peut convertir struct caldate, sous le calendrier grégorien, en un numéro de jour julien modifié pour faciliter l'arithmétique des dates.
libtai fournit une structure caltime pour stocker les dates et heures du calendrier avec les décalages UTC. Il peut convertir de struct tai à struct caltime inUTC, en tenant compte des secondes intercalaires, pour un affichage précis de la date et de l'heure. Il peut également reconvertir de struct caltime à struct tai pour l'entrée utilisateur. Sa vitesse de conversion globale UTC-TAI est 100 fois meilleure que l'implémentation UNIX mktime() habituelle.
Cette version de libtai nécessite un système UNIX avec gettimeofday(). Il sera facile de le porter vers d'autres systèmes d'exploitation avec des compilateurs prenant en charge l'arithmétique 64 bits.
Le code source de libtai est dans le domaine public.
Comme j'exécute chrony
au lieu de l'ancien ntpd
, je n'avais pas de moyen automatisé d'obtenir le bon paramètre du noyau, j'ai donc cherché une alternative.
Comme le décalage entre TAI et UTC est relativement constant (change
Il existe une application de test pour définir l'offset du noyau dans les sources du noyau, en
J'ai réduit l'application de test du noyau pour que le principal devienne :
Ensuite, pour mon cas d'utilisation, il s'agissait simplement d'extraire la valeur correcte du
J'espère que cela sera utile à quelqu'un d'autre !tools/testing/selftests/timers/set-tai.c
. Et, en supposant que vous avez le tzdata
package installé, il existe un fichier avec le décalage entre UTC et TAI en /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
fichier et exécutant set-tai
avec ceci en paramètre (en /etc/rc.local
pour que cela se produise au démarrage). Voici un exemple de méthode :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