GNU/Linux >> Linux Esercitazione >  >> Linux

C'è un modo per ottenere CLOCK_TAI corretto su Linux?

Penso che tu voglia clock_gettime con CLOCK_TAI per funzionare correttamente. Anch'io.

La frase critica nella risposta a cui si fa riferimento è:"Si noti che l'offset da CLOCK_REALTIME viene inizializzato all'avvio su zero e né ntpd né chronyd lo impostano per impostazione predefinita sul valore corretto (attualmente 35)."

Questo potrebbe essere ancora vero, a parte il fatto che l'offset ora è 37, ma un recente ntpd può almeno essere configurato per impostare l'offset. Ho fatto quanto segue su una macchina 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

Poi clock_gettime(CLOCK_TAI, &res) sembrava funzionare correttamente.

Penso che ntp imposti l'offset usando ntp_adjtime con MOD_TAI . Ricerca nella fonte chrony con grep -P '(ADJ|MOD)_TAI' non trova corrispondenze, quindi sembra che chrony non abbia ancora questa capacità.


Puoi usare libtai da djb:https://cr.yp.to/libtai.html

Che cos'è?

libtai è una libreria per memorizzare e manipolare date e orari.

libtai supporta due scale temporali:(1) TAI64, che copre alcune centinaia di miliardi di anni con una precisione di 1 secondo; (2) TAI64NA, che copre lo stesso periodo con una precisione di 1 attosecondo. Entrambe le scale sono definite in termini di TAI, l'attuale standard internazionale in tempo reale.

libtai fornisce un formato interno per TAI64, struct tai, progettato per manipolazioni rapide. Le routine tai_pack() e tai_unpack() convertono tra struct tai e un formato di archiviazione TAI64 portatile a 8 byte.libtai fornisce formati interni ed esterni simili per TAI64NA.

libtai fornisce struct caldate per memorizzare le date nella forma anno-mese-giorno. Può convertire struct caldate, sotto il calendario gregoriano, in un numero di giorno giuliano modificato per una facile aritmetica delle date.

libtai fornisce struct caltime per memorizzare le date e gli orari del calendario insieme agli offset UTC. Può convertire da struct tai a struct caltime in UTC, tenendo conto dei secondi intercalari, per una visualizzazione accurata di data e ora. Può anche riconvertire da struct caltime a struct tai per l'input dell'utente. La sua velocità complessiva di conversione da UTC a TAI è 100 volte migliore rispetto alla normale implementazione UNIX mktime().

Questa versione di libtai richiede un sistema UNIX con gettimeofday(). Sarà facile eseguire il porting su altri sistemi operativi con compilatori che supportano l'aritmetica a 64 bit.

Il codice sorgente di libtai è di pubblico dominio.


Mentre eseguo chrony invece del vecchio ntpd , non avevo un modo automatico per ottenere i parametri del kernel corretti, quindi ho cercato un'alternativa.

Poiché l'offset tra TAI e UTC è relativamente costante (cambia meno di una volta all'anno), è possibile impostare staticamente il parametro del kernel, quindi utilizzare l'orologio CLOCK_TAI in un'applicazione darà il valore corretto.

C'è un'applicazione di prova per impostare l'offset del kernel nei sorgenti del kernel, in tools/testing/selftests/timers/set-tai.c . E, supponendo che tu abbia il tzdata pacchetto installato, c'è un file con l'offset tra UTC e TAI in /usr/share/zoneinfo/leap-seconds.list .

Ho ridotto l'applicazione di test del kernel in modo che il main diventasse:

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

Quindi, per il mio caso d'uso, si trattava solo di estrarre il valore corretto da leap-seconds.list file ed eseguendo set-tai con this come parametro (in /etc/rc.local per farlo accadere al momento dell'avvio). Un modo di esempio per farlo è:

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

Spero che questo sia utile a qualcun altro!


Linux
  1. Abbiamo un annullamento in Linux?

  2. C'è STDCALL in Linux?

  3. Esiste un metodo per ottenere una percentuale su un DD in Linux?

  4. C'è un modo per ascoltare il processo?

  5. C'è un modo per ottenere la versione del BIOS da Linux?

Iniziare con Etcher.io

C'è un modo per ispezionare l'attuale rpath su Linux?

C'è un modo per ottenere l'UID dell'utente sulla macchina Linux usando java?

Qual è il modo corretto per avviare un servizio mongod su Linux/OS X?

Esiste un modo per ottenere time_t a 64 bit nei programmi a 32 bit in Linux?

C'è un modo per ottenere emoji colorati in qualsiasi emulatore di terminale su Linux?