L'utilizzo di Chrony al posto di NTP su dispositivi come Raspberry Pi presenta il vantaggio di permettere uno slew rate maggiore e quindi poter sincronizzare l'orologio in tempi più rapidi senza salti che possano creare malfunzionamenti nelle funzioni di temporizzazione (cfr. maxslewrate e makestep nel manuale di chrony.conf).
Questo script è una variante del precedente che funziona con Chrony. Nel file, viene anche riportato il valore dell'errore tra l'ora di sistema e quella NTR al momento dell'acquisizione del sync, utile per far sapere all'applicazione di quanto è stato fuori sync l'orologio finora.
Chrony deve essere installato e configurato correttamente.
<?php
error_reporting(E_ALL);
# Apro in scrittura il file su tmpfs
# se non esiste lo crea
$fhandle = fopen("/mnt/pirun1/NtpSync", "c");
# La scrittura dello stato avviene solo in caso di acquisizione
# o perdita del sync, per risparmiare risorse
# Lo stato del ciclo precedente viene salvato nella variabile:
$LastValue = 2;
# Inizializzo a 2 in modo che poi, confrontata con 1 o 0 sia sempre falsa e
# faccia scrivere sempre il file temporaneo all'avvio dello script;
while (true) {
/*
* Il comando waitsync è molto comodo per avere lo stato del sync del demone
* vedere la pagina man di chronyc per i dettagli:
* https://chrony.tuxfamily.org/doc/3.2/chronyc.html
*/
$LastLine = exec("chronyc -n waitsync 10 0 0 0.1", $OutputArray, $return_var);
/*
* Variabile di ritorno è =0 se è in sync, !=0 se è fuori sync
* Uso $LastLine per scrivere su $SystemError l'entità dell'errore
*/
if ($return_var === 0) {
$IsSynced = 1;
preg_match('/correction: (.*), skew: /', $LastLine, $LastLineErrorArray);
$SystemError = $LastLineErrorArray[1] + 0;
} else {
$IsSynced = 0;
}
# Se cambia lo stato, il file viene aggiornato.
if ($IsSynced <> $LastValue) {
fseek($fhandle, 0);
if ($IsSynced === 1) {
/*
* Se mi interessa solo lo stato posso non acquisire il lock del file,
* se serve anche l'errore è necessario farlo.
*/
fwrite($fhandle, "1");
LogRow("In sync" . PHP_EOL);
flock($fhandle, LOCK_EX);
fwrite($fhandle, "_err=" . number_format($SystemError, 9) . "_");
flock($fhandle, LOCK_UN);
$PollingInterval = 1000000;
} else {
fwrite($fhandle, "0");
LogRow("Out of sync" . PHP_EOL);
$PollingInterval = 100000;
}
}
$LastValue = $IsSynced;
usleep($PollingInterval);
}
function LogRow($text) {
echo (date("c") . " " . $_SERVER["SCRIPT_NAME"] . " - " . $text);
}


