<?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/1598"/>
  <link rel="self" type="application/atom+xml" href="http://artisan.karma-lab.net/node/1598/atom/feed"/>
  <id>http://artisan.karma-lab.net/node/1598/atom/feed</id>
  <updated>2008-10-25T16:09:21+02:00</updated>
  <entry>
    <title>lm_sensors, contrôle et monitoring</title>
    <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1598" />
    <id>http://artisan.karma-lab.net/node/1598</id>
    <published>2008-07-25T00:56:54+02:00</published>
    <updated>2008-10-25T16:09:21+02:00</updated>
    <author>
      <name>Ulhume</name>
    </author>
    <category term="kernel" />
    <category term="OK" />
    <category term="Planet Libre" />
    <category term="Tutoriel" />
    <summary type="html"><![CDATA[<p>
   Rapidement fatigué de l'inesthétisme de mon ancien boîtier dans notre nouvel intérieur, et attiré par la magie d'avoir enfin un garage entier pour bricoler, j'ai décidé de transformer un de nos meubles de salon en boite à serveur. Le problème, c'est que le bois ça fait aussi bien sonner les belles guitares que rendre assourdissant les ventilateurs... Alors retour en atelier,  installation de suspensions pour les disques, et de ventilateurs 12cm à basse vitesse de rotation. Ne restait donc que ce maudit ventilateur de CPU qui moulinait comme un malade. 
</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>
   Rapidement fatigué de l'inesthétisme de mon ancien boîtier dans notre nouvel intérieur, et attiré par la magie d'avoir enfin un garage entier pour bricoler, j'ai décidé de transformer un de nos meubles de salon en boite à serveur. Le problème, c'est que le bois ça fait aussi bien sonner les belles guitares que rendre assourdissant les ventilateurs... Alors retour en atelier,  installation de suspensions pour les disques, et de ventilateurs 12cm à basse vitesse de rotation. Ne restait donc que ce maudit ventilateur de CPU qui moulinait comme un malade. 
</p>
<!--break-->

	<a name='chapter_1'></a>
  <h2>lm_sensors</h2>
	
<p>
   Il se trouve que c'est le même outil qui permet à la fois de lire les senseurs internes de la bécane et de contrôler certains éléments comme la vitesse de rotation des ventilateurs. Et cet outil c'est <a class='external' target='_blank' href='http://www.lm-sensors.org/' >lm_sensors</a>. Pour l'installer, l'enfance de l'art, il est forcement dans votre dépôt. Donc urpmi/apt-get selon vos tendances. 
</p>
<p>
  Pour le configurer il faut lancer <kbd>sensors-detect</kbd> en tant que root. L'outil va tester toutes les combinaisons bus/puce pour terminer par écrire le paramétrage de ce qu'il aura détecté. Dans le cas de ma Gigabyte P35 - Q6600, il a détecté une puce SuperIO ITE IT8718F et les 4 senseurs de température des 4 coeurs du processeur. 
</p>
<p>
 Ceci fait, un nouveau  service est alors utilisable qui se lance par <kbd>/etc/init.d/lm_sensors start</kbd>. Cela va charger les modules correspondant à ce qui a été trouvé, dans mon cas <kbd>it87</kbd> et <kbd>i2c_i801</kbD>. Ensuite, pour lire les valeurs des capteurs, vous devez lancer la commande <kbd>sensors</kbd>. Apparaissent alors 5 sections, correspondant à ce qui a été trouvé par <kbd>sensors-detect</kbd> :

  <div class='code-block code-block-traces'>
  <div class='container'>
  <div class='command'><span class='prompt'>root#</span>sensors</div><div class='result'>it8718-isa-0290</div><div class='result'>Adapter: ISA adapter</div><div class='result'>in0:       +1.12 V  (min =  +0.00 V, max =  +4.08 V)</div><div class='result'>in1:       +1.90 V  (min =  +0.00 V, max =  +4.08 V)</div><div class='result'>in2:       +3.36 V  (min =  +0.00 V, max =  +4.08 V)</div><div class='result'>in3:       +2.99 V  (min =  +0.00 V, max =  +4.08 V)</div><div class='result'>in4:       +0.26 V  (min =  +0.00 V, max =  +4.08 V)</div><div class='result'>in5:       +0.05 V  (min =  +0.00 V, max =  +4.08 V)</div><div class='result'>in6:       +0.10 V  (min =  +0.00 V, max =  +4.08 V)</div><div class='result'>in7:       +3.10 V  (min =  +0.00 V, max =  +4.08 V)</div><div class='result'>in8:       +3.26 V</div><div class='result'>fan1:     1523 RPM  (min =    0 RPM)</div><div class='result'>fan2:        0 RPM  (min =    0 RPM)</div><div class='result'>fan3:        0 RPM  (min =    0 RPM)</div><div class='result'>fan4:        0 RPM  (min =    0 RPM)</div><div class='result'>temp1:       +51°C  (low  =  +127°C, high =  +127°C)   sensor = thermistor</div><div class='result'>temp2:       +34°C  (low  =  +127°C, high =  +127°C)   sensor = diode</div><div class='result'>temp3:        -2°C  (low  =  +127°C, high =  +127°C)   sensor = thermistor</div><div class='result'>vid:      +0.513 V</div><div class='result'>&nbsp;</div><div class='result'>coretemp-isa-0000</div><div class='result'>Adapter: ISA adapter</div><div class='result'>Core 0:      +43°C  (high =  +100°C)</div><div class='result'>&nbsp;</div><div class='result'>coretemp-isa-0001</div><div class='result'>Adapter: ISA adapter</div><div class='result'>Core 1:      +46°C  (high =  +100°C)</div><div class='result'>&nbsp;</div><div class='result'>coretemp-isa-0002</div><div class='result'>Adapter: ISA adapter</div><div class='result'>Core 2:      +42°C  (high =  +100°C)</div><div class='result'>&nbsp;</div><div class='result'>coretemp-isa-0003</div><div class='result'>Adapter: ISA adapter</div><div class='result'>Core 3:      +42°C  (high =  +100°C)</div><div class='command'><span class='prompt'>root#</span><span class='cursor'>&nbsp;</span></div>
  </div>
  
  </div>
</p>

<p>
  Sur le fond, lm_sensors est un très bon outil, le problème vient plus de la difficulté à le paramétrer. En effet, si vous obtenez une température de CPU de 150°c, ne jetez pas tout de suite votre jus d'orange pour stopper la combustion, c'est sûrement un problème d'échelle. Par exemple dans mon cas, je doute fort qu'il y ait un point sur la carte mère à -2°c.... Pas évident de faire son tris là dedans. 
</p>

<p>
  Le problème vient du fait que les constructeurs ne jouent pas le jeu (oh !), genre ASUS, au hasard, qui ne publie pas les datasheet de ses composants. Du coup les calibrages se font au doigt mouillé. J'ai par exemple un ventillo sur une A7N8X qui est sensé tourner à 88730 rpm... Rassurez-vous, j'ai du ancré le PC au sol <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/wink2.gif" title="Wink" alt="Wink" class="smiley-content"/>
</p>
<p>
   Il faut donc aller trifouiller dans <kbd>/etc/sensors.conf</kbd> pour améliorer un peu les choses. Le meilleur moyen que j'ai trouvé est de redémarrer le PC, noter les valeurs données par le BIOS et opérer les ajustements de retour sous Linux. On peut aussi utiliser un thermomètre infrarouge qui permettra de faire cela avec plus de précision.
</p>


	<a name='chapter_2'></a>
  <h2>sensors.conf</h2>
	
</h2>
<p>
  Pour bien comprendre comment fonctionne le fichiers <kbd>sensors.conf</kbd>, il faut déjà saisir d'où viennent les valeurs qu'il manipule. 
</p>
<p>
  Comme nous l'avons vu plus haut, la fonction <kbd>sensors-detect</kbd> va trouver une série de puces. Chaque puce est relié à une série de capteurs ou de contrôles. Dans le cas de mas Gigabyte, l'outil a trouvé 5 puces, 4 correspondant à la température de chacun des coeurs du CPU (coretemp-isa-XXXX), et un pour le reste des valeurs (it8718-isa-0290). Pour ces deux catégories de puce, nous avons deux pilotes kernel correspondant : <kbd>coretemp</kbd> et <kbd>it87</kbd>. 
</p>
<p>
  Une fois montés en mémoire, ces pilotes vont chacun créer des entrées dans le dossier <kbd>/sys/class/hwmon</kbd>. Dans ce dossier nous allons trouver 5 sous dossiers <kbd>hwmon0</kbd> à <kbd>hwmon4</kbd> : 4 pour <kbd>coretemp</kbd> et 1 pour <kbd>it87</kbd>. 
</p>
<p>
  Dans chaque dossier <kbd>hwmon0-4</kbd>, nous avons un sous-dossier <kbd>device</kbd>. Et dans ce dossier nous avons quelque chose de genre :
  
  <div class='code-block code-block-traces'>
  <div class='container'>
  <div class='command'><span class='prompt'>root#</span>ls /sys/class/hwmon/hwmon0/device/</div><div class='result'>alarms      fan4_min       in3_input  in6_min      pwm2         temp2_input</div><div class='result'>bus@        hwmon:hwmon0@  in3_max    in7_input    pwm2_enable  temp2_max</div><div class='result'>cpu0_vid    in0_input      in3_min    in7_max      pwm2_freq    temp2_min</div><div class='result'>driver@     in0_max        in4_input  in7_min      pwm3         temp2_type</div><div class='result'>fan1_input  in0_min        in4_max    in8_input    pwm3_enable  temp3_input</div><div class='result'>fan1_min    in1_input      in4_min    modalias     pwm3_freq    temp3_max</div><div class='result'>fan2_input  in1_max        in5_input  name         subsystem@   temp3_min</div><div class='result'>fan2_min    in1_min        in5_max    power/       temp1_input  temp3_type</div><div class='result'>fan3_input  in2_input      in5_min    pwm1         temp1_max    uevent</div><div class='result'>fan3_min    in2_max        in6_input  pwm1_enable  temp1_min    vrm</div><div class='result'>fan4_input  in2_min        in6_max    pwm1_freq    temp1_type</div><div class='command'><span class='prompt'>root#</span><span class='cursor'>&nbsp;</span></div>
  </div>
  
  </div>
</p>
<p>
  Comme vous le voyez, tout y est. D'abord la vitesse des ventilateurs (<kbd>fanX_input</kbd>) et la valeur minimum à ne jamais atteindre (<kbd>fanX_min</kbd>). Les <kbd>inX_input</kbd> représentent des tensions avec une valeur min (<kbd>inX_min</kbd>) et max (<kbd>inX_max</kbd>). Enfin les températures (<kbD>tempX_input</kbd>), et la aussi des valeurs min (<kbd>tempX_min</kbd>) et max (<kbd>tempX_max</kbd>). Enfin, nous le verrons un peu plus loin, les <kbd>pwmX</kbd> nous permettrons de changer la vitesse de rotation des ventilateurs.   
</p>
<p>
  Donc si lors de l'exécution de la commande <kbd>sensors</kbd>, vous aviez une vitesse affiché pour <kbd>In1</kbd>, vous pouvez avoir cette vitesse en tapant :
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  &nbsp; <a target="blank" href="http://pwet.fr/man/linux/commandes/cat"><span class="kw2">cat</span></a> <span class="sy0">/</span>sys<span class="sy0">/</span>class<span class="sy0">/</span>hwmon<span class="sy0">/</span>hwmon0<span class="sy0">/</span>device<span class="sy0">/</span>in1_input
  </div>
  
  </div>
</p>
<p>
  La seule chose est que la valeur retournée n'a généralement que peu de rapport avec celle de <kbd>sensors</kbd>. C'est tout l'interêt de <kbd>sensors.conf</kbd>, transformer ces valeurs brute en réalité compréhensibles.  Dans le vocabulaire <kbd>lm_sensors</kbd>, in1_input, fan3_min, pwm2, etc, sont des <kbd>fonctionnalités</kbd> (features). Ce sont ces fonctionnalités que nous allons travailler dans notre fichier de configuration.  
</p>
</kbd>
  Le fichier <kbd>sensors.conf</kbd> est composé de directives :
  <ul>
  	<li><b>chip</b> "nom_1" "nom_2" ... "nom_n", par exemple <kbd>chip "it87-*" "it-8712-*"</kbd>. Cette directive indique que tout ce qui suit jusqu'à la prochaine directive <kbd>chip</kbd> ou la fin du fichier, s'applique aux puces dont le nom commence par <kbd>it87-</kbd> ou <kbd>it-8712</kbd>. Le nom de la puce est celui affiché lorsque vous lancez <kbd>sensors</kbd>.</li>
  	 
  	<li><b>ignore</b> fonctionnalité, par exemple <kbd>ignore temp3</kbd>. Comme son nom l'indique, le but de cette directive est d'indiquer à <kbd>lm_sensors</kbd> que la fonctionnalité est à zapper car généralement elle n'est connecté à rien du tout.</li>
  	
  	<li><b>label</b> fonctionnalité "description", par exemple <kbd>label temp1 "Température du CPU"</kbd>. Ici le but est de donner aux fonctionnalités un nom un peu plus sexy que celui choisi par le pilote.</li>
  	
  	<li><b>set</b> fonctionnalité expression, par exemple <kbd>set temp1_over 60</kbd>. Ici il s'agit de donner à des valeurs du système, typiquement le min et le max d'un capteur. Il est possible de mettre de petites expressions mathématiques qui peuvent même inclure des noms de capteurs. Faites cependant gaffe aux régérences circulaires... Pour que ces valeurs soient prises en compte dans les alarmes, il faut soit lancer <kbd>sensors -s</kbd>, soit redémarrer le service <kbd>lm_sensors</kbd>.</li>
  	
  	<li><b>compute</b> fonctionnalité expression_out expression_in, par exemple <kbd>compute in3 ((6.8/10)+1)*@ ,  @/((6.8/10)+1)</kbd>. Cette directive définir deux expressions permettant respectivement de transformer la valeur brute venant du capteur en valeur lisible, et inversement. Le <kbd>@</kbd> représente la valeur brute dans le premier cas, et une valeur lisible dans le second. C'est ici que tout le jeu se passe pour arriver à trouver la formule la plus proche possible de la réalité. En effet, les puces sont construites pour lire un interval fixe de tensions, par exemple 0 à 5v. Donc pour pouvoir mesurer la tension 12v, le constructeur de la carte mère va ajouter des diviseurs de tension. C'est ce type de magouille que les formules cherchent à caractériser. </li>
</ul>
</p>
<p>
   Comme vous le voyez, il est relativement simple de modifier ce fichier de configuration, un peu moins d'arriver à obtenir les bonnes valeurs si les formules par défaut ne collent pas... 
</p>
<p>
  Prenons le cas de ma puce <kbd>it8718-isa-0290</kbd>. Déjà, je ne trouve pas de directive <kbd>chip</kbd> qui lui correspond. En revanche, j'ai bien un <kbd>chip "it87-*" "it-8712-*"</kbd>. Comme je sais que l'it8718 fait peu ou prou la même chose que l'ensemble de la gamme <kbd>it87</kbd>, je vais donc simplement rajouter ma puce à la liste : <kbd>chip "it87-*" "it-8712-*" "it-8718-*"</kbd>. Ensuite je vais faire un peu de ménage sur les valeurs non pertinentes par <kbd>ignore</kbd>, renommer proprement les fonctionnalités avec <kbd>label</kbd> et bidouiller deux trois formules pour coller avec la réalité. J'ajouterais enfin des directives <kbd>set</kbd> pour fixer les valeurs min et max de certaines valeurs critiques (arrête du ventilateur, CPU en fusion, etc..). 
</p>

<p>
  Au final, on obtiens un résultat de <kbd>sensors</kbd> le plus juste possible. Ensuite il existe de nombreux enrobages graphiques à <kbd>lm_sensors</kbd> comme par exemple le <a class='external' target='_blank' href='http://sensors-applet.sourceforge.net/' >gnome-applet-sensors</a> me permettant de remonter tout cela sur mon bureau.  
</p>

<p>
   Si vous voulez prendre en charge les alarmes, faites un tour sur <kbd>man sensord</kbd>. <kbd>sensord</kbd> est le démon lancé par le service <kbd>lm_sensors</kbd> qui va auditer toutes ces valeurs et vous prévenir si quelque chose part en vrille. En revanche si cette fonctionnalité ne vous intéresse pas, ou si vous monitorez ces valeurs via nagios, il peut être malin d'empêcher le lancement de ce démon en torpillant le fichier <kbd>/etc/init.d/lm_sensors</kbd>.
</p>


	<a name='chapter_3'></a>
  <h2>Contrôle des ventilateurs</h2>
	
<div class='inline-box attention'>
   S'amuser à arrêter un ventillateur sur un processeur en activité est le meilleur moyen pour le faire griller. Ne faites jamais cela plus de 5 secondes, et seulement si vous savez ce que vous faites. 
</div>
<p>
  Maintenant que les valeurs sont au point, il nous reste toujours à réduire la vitesse de nos ventilateurs si bien sur la carte mère le permet. Comme nous l'avons vu plus haut, ce sont les fonctionnalités <kbd>pwmX</kbd> qui sont responsables de ce comportement. Basiquement pour activer le contrôle il faut envoyer une valeur 1 au <kbd>pwmX_enable</kbd> qui va bien, et ensuite une valeur de 0 (arrêt) à 255 (fullspeed) à <kbd>pwmX</kbd>. En somme, si l'on connait le bon <kbd>pwm</kbd>, réduire de moitier la vitesse d'un ventillateur se résume à 
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  <span class="kw3">echo</span> <span class="nu0">1</span> <span class="sy0">&gt;</span> <span class="sy0">/</span>sys<span class="sy0">/</span>class<span class="sy0">/</span>hwmon<span class="sy0">/</span>hwmon0<span class="sy0">/</span>device<span class="sy0">/</span>pwm3_enable<br />
&nbsp; <span class="kw3">echo</span> <span class="nu0">127</span> <span class="sy0">&gt;</span> <span class="sy0">/</span>sys<span class="sy0">/</span>class<span class="sy0">/</span>hwmon<span class="sy0">/</span>hwmon0<span class="sy0">/</span>device<span class="sy0">/</span>pwm3
  </div>
  
  </div> 
<p>
<p>
   Après le jeu est donc de trouver le bon pwm associé au ventilateur que l'on cherche à modérer. Vous pouvez faire cela à la main, ou utiliser <kbd>pwmconfig</kbd> qui est fait pour cela. Ce dernier pour chaque <kbd>fanX</kbd> activé, va tester les <kbd>pwmX</kbd> les uns après les autres jusqu'à trouver celui qui fonctionne. Une fois que vous avez le numéro, vous pouvez faire le reste à la main. 
</p>  
<p>
  Vous pouvez aussi laisser <kbd>pwmconfig</kbd> poursuivre, il vous proposera alors de calibrer la valeur de <kbd>pwm</kbd> avec la vitesse obtenue sur le <kbd>fanX</kbd> correspondant. Ceci fait, il vous permettra de paramétrer un démon appelé <kbd>fancontrol</kbd> que vous pourrez utiliser pour ajuster automatiquement la vitesse avec la température du processeur. 
</p>


	<a name='chapter_4'></a>
  <h2>Et le disque dur ?</h2>
	
<p>
  La température du disque dur ne fait pas parti du domaine de compétence de <kbd>lm_sensors</kbd> mais de celui du système <kbd>S.M.A.R.T.</kbd>. Cette norme de contrôle des disques durs introduite par IBM permet de remonter de l'unité une foultitude d'informations permettant de prévenir les avaries. Et l'une de ces informations est la température. Pour la lire vous avez deux solutions, soit l'artillerie lourde avec <kbd>smartmontools</kbd> et la commande <kbd>smartctl -A /dev/sda</kbd>, ou alors plus simple avec l'utilitaire <kbd>hddtemp</kbd> et la commande <kbd>hddtemp /dev/sda</kbd>.
</p>

	<a name='chapter_5'></a>
  <h2>Conclusion</h2>
	
<p>
   Fin du petit tour d'horizon de ce qu'il est possible de faire avec <kbd>lm_sensors</kbd> et début de la zone de silence <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/smile.gif" title="Smiling" alt="Smiling" class="smiley-content"/>
</p>    ]]></content>
  </entry>
</feed>
