Ajouter du swap à chaud sur son OS.


Le problème

Si comme moi, à l’installation de ton UNIX préféré, tu t’es dis que la partoche de swap c’était pour les faibles, tu risques d’avoir le même problème 😀

En effet, si à la compilation d’un programme quelconque t’endure un lamentable échec qui ressemble à ça :

{standard input}: Assembler messages:
{standard input}:0: Warning: end of file not at end of a line; newline inserted
{standard input}:142: Warning: missing operand; zero assumed
{standard input}:142: Error: .size expression too complicated to fix up
c++: Internal error: Killed: 9 (program cc1plus)
Please submit a full bug report.

C’est que le swap aurait quand même eu une utilité sur ton PC 😀 Enfin, c’est surtout la ligne c++: Internal error: Killed: 9 (program cc1plus) qui nous intéresse là dedans, mais j’ai mises les autres avec pour avoir un contexte. Donc, que nous dis cette ligne ? En gros que le noyau à décidé de killer l’application cc1plus, qui n’est autre que le logiciel utilisé par gcc pour compiler du c++ (g++ donc). En effet, ça n’est pas très pratique, surtout en plein milieu d’une compilation.

J’ai donc essayé de voir pourquoi j’avais ce problème, et grâce à la commande top j’ai vu que juste avant de killer, ma RAM disponible est très vite descendue pour arrivée à 0. Comme j’ai un swap nul, j’en ai déduis que le noyau killait certainement cc1plus parce que l’application poussait le système à sa perte, et donc qu’en fait, c’est un acte héroïque qu’il a fait 🙂

J’ai donc continué ma recherche, et j’ai appris que certaines applications (dont Chromium), demandaient plus de 4Go de RAM pour pouvoir être compliées, et que les erreurs en cas de RAM indisponible étaient les mêmes. J’étais sur une bonne piste donc 😀

La solution

Il y a deux solutions possible : soit je retouche à mes tables de partition pour mettre en place un swap de 5 gigas que j’utiliserai 3 fois par mois… Soit je mets en place un super système de swap dynamique, qui se base sur un fichier plutôt que sur une partition. On choisira… La deuxième solution :p

Je vais vous expliquer comment faire ça depuis FreeBSD 9. C’est en effet, sur cette plate-forme que j’ai expérimenté tout ça.

Dans un premier temps donc, il faut créer le fichier qu’on utilisera pour le swap. Pour ce cas, j’utilise la commande dd :

dd if=/dev/zero of=fichier_swap bs=1024 count=2097152

Comme dit dans le man de dd, l’option if indique de quoi il faut remplir le fichier of. En l’occurrence ici, on remplit of de caractères null. Ce fichier (qui s’appellera fichier_swap, l’attribut de of donc) sera composé de 2 097 152 block (l’option count), et chaque block fera 1024 octets, soit 1 ko (l’option bs). En gros, on créer un fichier de 2 Go composé de vide. C’est con ? Peut être, mais c’est ça notre futur swap \o/

Hé oui, une fois le fichier créé, on doit le définir. Le définir comme étant un système de fichier swap. Pour ce faire, on utilisera la commande mdconfig, qui dans notre cas, s’utilise de cette façon :

mdconfig -a -t swap -f fichier_swap

En gros, comme le dit le man, -a signifie que l’on veut monter un fichier qui devra être considéré par le système d’exploitation comme étant un ”memory disk”. À croire que FreeBSD ne considère pas le stockage « en dur » sur le disque dur comme de la mémoire, parce que ça correspond à justement, de la « mémoire à utiliser pour l’exécution des applications ». Oui, de la RAM ^^

On peut monter de la « fausse ram » pour plusieurs choses : principalement pour du swap, et, plus spécifiquement, comme zone de mémoire réservée aux allocations dynamiques (malloc). Nous dans notre cas, on veut du swap, l’option -t pour « type » prend donc en paramètre swap. Et enfin, l’option -f qui pointe vers le fichier à utiliser pour « mémoire virtuelle ».

Une fois la commande exécutée, elle nous retourne le nom du périphérique montée. À savoir ici md0. Non, le swap ne se monte pas comme un système de fichier normal ^^ Pas de mount, mais un swapon :

swapon /dev/md0

Et voilà ! Votre nouveau swap est près à l’emploi ! Attention cependant, au prochain reboot il ne sera plus utilisé. Le fichier sera encore présent sur le disque, mais il faudra le remonter avec mdconfig et swapon. Je sais qu’il existe un moyen d’automatiser tout ça, mais j’ai plus le courage de chercher là. Je suis trop fatigué, et j’en ai pas l’utilité 😀 Mais si tu connais la réponse, je me ferai une joie de mettre à jour l’article 😉

En résumé, voilà ce que ça donne niveau commande. (Les lignes précédés d’un dièse (#) sont les commandes que j’ai tapée, les autres sont les sorties des programmes. Ce qui suit les doubles-slash(//) sont des commentaires que l’ai rajouté. C’est ni à taper, ni à voir à l’écran, c’est juste des illustrations (Des commentaires quoi :-/)).

#top
last pid: 29928;  load averages:  0.00,  0.00,  0.00                             up 0+01:21:24  01:58:41
50 processes:  1 running, 49 sleeping
CPU:  0.0% user,  0.0% nice,  0.0% system,  0.0% interrupt,  100% idle
Mem: 283M Active, 36M Inact, 269M Wired, 4660K Cache, 213M Buf, 1375M Free
Swap: 
//[...] Affichage tronqué.
//Pas de swap pour le moment : (

//Création du fichier
#dd if=/dev/zero of=fichier_swap bs=1024 count=2097152
2147483648 bytes transferred in 27.236743 secs (78845097 bytes/sec)

//Montage du fichier comme étant une zone de swap
#mdconfig -a -t swap -f fichier fichier_swap
md0

//Configuration de l'OS pour qu'il utilise le swap
#swapon /dev/md0 

//Victoire !
#top 
last pid: 29955;  load averages:  0.00,  0.00,  0.00                             up 0+01:26:22  02:03:39
49 processes:  1 running, 48 sleeping
CPU:  0.0% user,  0.0% nice,  0.0% system,  0.0% interrupt,  100% idle
Mem: 303M Active, 1226M Inact, 356M Wired, 42M Cache, 213M Buf, 40M Free
Swap: 2048M Total, 2048M Free
//[...] Affichage tronqué.
//2Go de swap \o/

Après ça, la compilation est passée comme dans du beurre 🙂