<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Artisan Numérique</title>
  <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1146"/>
  <link rel="self" type="application/atom+xml" href="http://artisan.karma-lab.net/node/1146/atom/feed"/>
  <id>http://artisan.karma-lab.net/node/1146/atom/feed</id>
  <updated>2008-10-21T23:10:02+02:00</updated>
  <entry>
    <title>Maîtriser le temps...</title>
    <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1146" />
    <id>http://artisan.karma-lab.net/node/1146</id>
    <published>2008-10-21T16:14:02+02:00</published>
    <updated>2008-10-21T23:10:02+02:00</updated>
    <author>
      <name>Ulhume</name>
    </author>
    <category term="Serveurs" />
    <category term="drupalfr.org" />
    <category term="OK" />
    <category term="Planet Libre" />
    <category term="Tutoriel" />
    <summary type="html"><![CDATA[<p>
   Garder son PC à l'heure ou synchroniser plusieurs machines sur la même base de temps n'est pour diverses raisons pas toujours évident. Et pourtant c'est primordiale lorsque l'on est plusieurs à accéder à une même ressource, ou simplement pour éviter de louper un rendez-vous... 
</p>
<p>
  Les distributions règlent généralement ce problème en collant un serveur NTP en mémoire mais c'est un peu prendre un marteau pour écraser une mouche et surtout cela manque de souplesse. Voyons donc comment fonctionne le temps sur un PC, et sur GNU/Linux en particulier. 
</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>
   Garder son PC à l'heure ou synchroniser plusieurs machines sur la même base de temps n'est pour diverses raisons pas toujours évident. Et pourtant c'est primordiale lorsque l'on est plusieurs à accéder à une même ressource, ou simplement pour éviter de louper un rendez-vous... 
</p>
<p>
  Les distributions règlent généralement ce problème en collant un serveur NTP en mémoire mais c'est un peu prendre un marteau pour écraser une mouche et surtout cela manque de souplesse. Voyons donc comment fonctionne le temps sur un PC, et sur GNU/Linux en particulier. 
</p>
<!--break-->


	<a name='chapter_25'></a>
  <h2>Horloge Système</h2>
	
<p>
  Depuis que le PC est PC, il y a toujours eu deux horloges, l'une logicielle et l'autre matérielle. 
</p>
<p>
  L'horloge logicielle des premiers PC et PC/XT, était prise en charge par une puce 
  <a target='_blank' href='http://fr.wikipedia.org/wiki/Intel 8253'>
  Intel 8253
  </a> relevée avec les PC/AT par la <a class='external' target='_blank' href='http://ftp.utcluj.ro/pub/users/calceng/PMP/231164.pdf' >8254</a>. Ces puces "timer-counter" étaient programmées par le BIOS pour générer une interruption toutes les 54.936 secondes, soit environ 18.206 fois par secondes. A l'époque le manque de précision impliquant que l'horloge se désynchronisait avec la réalité en perdant en gros une minute par jours. Aujourd'hui les sources sont beaucoup plus précise avec des puces comme les <a class='external' target='_blank' href='http://www.netburner.com/downloads/mod5270/APPNOTE-MOD5270-PIT.pdf' >PIT</a> (Programmable Interrupt Timer) utilisé notamment par Linux (clock=pit au démarrage du kernel). 
</p>
<p> 
  La commande pour lire et écrire dans cette horloge est donc :
  
  <div class='code-block code-block-traces'>
  <div class='container'>
  <div class='co0'># réglage de l'horloge, petite remontée dans le temps...</div><div class='command'><span class='prompt'>root#</span>date --set="9/22/96 16:45:05"</div><div class='result'>dim. sept. 22 16:45:05 CEST 1996</div><div class='result'>&nbsp;</div><div class='co0'># lecture du l'horloge système</div><div class='command'><span class='prompt'>root#</span>date</div><div class='result'>dim. sept. 22 16:45:17 CEST 1996</div><div class='command'><span class='prompt'>root#</span><span class='cursor'>&nbsp;</span></div>
  </div>
  
  </div>
<p>
  Mais même si elle sont plus précise, les horloges logicielles gardent une lacune de taille, elle ne savent pas compter le temps lorsque le PC est éteint. 
</p>



	<a name='chapter_26'></a>
  <h2>Horloge Matérielle</h2>
	
<p>
<image file="Realtimeclock_Motherboard_Baby_AT_crop.jpg" width="200px"/>
  Cette horloge là est dite RTC (Real Time CLock) et prise en charge par un composant spécifique sur la carte mère (dans le temps, la fameuse "Dallas") même si aujourd'hui elle est de plus en plus intégrée au southbridge. Cette horloge est généralement basée sur un quartz qui oscille, comme celui des montres, à une fréquence de 32768Hz, soit 2<sup>15</sup> fois par secondes, ce qui est pratique pour le comptage binaire. Ce circuit a sa propre alimentation, par une simple pile au lithium ou un 
  <a target='_blank' href='http://fr.wikipedia.org/wiki/supercondensateur'>
  supercondensateur
  </a>. Le résultat en est une horloge relativement précise qui tourne tout le temps, même PC éteint. C'est aussi grâce à ce composant que l'on peut, via le BIOS, allumer un PC à une heure précise. 
</p>
<p>
  Pour lire et écrire dans l'horloge matérielle la commande est 
  
  <div class='code-block code-block-traces'>
  <div class='container'>
  <div class='co0'># lecture de l'horloge (on remarque que c'est bien une heure différente de celle de "date")</div><div class='command'><span class='prompt'>root#</span>hwclock --show</div><div class='result'>mar. 21 oct. 2008 15:24:57 CEST  -0.408169 secondes</div><div class='result'>&nbsp;</div><div class='co0'># Réglage de l'heure hardware</div><div class='command'><span class='prompt'>root#</span>hwclock --set --date="9/22/98 16:45:05"</div><div class='result'>&nbsp;</div><div class='co0'># vérification</div><div class='command'><span class='prompt'>root#</span>hwclock --show</div><div class='result'>dim. 22 sept. 1998 16:45:09 CEST  -0.751474 secondes</div><div class='command'><span class='prompt'>root#</span><span class='cursor'>&nbsp;</span></div>
  </div>
  
  </div>
</p>
<p>
  Vous avez constaté en lançant ces commandes que la réaction n'est pas instantanée, en lecture comme en écriture, ce qui explique sûrement (mais je n'en suis pas bien sur) pourquoi les OS n'utilisent pas uniquement cette horloge. 
</p>
<p>
  Maintenant voyons comment synchroniser l'horloge matérielle avec l'horloge logicielle et inversement :

  <div class='code-block code-block-traces'>
  <div class='container'>
  <div class='co0'># Horloge interne -> système en utilisant le temps universel</div><div class='command'><span class='prompt'>root#</span>hwclock --hctosys --utc</div><div class='result'>&nbsp;</div><div class='co0'># L'horloge système est maintenant en 1998</div><div class='result'>&nbsp;</div><div class='co0'># Horloge système -> interne en utilisant le temps universel</div><div class='command'><span class='prompt'>root#</span>hwclock --systohc --utc</div><div class='command'><span class='prompt'>root#</span><span class='cursor'>&nbsp;</span></div>
  </div>
  
  </div>
</p>


	<a name='chapter_27'></a>
  <h2>Horloge distante</h2>
	
<p>
  Maintenant nos deux horloges sont bien sympathique mais qu'en est-il du "vrai" temps qui passe ? L'idéal pour être à l'heure est de la demander à un serveur qui sait de quoi il parle. Ce sont les serveurs NTP (Net Time Protocol). Et il y'en a de nombreux de disponible, alors autant en profiter.
</p>
<p>
 Le seul problème est que la majorité des distributions passent par une usine à gaz pour récupérer le temps sur un serveur distant en passant par l'installation locale d'un service <kbd>ntpd</kbd> alors que là aussi, il existe une commande faite pour cela.
</p>
<p>
  Cette commande c'est <kbd>ntpdate</kbd> du paquet <kbd>ntp-client</kbd> et son rôle est simplement de mettre à jour l'horloge système avec un serveur NTP distant. Ce serveur distant peut être sur <a class='external' target='_blank' href='http://www.pool.ntp.org/zone/europe' >Internel</a>, mais aussi installé <a class='external' target='_blank' href='http://blog.nicolargo.com/2008/10/installation-dun-serveur-ntp.html' >par vos soins</a>. 
</p>
<p>
  Une fois que vous votre adresse, ici j'utilise <kbd>fr.pool.ntp.org</kbd>, vous pouvez lancer la commande de synchronisation :

  <div class='code-block code-block-traces'>
  <div class='container'>
  <div class='co0'># récupération de l'heure du serveur NTP</div><div class='command'><span class='prompt'>root#</span>ntpdate -s -b fr.pool.ntp.org</div><div class='result'>&nbsp;</div><div class='co0'># Vérification de la synchronisation avec l'horloge système</div><div class='command'><span class='prompt'>root#</span>date</div><div class='result'>mar. oct. 21 15:40:27 CEST 2008</div><div class='result'>&nbsp;</div><div class='co0'># Et l'horloge matérielle est quant à elle encore en 1998</div><div class='command'><span class='prompt'>root#</span>hwclock --show</div><div class='result'>dim. 22 sept. 1998 16:59:15 CEST  -0.251837 secondes</div><div class='command'><span class='prompt'>root#</span><span class='cursor'>&nbsp;</span></div>
  </div>
  
  </div>
</p>


	<a name='chapter_28'></a>
  <h2>Mise en musique</h2>
	
<p>
  Maintenant nous n'avons plus qu'à mettre tout cela dans un script
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  &nbsp; <span class="co0">#! /bin/sh</span><br />
<br />
&nbsp; <span class="co0"># synchronisation serveur NTP -&gt; horloge logicielle</span><br />
&nbsp; <span class="sy0">/</span>usr<span class="sy0">/</span>sbin<span class="sy0">/</span>ntpdate -s -b fr.pool.ntp.org<br />
<br />
&nbsp; <span class="co0"># Quelque chose c'est mal passé ? </span><br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re4">$?</span> <span class="sy0">!</span>= <span class="nu0">0</span> <span class="br0">&#93;</span> ; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Erreur lors de la synchronisation de l'heure&quot;</span> <span class="sy0">&gt;</span> <span class="sy0">/</span>dev<span class="sy0">/</span>stderr<br />
&nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; <span class="co0"># synchronisation horloge logicielle -&gt; horloge matérielle </span><br />
&nbsp; &nbsp; <span class="sy0">/</span>sbin<span class="sy0">/</span>hwclock --systohc --utc<br />
&nbsp; <span class="kw1">fi</span>
  </div>
  <div class='caption'>/sbin/sync-clock.sh</div>
  </div>
</p>
<p>
  Ce script peut être lancé à la main en cas de besoin ou mieux, être collé dans le CRON pour être exécuté sur une base journalière. Mais Comme le fait très justement remarquer Axone dans un commentaire un peu plus bas ce n'est pas très sympathique pour les serveurs distant su tout le monde les appelle à heure entière (ex. xx:00). Donc nous allons faire cela plus intelligemment en créant un fichier <kbd>/etc/cron.d/time-sync</kbd> :
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  <span class="nu0">17</span> <span class="nu0">23</span> <span class="sy0">*</span> <span class="sy0">*</span> <span class="sy0">*</span> <span class="sy0">/</span>sbin<span class="sy0">/</span>sync-clock.<a target="blank" href="http://pwet.fr/man/linux/commandes/sh"><span class="kw2">sh</span></a>
  </div>
  <div class='caption'>/etc/cron.d/time-sync</div>
  </div>
</p>
<p>
  Ainsi la mise à jour est faite tous les jours à 23:17, ce qui limite bien les risques. 
</p>


	<a name='chapter_29'></a>
  <h2>Conclusion</h2>
	
<p>
   Voilà, pas de grosse artillerie donc pour simplement s'assurer que deux machines fonctionnent sur la même base de temps ou que votre portable ne vous fait pas louper un rendez-vous...
</p>
    ]]></content>
  </entry>
</feed>
