SDB:Configurare l'ora di sistema
Indice
Ambito di applicazione
Dopo il riavvio del sistema, l'ora visualizzata da quest'ultimo, ad esempio con il comando date, risulta errata. Talvolta le informazioni legate all'orario per alcuni file sono errate, cioè in ritardo o in anticipo rispetto all'ora effettiva. Oppure all'avvio del sistema potrebbe venire avviato il controllo dei file system senza un motivo apparente.
Concetti di base
Ora locale
Durante l'installazione di un sistema Linux a gran parte degli utenti verrà richiesto di scegliere il tipo di ora da usare per l'orologio del CMOS/BIOS. A questo punto la maggior parte degli utenti sceglierà volutamente l'ora locale (local time in inglese), come ad esempio quella mostrata da un orologio da polso. Si raccomanda tuttavia di impostare l'orologio di sistema (come anche l'orologio interno del CMOS/BIOS) su UTC/GMT. In tal modo Linux sarà in grado di mantenere l'orologio dello spazio utente impostato all'orario corretto quando di passa dall'ora solare a quella legale, o viceversa (passaggio noto anche come DST: Daylight Saving Time). Il modo più sicuro è di impostare l'orologio del CMOS su UTC prima di iniziare il processo di installazione.
Ora universale coordinata
L'Ora universale coordinata o UTC (Coordinated Universal Time) è l'ora internazionale standard. È il termine di uso comune per quello che veniva precedentemente indicato come Ora del meridiano di Greenwich o GMT (Greenwich Meridian Time). Le ore zero e zero minuti UTC equivalgono alla mezzanotte in Gran Bretagna, a Greenwich, località situata sul meridiano corrispondente a longitudine 0 (zero). L'Ora universale coordinata è basata sul formato orario di 24 ore, cosa comune in molti paesi come l'Italia ma non in paesi in cui il Sistema Internazionale delle Unità di misura è poco diffuso, in cui al posto (per esempio) delle 16:00 UTC si avrebbero di frequente le 4 pm UTC (pm := post-meridiane, del pomeriggio).
Spazio utente
Per comprendere le ragioni per cui avere l'orologio CMOS impostato sull'ora locale potrebbe causare problemi, è utile sapere quale orologio viene utilizzato come riferimento dal kernel Linux e in che modo i programmi in spazio utente accedono a questo orologio. Ogni applicazione simile ai programmi utili in spazio utente userà dapprima (ad esempio) la chiamata di sistema time(2) per conoscere il numero di secondi trascorsi dall'Epoch (le ore 00:00:00 UTC dell'1 gennaio 1970). Questo numero verrà poi convertito, con l'aiuto delle funzioni, facenti parte dell'interfaccia API delle glibc, ctime(3), gmtime(3) e localtime(3), al fine di restituire l'ora locale.
Per convertire i secondi trascorsi dall'Epoch, le funzioni API delle glibc richiedono l'informazione del fuso orario (timezone in inglese, dato che sarà utile in seguito), ovvero l'entità dello scostamento del fuso orario, rispetto all'ora UTC, che è usato per l'ora locale e quali regole sono da applicarsi, come ad esempio quelle per il cambio dell'ora (o DST, Daylight Saving Time).
Tutte le informazioni relative ai fusi orari sono archiviate all'interno di /usr/share/zoneinfo/, ad esempio in /usr/share/zoneinfo/US/Central oppure in /usr/share/zoneinfo/Europe/Berlin. Per applicare tali regole si può usare la variabile di ambiente TZ, come in questi esempi:
oppure, per tutte le applicazioni in esecuzione in una sessione della shell
export TZ
o ancora, per chi usa (t)csh
che imposterà quindi il nuovo fuso orario per tutti i comandi lanciati dopo questa definizione, nella sessione shell corrente.
Per impostare il fuso orario per tutte le applicazioni attualmente in esecuzione nello spazio utente, le funzioni API delle glibc controllano anche la presenza del file
/etc/localtime
Quest'ultimo può essere un collegamento simbolico ad uno dei file di fuso orario contenuti in /usr/share oppure, se la directory /usr ha una partizione riservata, una copia di un file di fuso orario all'interno di /usr/share/zoneinfo/.
Spazio kernel
A questo punto sorge spontaneo domandarsi da dove il kernel tragga l'informazione sul numero di secondi che sono trascorsi dall'Epoch, ovvero 1 gen 1970, 00.00.00, UTC. All'avvio del sistema il kernel legge questa informazione dall'orologio del firmware, per esempio dal BIOS/CMOS. A questo proposito, al fine della determinazione della corretta ora locale in spazio utente, vale il seguente schema:
[Orologio del CMOS] -> [Orologio di sistema del Kernel in Ora universale (UTC)] | v [glibc] <- /etc/localtime oppure variabile di ambiente TZ | v [ora locale in spazio utente]
Per far sì che questo funzioni, e poiché il kernel non dispone di alcuna informazione sull'ora locale e sulle regole di fuso orario ad essa relative (come lo scostamento o differenza di fuso orario e le altre regole), naturalmente sarà necessario che l'orologio del CMOS/BIOS sia impostato sull'Ora universale (UTC).
Orologio hardware
Su alcuni sistemi sono presenti più di un sistema operativo e qualcuno degli altri sistemi operativi potrebbe non essere in grado di utilizzare l'ora UTC come il naturale orario di riferimento. A causa di questo potrebbe essere necessario impostare l'ora locale per l'orologio del CMOS/BIOS, anche se questa scelta ha due effetti negativi:
- Il kernel Linux deve venire informato di questa scelta, e questo deve avvenire prima di qualunque evento in cui si debba accedere ad un qualsiasi file system, probabilmente richiesto da un controllo di file system, e prima che quel file system venga montato, al fine di applicare le corrette impostazioni di data ed ora per il file system. Maggiori informazioni (in inglese) sono disponibili nell'archivio di messaggi elettronici The ext3 way of journalling della discussione ospitata su https://lkml.org.
- L'orologio CMOS/BIOS non è in grado di sapere se si sta usando l'ora solare o quella legale, dato che non è stato concepito a questo scopo. La situazione potrebbe cambiare con l'affermarsi del nuovo BIOS UEFI.
RAM disk Initrd
Per risolvere il primo dei due problemi, si può procedere ad informare l'orologio di sistema del kernel Linux su quale differenza di fuso orario applicare, ricorrendo alla chiamata di sistema settimeofday(2). Ciò richiede, dato che anche settimeofday(2) è incluso nelle glibc, che l'informazione contenuta in /etc/localtime, assieme a quella in /usr/share/zoneinfo/UTC, siano disponibili prima che si acceda al file system radice (quello della "root").
Per questo motivo i file /etc/localtime e /usr/share/zoneinfo/UTC sono salvati, assieme al programma di sistema warpclock, sotto a /lib/mkinitrd/ all'interno di initrd(4), il RAM disk iniziale, avviato dal gestore di avvio del sistema (ovvero dal boot loader). Lo schema visto sopra inizia allora a farsi più complesso:
[Orologio del CMOS] -> [Orologio di sistema del Kernel in ora locale (localtime)] ^ | +- [initrd warpclock <- (initrd)/etc/localtime] | v [Orologio di sistema del Kernel in Ora universale (UTC)] | v [glibc] <- /etc/localtime oppure variabile di ambiente TZ | v [ora locale in spazio utente]
Per far fronte all'altro problema, l'orologio CMOS/BIOS deve essere modificato ad ogni cambio dell'ora (passaggio ora locale/solare e v.v., noti in inglese come Daylight Saving Time (DST) switch). Questa operazione deve essere svolta dall'Amministratore del sistema o avviando il sistema operativo Windows[tm], che salva l'informazione del cambio in qualche posto remoto del suo registro di Windows[tm] (con lo svantaggio che nessun altro sistema operativo è a conoscenza della correzione all'orologio CMOS/BIOS che quello ha apportato).
Conclusioni
Dopo queste informazioni preliminari, ecco infine quale ora di riferimento dovrebbe essere opportuno usare per l'orologio del BIOS/CMOS:
- Su un sistema che avvia ed esegue soltanto Linux, UTC sembra essere l'unica scelta naturale da fare per l'orario di riferimento. Questo perché l'orologio del CMOS/BIOS non richiederà allora mai più alcun intervento di manutenzione dovuto al cambio dell'ora.
- Su un sistema che avvia più sistemi operativi in cui anche uno solo tra essi non sia in grado di gestire l'ora UTC nell'orologio CMOS/BIOS, l'unica scelta possibile è l'ora locale.
Quest'ultima opzione richiede un po' più di impegno per mantenere le informazioni relative al fuso orario e all'orologio del CMOS, contenute nel file initrd, sincronizzate con le impostazioni correnti. Ovvero, ogni modifica apportata al fuso orario richiede non solo di modificare l'orologio del CMOS, ma anche di aggiornare il file initrd prima che venga effettuato un qualsivoglia accesso al file system al successivo riavvio di sistema.
Altri sistemi operativi
Per Windows Vista[tm] SP2, Windows[tm] 7 e Server 2008 R2, gli Amministratori di sistema di quei sistemi Windows[tm] hanno anche la possibilità di creare un file con estensione .reg, ad esempio utc.reg, col seguente contenuto:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation] "RealTimeIsUniversal"=dword:00000001
e poi fare doppio clic sul file appena creato al fine di importarne il contenuto nel registro di Windows[tm]. Con queste modifiche dovrebbe essere possibile usare tutti quei sistemi Windows[tm] di sopra, e il sistema Linux, con UTC come ora di riferimento impostata nell'orologio del CMOS. È stato riportato che Vista[tm] SP2 non gestisce correttamente i cambi dell'ora per passaggio ad ora estiva/invernale.
Si veda in proposito il collegamento esterno (in inglese): IBM PC Real Time Clock should run in UT.
Un altro problema può essere costituito dall'usare Enhanced Write Filter e (oppure) File-Based Write Filter in Windows[tm]. Di conseguenza la procedura sopra esposta diventa più complessa:
- Assicurarsi che Enhanced Write Filter e File-Based Write Filter siano disabilitati.
- Impostare il fuso orario che si vuole sia usato da Windows[tm].
- Riavviare Windows[tm] e all'avvio passare alla schermata di configurazione del CMOS per impostarne l'orologio alla data e all'ora universali (UTC) correnti
- Avviare il sistema Windows[tm], accedere alla sessione e (ri)abilitare Enhanced Write Filter e File-Based Write Filter.
Si veda in proposito il collegamento esterno (in inglese): Computer Time Management and Embedded Systems (Windows Embedded Standard 7 Service Pack 1).