Outils pour utilisateurs

Outils du site


auto-heber:rpi:serveur_archlinux_arm_sur_un_raspberry_pi

La popularité du Rapberry Pi n'est plus à démontrer, d'autant plus que nombre de « gadgets » électronique et de cartes d'interfaces diverses et variées élargissent ses possibilités déjà nombreuses. LinuQ a tout naturellement proposé quelques séances d'activités autours à la découverte du Raspberry PI et l'a tout naturellement adopté pour subvenir à ses besoins. Le présent article se veut un compte rendu de ces séances et d'exposer pas à pas comment avoir un serveur dont la configuration est relativement basique mais suffisante pour les besoin de serveur de fichiers interne d'un GUL.

Le choix du Raspberry Pi

Le Raspberry Pi est loin d'être la seule option présente sur le marché, le Hackberry et le Cubieboard (pour ne citer que ceux là) sont d'autre choix totalement pertinents. Il est cependant peu dispendieux : 35$ USD plus les frais d'envois depuis les États-Unis qui sont à la base d'environ $12 chez Farnell. Par ailleurs LinuQ voulait une solution qui soit à la fois:

  • Compacte et facile à transporter
  • Peu dispendieuse (les moyens d'un GUL sont vite limités, sans compter le risque de vol….) ;
  • Dont les différentes composantes sont courantes (ce qui permet également le recyclage des fond de tiroirs) ;
  • Pouvant fonctionner sous une distribution de Linux dédiée à l'architecture ARM pour laquelle nous avons l'expertise ;
  • Pouvant se connecter à une mémoire de masse (i.e. disque dur USB ou eSATA) et doté d'un moins un port Ethernet RJ-45 ;
  • Prête à l'emploi, incluant le déploiement des mises à jour de paquets
  • Disposant d'un boîtier pré-fabriqué pouvant sécuriser un minimum la carte électronique (de doigts trop curieux…. )

Plusieurs membres du CA de LinuQ avaient commandé des Raspberry Pi lors son annonce en 2011 et voulaient voir comment ce dernier se comporterait lorsqu'il serait utilisé en tant que serveur.

Installation du système d'exploitation archlinux ARM

Ne seront détaillées ici que les étapes les plus importantes.

Récupération de l'image initiale et copie sur une carte SD

Il faut pour commencer récupérer l'image de archlinux ARM dans la section downloads de raspberrypi.org. A ce sujet, nous n'avons jamais été en mesure de faire démarrer notre Raspberry Pi à partir de l'image archlinux-hf-2012-09-18 : obention d'un kernel panic stipulant qu'init n'a pu être trouvé (présence de messages bizarres au sujet du lecteur de SDHC aperçue en un clin d'oeil avant de se retrouver sous kdb). La dernière version de archlinux ARM fonctionnant correctement sur un Raspberry Pi, en date du mois de novembre, est donc du 19 avril 2012 (chercher archlinuxarm-19-04-2012.zip dans Google).

Une fois l'image téléchargée il va vous falloir la décompresser et la copier sur une carte SD. Le lecteur SD est vu soit comme un périphérique bloc SCSI (/dev/SDX) ou comme un périphérique MMC/SD (/dev/mmcblkX) selon votre distribution/matériel.
linux-desktop01 ~# unzip -x archlinuxarm-19-04-2012.zip
Archive: archlinuxarm-19-04-2012.zip creating: archlinuxarm-19-04-2012/ inflating: archlinuxarm-19-04-2012/archlinuxarm-19-04-2012.img.sha1 inflating: archlinuxarm-19-04-2012/archlinuxarm-19-04-2012.img
linux-desktop01 ~# dd if=archlinuxarm/archlinuxarm-19-04-2012.zip of=/dev/sdc && sync

La copie est lente et prend aisément un bon quart d'heure, l'image dé-zippée pesant son 2 Go… Si vous voulez voir où rendu est le processus de copie de limage, il est possible de lui envoyer un signal USR1 depuis un autre terminal avec la commande killall si vous avez la flemme de chercher le PID exact à cibler :
linux-desktop01 ~# killall dd -USR1

Sur le terminal où la commande dd roule, une mention de la taille traitée jusqu'à présent sera affichée:
linux-desktop01 ~# dd if=archlinuxarm/archlinuxarm-19-04-2012.zip of=/dev/sdc && sync
… 3862528+0 records in 3862528+0 records out 1977614336 bytes (2.0 GB) copied, 1411.29 s, 1.4 MB/s …

Une fois la copie achevée, ne retirez pas la carte SD de son lecteur tout de suite nous avons quelques opérations à faire avec :-)

Augmentation de la capacité de la partition racine

Les images disponibles sur raspberrypi.org correspondent à des cartes SD d'une capacité de 2 Go (la capacité est correcte pour un système de base cependant la limite de stockage s'atteint vite si on installe des paquets supplémentaires…). Ces images sont des images 1:1 de cartes et comportent dans tous les cas de figure au moins deux partitions:

linux-desktop01 ~ |commande=fdisk -l /dev/sdc|resultat=Disk /dev/sdc: 7969 MB, 7969177600 bytes 246 heads, 62 sectors/track, 1020 cylinders, total 15564800 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000683dc Device Boot Start End Blocks Id System /dev/sdc1 1 195312 97656 c W95 FAT32 (LBA) /dev/sdc2 197265 3862527 1832631+ 83 Linux

La première partition (Id = 0x0C soit FAT32) d'environ 95 Mo est en VFAT et contient les fichiers nécessaire à l'amorçage du Raspberry Pi sur lesquels nous aurons l'occasion de revenir un peu plus loin. La seconde partition contient la racine du système de fichiers et est, du moins pour les images que nous avons essayées, un système de fichiers ext4 ou ext3. Dans les cas de l'image archlinux que nous utilisons ici, la partition racine est en ext3.

Le hic est que si votre carte SD fait 4 Go ou plus, vous perdez au bas mot 50% de sa capacité ! Le système de fichiers contenu dans la seconde partition de la carte SDHC n'étant pas automatiquement agrandi. Avant d'aller plus loin, procédons à cet agrandissement. Gparted étant trop facile d'approche, voici une occasion de faire une manipulation totalement inélégante mais qui reste digne d'un membre d'un Groupe d'Utilisateur Linux.

Avant toute autre chose, il faut demander au noyau de refraîchir les partitions qu'il connaît et le faire seulement pour ce qui est contenu sur notre unité de carte SDHC vue ici comme /dev/sdc puis s'assurer que deux partitions sont vues sur ce périphérique bloc:

linux-desktop01 ~ |commande=partprobe /dev/sdc linux-desktop01 ~ |commande=cat /proc/partitions | grep sdc|resultat= 8 32 7782400 sdc 8 33 97656 sdc1 8 34 1832631 sdc2

A ce stade il faut forcer une vérification du système de fichiers situé sur /dev/sdc2 qui ne contient en principe aucune erreur:

linux-desktop01 ~ |commande=e2fsck -f /dev/sdc2|resultat=e2fsck 1.42.6 (21-Sep-2012) Pass 1: Checking inodes, blocks, and sizes Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information /dev/sdc2: 32264/114688 files (0.1% non-contiguous), 131392/458157 blocks

Notez que si vous obtenez:

linux-desktop01 ~ |commande=e2fsck -f /dev/sdc2|resultat=e2fsck 1.42.6 (21-Sep-2012)|resultat=e2fsck: Superblock invalid, trying backup blocks… e2fsck: Bad magic number in super-block while trying to open /dev/sdc2 The superblock could not be read or does not describe a correct ext2 filesystem. If the device is valid and it really contains an ext2 filesystem (and not swap or ufs or something else), then the superblock is corrupt, and you might try running e2fsck with an alternate superblock: e2fsck -b 8193 <device>

Il est possible que le noyau ait conservé en mémoire le partitionnement d'une carte SDHC qui vous avez préalablement utilisée, tentez de faire un partprobe comme indiqué ci-dessus (votre image peut aussi être corrompue…). Si tout va pour le mieux dans le meilleur des mondes, il ne reste pour cette étape plus qu'à procéder à l’agrandissement de la seconde partition. Plusieurs outils existent pour agrandir des partitions ext4 dont le désormais bien connu gparted sauf que voila non seulement c'est trop simple mais en plus il se peut que vous n'avez pas gparted sous la main. Une alternative consiste par exmeple à utiliser parted ou fdisk et leur faire effacer la géométrie de la seconde partitions de la carte SDHC pour la recréer en utilisant le maximum d'espace disponible en commençant à l'exact même emplacement:

Dans le cas de parted (noter l'usage de l'unité 's' pour sector et prêter attention au refus d'alignement lors du mkpart) :

linux-desktop01 ~ |commande=parted /dev/sdc|resultat=GNU Parted 3.1 Using /dev/sdc Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) unit s (parted) print Model: Generic- SD/MMC (scsi) Disk /dev/sdc: 15564800s Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 1s 195312s 195312s primary fat16 lba 2 197265s 3862527s 3665263s primary ext3 (parted) rm 2 (parted) mkpart primary ext3 197265 100% Warning: The resulting partition is not properly aligned for best performance. Ignore/Cancel? i <—- Attention répondre 'i' pour ignorer l'alignement proposé (parted) print Model: Generic- SD/MMC (scsi) Disk /dev/sdc: 15564800s Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 1s 195312s 195312s primary fat16 lba 2 197265s 15564799s 15367535s primary ext3 (parted) quit

Attention ne vous trompez-pas, il ne faut surtout pas utiliser la commande mkpartfs de parted faute de quoi, un nouveau système de fichier flambant neuf sera créé et il vous voudra donc recommencer la copie de l'image de la carte SDHC avec dd…. Par ailleurs, refusez l'alignement de la seconde partition lorsque mkpart vous le demande car la partition que vous venez de créer doit commencer exactement au même endroit que celle que vous avez supprimée. Par acquis de conscience il est conseillé de faire une petite vérification : linux-desktop01 ~ |commande=e2fsck -f /dev/sdc2|resultat=e2fsck 1.42.6 (21-Sep-2012) Pass 1: Checking inodes, blocks, and sizes Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information Le système de fichier étant intègre, il reste à l'agrandir: linux-desktop01 ~ |commande=resize2fs -p /dev/sdc2|resultat=resize2fs 1.42.6 (21-Sep-2012) Resizing the filesystem on /dev/sdc2 to 1920941 (4k) blocks. Begin pass 1 (max = 45) Extending the inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX The filesystem on /dev/sdc2 is now 1920941 blocks long. Et voila! Nous sommes passés dans notre cas d'un système de fichier racine de 2 Go à un système de fichiers de 8 Go :-)

Et l'espace d'échange dans tout celà ?

Nous n'avons pas créé une partition dédiée à l'espace d'échange pour une raison bien simple: les cartes SDHC sont limitées dans leur cycle d'écriture (~100 000) et il n'y pas à notre connaissance pour le moins de répartition d'usure des cellules mémoire comme c'est le cas sur un disque SSD. De plus l'écriture sur une carte SDHC reste une opération relativement lente. Mieux vaut dédier un espace sur une mémoire de masse comme un disque dur externe qui n'est pas sujet à ce genre de limite.

Feu!!

La carte SD est prête ! Il faut l'insérer dans le Raspberry Pi et allumer ce dernier, si vous va bien vous devriez arriver au prompt demandant le login (qui est root sur les images archarm) et le mot de passe (qui est également root). Par ailleurs :

  • L'image archman comporte un démon OpenSSH qui est lancé automatiquement au démarrage et qui est configuré pour accepter directement un login sous le compte root
  • La configuration de l'adressage réseau est automatique (DHCP) par défaut à moins d'éditer le fichier /etc/rc.conf de l'image
  • La variable noyau net.ipv4.icmp_echo_ignore_broadcasts est mise par défaut à 1 ce qui fait que le Raspberry Pi ne répondra pas à un ping sur une adresse de broadcast à moins d'éditer le fichier /etc/sysctl.conf de l'image et changer cette valeur pour 0 (zéro).

Aussi est-t'il bien plus simple de soit travailler en console sur le Raspberry Pi au travers du port série sur les broches GPIO ou bien avec un clavier USB et un écran branché sur la prise HDMI. Dans notre cas de figure, nous avons tout simplement édité le fichier /etc/rc.conf de l'image archlinux ARM pour adopter une configuration réseau statique (attention aux plages de vos serveurs DHCP sur le LAN!). Le fichier est largement commenté et ne devrait pas poser de problèmes. A titre indicatif les modifications que nous y avons apportés à ce stade se situent au niveau de la ligne 5 (changement du fuseau horaire) ainsi que la configuration en IP statique qui est effectuées au niveau des lignes 11 à 16 de l'extrait ci-dessous:

/etc/rc.conf

LOCALE=“en_US.UTF-8” \ DAEMON_LOCALE=“no” \ HARDWARECLOCK=“UTC” \ TIMEZONE=“America/Montreal” \ KEYMAP=“us” \ CONSOLEFONT= \ CONSOLEMAP= \ USECOLOR=“yes” \ … \ Configuration réseau statique \ interface=eth0 \ address=192.168.1.245 \ netmask=255.255.255.0 \ broadcast=192.168.1.255 \ gateway=192.168.1.1 …

Une fois la session SSH ouverte sur le Raspberry Pi:

invite=raspi ~ |commande=df -h|resultat=Filesystem Size Used Avail Use% Mounted on rootfs 7.3G 487M 6.4G 7% / /dev/root 7.3G 487M 6.4G 7% / devtmpfs 61M 0 61M 0% /dev run 61M 144K 61M 1% /run shm 61M 0 61M 0% /dev/shm /dev/mmcblk0p1 96M 35M 61M 37% /boot

Retour vers le futur

Le Raspberry Pi n'ayant pas d'horloge RTC incluse il est donc incapable de conserver la date/heure une fois éteint ou redémarré. Pour s'en convaincre:

raspi ~# date +“%s”; date -u; w

585 Thu Jan 1 00:09:45 UTC 1970 19:09:45 up 9 min, 1 user, load average: 0.97, 0.76, 0.49 USER TTY LOGIN@ IDLE JCPU PCPU WHAT root pts/0 19:03 0.00s 0.24s 0.02s w

Effectivement nous sommes bien le 1er Janvier 1970 ou du moins le 31 décembre 1969 au Canada avec le décalage horaire ;-) La toute première tâche est de mettre le Raspberry Pi à date et heure correcte et il existe deux moyens:

  1. Mettre la date à la main avec date -s ;
  2. Laisser faire à la commande ntpdate le sale boulot ;

Malheureusement l'archive que nous utilisons a un léger souci avec NTP:

  1. les scripts de démarrage font référence au démon NTP dopenntp
  2. il n'y pas de fichier openntpd mais juste un fichier ntpd :-(

Qu'à cela ne tienne nous y reviendrons plus loin, pour le moment la date mise à la main est suffisante (exemple!)

raspi ~# date -s “Thu Nov 8 23:49:35 EST 2012”

Thu Nov 8 23:49:35 EST 2012

Sélection du miroir de dépôt de paquets

Le gestionnaire de paquets pacman est paramétré à base pour solliciter l'hôte mirror.archlinuxarm.org. Ce serveur n'existe en fait pas réellement et est résolu sur plusieurs adresses IP correspondants à des serveurs différents en fonction de la « situation géographique » de votre adresse IPv4 publique (GeoIP) afin de répartir la charge réseau:

raspi ~# nslookup mirror.archlinuxarm.org

Server: 192.168.1.2 Address: 192.168.1.2#53 Non-authoritative answer: Name: mirror.archlinuxarm.org Address: 208.97.140.21 Name: mirror.archlinuxarm.org Address: 67.23.118.182 Name: mirror.archlinuxarm.org Address: 69.55.55.2

Etant donné que nous hébergeons à l'interne un mirroir archlinux ARM qui est régulièrement mis à jour, nous devons paramétrer pacman pour l'utiliser. Dans notre cas le miroir est situé sur un disque externe USB branché sur le Raspberry Pi et qui a été monté sur /mnt. Pour ce faire il faut modifier le fichier /etc/pacman.d/mirrorlist et y ajouter ne nécessaire (dans notre cas nous y avons ajouté une déclaration figurant aux lignes 9 et 10) :

# Arch Linux ARM repository mirrorlist \ # Generated on 2012-02-04 \ # \ \ ## Geo-IP based mirror selection \ #Server = http://mirror.archlinuxarm.org/arm/$repo

# Mirroir interne
Server = file:/mnt/archlinuxarm/arm/$repo

## IPv6
# Server = http://6.mirror.archlinuxarm.org/arm/$repo

### Mirrors by country

### Germany
# Server = http://eu.mirror.archlinuxarm.org/arm/$repo
# Server = http://6.eu.mirror.archlinuxarm.org/arm/$repo

### United States
## IL
# Server = http://us.mirror.archlinuxarm.org/arm/$repo
## VA
# Server = http://va.us.mirror.archlinuxarm.org/arm/$repo
Fichier '/etc/pacman.d/mirrorlist

Le coeur du Raspberry Pi est un System on Chip (SoC) comportant en son sein un processeur ARM1176JZF-S qui est de la famille ARM11, une branche dérivée de l'architecture ARM v6. Il loin d'être dramatique de conserver référence vers les paquets ARM v5 du miroir car l'ARM11 est rétro-compatible et cela va nous simplifier en plus l'existance lors de la mise à jour initiale des paquets logiciels installés sur le Rasbbbery Pi. Il faut par ailleurs vérifier le contenu du fichier /etc/pacman.conf et s'assurer que les dépôts core, community, alarm et aur sont dé-commentés: \ … \ [core] \ #SigLevel = PackageRequired \ Include = /etc/pacman.d/mirrorlist \ \ [extra] \ #SigLevel = PackageOptional \ Include = /etc/pacman.d/mirrorlist \ \ [community] \ #SigLevel = PackageOptional \ Include = /etc/pacman.d/mirrorlist \ \ [alarm] \ #SigLevel = PackageOptional \ Include = /etc/pacman.d/mirrorlist \ \ [aur] \ #SigLevel = PackageOptional \ Include = /etc/pacman.d/mirrorlist \ … \ Fichier /etc/pacman.conf

Mise à jour initiale

Le grand moment est arrivé ! Nous allons procéder à la mise à jour de l'instance d'archlinux installée sur le Raspberry Pi. Glissez la carte mémoire sur laquelle vous avez copié l'image archlinux ARM dans le slot SDHC du Rapberry Pi et mettez le en marche. Si vous avez branché le Raspberry Pi sur un écran avec un cable HDMI, vous devriez voir une série de messages défiler avant d'attérir sur l'invite de login:

Arch Linux 3.1.9-11+ (tty1) pi login:_

Le seul compte existant est root (le mot de passe est root) et c'est ce compte que nous allons utiliser sur le Raspberry Pi pour l'article. Petit rappel: un démon SSH est également disponible et accepte directement le compte root.

Accroissement de la capacité mémoire (Raspberry Pi avec 256 Mo de mémoire seulement aka Raspberry v1)

L'image archlinux ARM datée du 19 Avril 2012 est configurée par défaut pour que la mémoire du Raspberry Pi soit divisée à part égale entre le CPU et le GPU (i.e. le CPU dispose de 128 Mo de mémoire et le GPU de 128 Mo également). Il est souhaitable de modifier cette allocation pour que le GPU ne conserve qu'une part très limitée de la mémoire ce qui est effectué comme suit :

~ # cd /boot

raspi ~ /boot# ls -l

total 35548 -rwxr-xr-x 1 root root 2029764 Apr 18 2012 arm128_start.elf <— 128 CPU / 128 GPU -rwxr-xr-x 1 root root 2029764 Apr 18 2012 arm192_start.elf <— 192 CPU / 64 GPU -rwxr-xr-x 1 root root 2029764 Apr 18 2012 arm224_start.elf <— 224 CPU / 32 GPU -rwxr-xr-x 1 root root 16528 Apr 18 2012 bootcode.bin -rwxr-xr-x 1 root root 218 Apr 18 2012 cmdline.txt -rwxr-xr-x 1 root root 28 Apr 18 2012 config.txt -rwxr-xr-x 1 root root 5915380 Apr 18 2012 kernel_debug.img -rwxr-xr-x 1 root root 16412020 Apr 18 2012 kernel_emergency.img -rwxr-xr-x 1 root root 5606532 Apr 18 2012 kernel.img -rwxr-xr-x 1 root root 314691 Apr 18 2012 loader.bin -rwxr-xr-x 1 root root 2029764 Nov 9 17:26 start.elf

Ce n'est pas forcément intuitif mais la clé réside dans le fichier start.elf: ce fichier est en fait une copie d'un des trois armXXX_start.elf (pas de lien symbolique possible, /boot étant contenu dans un système de fichiers vfat, vérifiez avec la commande mount pour vous en convaincre). Pour savoir à quel fichier start.elf correspond réellement, vous pouvez calculer leur hash MD5:

raspi ~ /boot# md5sum *start.elf

2477efed8f3bdfa62a62541bea03e241 arm128_start.elf 67cc4275f5f3ad287d47382ba73cf7fe arm192_start.elf e6eac09788ce3c3678107623055a8cea arm224_start.elf 2477efed8f3bdfa62a62541bea03e241 start.elf <— Identique à arm128_start.elf

Vu que nous souhaitons le maximum de mémoire pour le CPU, on écrase start.elf avec arm224_start.elf et on redémarre le Raspberry Pi (il n'est pas possible d'influer sur la répartition de l'allocation dynamiquement):

/boot# cp -f arm224_start.elf start.elf

/boot# reboot

Une fois le Raspberry Pi redémarré, ouvrez une session comme root et vérifiez avec la commande free la taille de la mémoire totale disponible (Mem total) soit de 216 Mo. C'est un peu moindre que 224 Mo, ce qui est tout à fait normal si on pense à la mémoire utilisée par le noyau :

raspi ~# free -m

total used free shared buffers cached Mem: 216 204 11 0 29 150 -/+ buffers/cache: 25 191 Swap: 0 0 0

Rafraîchissement des bases de données de dépôts

A présent que nous avons assez de mémoire disponible, nous pouvons nous attaquer à la mise à jour qui commence par un rafraîchissement des base de données locales de chacun des dépôts utilisés:

raspi ~# pacman -Sy

:: Synchronizing package databases… core 35.4 KiB 5.63M/s 00:00 [#######################################################] 100% extra 404.0 KiB 7.94M/s 00:00 [#######################################################] 100% community 389.5 KiB 9.19M/s 00:00 [#######################################################] 100% alarm 4.9 KiB 4.41M/s 00:00 [#######################################################] 100% aur 11.0 KiB 4.36M/s 00:00 [#######################################################] 100%

La passe de la ruse du coyote qui pue

Attention

Avant de poursuivre la lecture de cette section, il est recommandé de faire une copie de votre carte SDHC (arrêter au préalable le Raspberry Pi avec la commande halt ou shutdown -h now avant de retirer la carte du lecteur SD bien évidemment…) à l'aide de la commande dd sur une machine tierce. Advenant un problème vous aurez juste à restaurer votre sauvegarde sur la carte SDHC.

Remettez ensuite la carte dans le Raspberry Pi et rallumez-le. Advenant qu'une des opérations ci-après flingue l'installation votre instance d'archlinux ARM, vous pourrez repartir de l'image sauvegardée sans avoir à tout refaire du début. Revenons à présent à nos moutons ! La démarche expliquée dans ce paragraphe est beaucoup plus empirique que scientifique et a en gros le déroulement suivant:

  1. Mise à jour du kernel et firmware du Raspberry Pi
  2. Clonage de la carte SDHC sur une seconde carte SDHC (constituant ainsi un environnement stand-by qui sera manipulé sans risque)
  3. Mise à jour de tous les paquets possibles de l’environnement standby
  4. Purge de tous les paquets restant ayant des fichiers dans le répertoire /lib de l’environnement standby (incluant la glibc)
  5. Mise à jour de tous les paquets restant de l'envrionnement standby

Le véritable défi de cette section est de résoudre une série de dépendances de paquets sur la glibc et dont la résolution est un peu ardue. Pour ne rien arranger, la version 3.1.9 du noyau Linux semble être plombée par un bogue bizarre: un oops « Unable to handle kernel paging request at virtual address 90804063 » (l'adresse mémoire est constante) lorsque pacman déploie certains paquets dont coreutils et binutils:

Unable to handle kernel paging request at virtual address 90804063 pgd = c5060000 [90804063] *pgd=00000000 Internal error: Oops: 5 [#1] Modules linked in: evdev hid_logitech snd_bcm2835 snd_pcm snd_page_alloc snd_timer snd CPU: 0 Not tainted (3.1.9-11+ #4) pc : [<c0464dec>] lr : [<c00737bc>] psr: 60000013 sp : c7a15ee0 ip : c6f67840 fp : c7a15f2c r10: c6f67840 r9 : 4013f000 r8 : 00033000 r7 : 00043000 r6 : 4010c000 r5 : c6e96900 r4 : c6e96900 r3 : 00043000 r2 : 00033000 r1 : 00000013 r0 : 90804063 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user (…) —[ end trace f0961e4545c69daf ]—

Mise à jour du noyau et des firmwares du Raspberry Pi

Allons y! La première étape consiste, comme vu plus haut à mettre à jour le noyau et le firmware du Raspberry Pi. Commençons par faire une copie de secours des fichiers /boot/cmdline.txt et /boot/config.txt (effacés par la mise à jour) dans le répertoire /root : raspi ~# cp /boot/cmdline.txt /root raspi ~# cp /boot/config.txt /root A présent procédons à la mise à jour proprement dite (ne mettez pas à jour pacman ): raspi ~# pacman -S raspberrypi-firmware linux-raspberrypi :: The following packages should be upgraded first : pacman :: Do you want to cancel the current operation :: and upgrade these packages now? [Y/n] n <—- Refusez la mise à jour de pacman resolving dependencies… looking for inter-conflicts… Targets: linux-raspberrypi-3.2.27-13 raspberrypi-firmware-20121021-1 Total Download Size: 25.21 MiB Total Installed Size: 37.35 MiB Net Upgrade Size: -40.21 MiB Proceed with installation? [Y/n] y :: Retrieving packages from core.. (…) »> Updating module dependencies. Please wait … ERROR: could not open directory /lib/modules/3.2.27-13-ARCH+: No such file or directory FATAL: could not search modules: No such file or directory »>Edit /boot/cmdline.txt and add sdhci-bcm2708.cycle_delay=1000 Ne vous inquiétez pas des erreurs pour le moment, il est tout à fait normal que depmod échoue car les modules noyau sont placés dans le répertoire /usr/lib/modules au lieu de /lib/modules et depmod ne cherche pas le premier s'il trouve le second. Qu'a cela ne tienne, créons un lien symbolique qui rendra depmod heureux puis rafraîchissons les dépendances des modules du noyau fraîchement mis à jour (3.2.27-13-ARCH+ ici) : raspi ~# ln -s /usr/lib/modules/3.2.27-13-ARCH+ /lib/modules raspi ~# depmod -a 3.2.27-13-ARCH+ Assurez-vous ensuite que /boot/cmdline.txt contienne (une seule ligne, il est possible que le fichier ait été effacé lors de la mise à jour): sdhci-bcm2708.cycle_delay=1000 smsc95xx.turbo_mode=N dwc_otg.dma_enable=1 dwc_otg.dma_burst_size=256 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 loglevel=2 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait Fichier /boot/cmdline.txt \ Petite particulier intéressante: le firmware du Raspberry Pi qui a été mis à jour à l'instant est daté du mois d'octobre 2012 et change quelque peu la manière de paramétrer l'allocation mémoire entre le CPU et le GPU. La quantité de mémoire CPU/GPU ne change plus en recopiant un des fichiers armXXX_start.elf sur start.elf comme nous l'avions fait quelques paragraphes plus tôt mais en spécifiant un paramètre nommé gpu_mem dans le fichier /boot/config.txt (les fichiers armXXX_start.elf ont été d'ailleurs effacés de /boot).

Information

La page « Liste des paramètres du micrologiciel du Raspberry Pi » existant dans la dompe dresse la liste des options possibles pour le fichier /boot/config.txt.


Ainsi pour limiter à 16 Mo la mémoire dédiée au GPU (recommandé pour un usage serveur), spécifiez ceci dans /boot/config.txt Puis redémarrez le Raspberry Pi:

# 16 Mo est la plus petite quantité de mémoire qu'il est possible d'allouer au GPU

# En pratique cela donne ~230Mo de mémoire à disposition du CPU dont ~200 Mo de libre.

gpu_mem=16

Fichier /boot/cmdline.txt

Pour tout le reste de cet article, il est fortement recommandé de brancher un écran sur la prise HDMI du Raspberry Pi ou d'utiliser le port RS-232 disponible sur les broches GPIO de carte mère du Raspberry Pi afin de surveiller ce qui se passe sur la console. Sachez au sujet des broches RS-232 disponible sur le connecteur GPIO du Raspberry Pi que ces dernières fonctionnent en 3.3V et non en 5V (fatal pour l'électronique). Si bricoler un adaptateur est hors de vos compétences en électronique, il existe des câbles prêts à l'emploi USB/RS-232 dédiés au Raspberry en vente chez Newark/Element14 (Farnell) et AdaFruit pour une somme modique d'environ $10.

Le Raspberry Pi ne devrait normalement pas avoir de problèmes pour redémarrer et vous devriez retrouver en moins d'une minute le l'invite de login sur la console (et la possibilité d'ouvrir une session SSH). Avant d'aller plus en avant, nous allons avoir besoin d'arrêter le Raspberry Pi (proprement !) pour constituer un clone de la carte SDHC qui nous servira d'environnement stand-by qui subira lui toutes les modifications, la carte SDHC originale constituera l'environnement live qui demeurera inchangé dans la suite des opérations. Bien évidemment avoir une copie de la carte quelque part est une bonne idée, au cas où quelques chose se passe mal et qu'il faille remettre l'environnement standby dans son état initial.

La copie binaire 1:1 exacte de la carte SDHC originale est effectuée par:

linux-desktop01 ~# dd if=/dev/sdc of=/root/archlinux-arm-apres-maj-noyau.dd

La copie de l'image précédemment constituée sur la carte SDHC servant d'environnement standby s'effectue par:

linux-desktop01 ~# dd if=/root/archlinux-arm-apres-maj-noyau.dd of=/dev/sdc

Mise à jour intégrale de l'environnement standby (première partie)

La partie la plus délicate de l'opération commence, n'allez pas trop vite il est facile de sauter une étape ! Le Raspberry Pi étant éteint :

  1. Glissez une carte SDHC dans le slot SD du Raspberry Pi (le contenu de la première carte SDHC venant d'être dupliqué sur la seconde carte SDHC seconde, les deux cartes ont un contenu identique)
  2. Glissez la seconde carte SDHC dans un lecteur USB de cartes SD/MMC que vous branchez à son tour dans une des deux prises USB du Raspberry Pi

Démarrez ensuite le Raspberry Pi, ouvrez une session sous le compte root soit au travers de SSH soit directement sur la console et à l'aide de la commande lsblk vérifiez ce qui est vu comme périphérique bloc :

raspi ~# lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT mmcblk0 179:0 0 7.4G 0 disk ├─mmcblk0p1 179:1 0 95.4M 0 part /boot └─mmcblk0p2 179:2 0 7.3G 0 part / sda 8:0 1 7.4G 0 disk ├─sda1 8:1 1 95.4M 0 part └─sda2 8:2 1 7.3G 0 part

Ici tout va pour le mieux, le lecteur USB MMC/SD raccordé au Raspberry Pi est vu comme étant /dev/sda le lecteur MMC/SD interne du Raspberry Pi restant /dev/mmcblk0. A présent il faut monter les partitions /dev/sda1 et /dev/sda2 (carte SDHC standby) sous un point de montage (son nom importe peu):

raspi ~# mount /dev/sda2 /mnt

raspi ~# mount /dev/sda1 /mnt/boot

Les deux partitions montées, la première série de mise à jour sur la carte standby s'effectuant comme suit (la liste des paquets va fort possiblement différer un peu dans votre cas, par contre ne mettez pas à jour pacman lorsque demandé) :

raspi ~# pacman -b /mnt/var/lib/pacman -r /mnt -Su –ignore glibc

:: The following packages should be upgraded first : pacman :: Do you want to cancel the current operation :: and upgrade these packages now? [Y/n] n <— Répondre NON ici :: Starting full system upgrade… warning: glibc: ignoring package upgrade (2.15-7 ⇒ 2.16.0-5) :: Replace libusb with core/libusbx? [Y/n] y <— Répondre OUI ici :: Replace libusb with core/libusbx? [Y/n] y <— Répondre OUI ici :: Replace procps with core/procps-ng? [Y/n] y <— Répondre OUI ici :: Replace udev with core/systemd? [Y/n] y <— Répondre OUI ici resolving dependencies… warning: ignoring package glibc-2.16.0-5 warning: cannot resolve “glibc>=2.16”, a dependency of “binutils” warning: ignoring package glibc-2.16.0-5 warning: cannot resolve “glibc>=2.16”, a dependency of “gcc-libs” warning: ignoring package glibc-2.16.0-5 (…) :: The following packages cannot be upgraded due to unresolvable dependencies: binutils ca-certificates coreutils cronie cryptsetup curl db dbus-core device-mapper e2fsprogs filesystem gcc-libs glib2 gmp grep inetutils initscripts iproute2 iputils krb5 less libarchive libldap libssh2 linux-raspberrypi logrotate lvm2 mkinitcpio openntpd openssh openssl pacman pam pcre perl shadow syslog-ng sysvinit systemd util-linux wget wpa_supplicant xfsprogs Do you want to skip the above packages for this upgrade? [y/N] y <– Répondre OUI ici looking for inter-conflicts… Targets (51): acl-2.2.51-2 alsa-lib-1.0.26-1 alsa-utils-1.0.26-1 attr-2.4.46-2 bash-4.2.039-1 bzip2-1.0.6-4 cracklib-2.8.19-1 dhcpcd-5.6.2-1 dialog-1.1_20120706-1 fuse-2.9.1-1 gnupg-2.0.19-2 gzip-1.5-1 hwids-20121022-1 iana-etc-2.30-3 kbd-1.15.3-3 keyutils-1.5.5-3 kmod-10-2 libcap-2.22-3 libedit-20120601_3.0-1 libffi-3.0.11-1 libgssglue-0.4-1 libidn-1.25-1 libnl-3.2.11-1 libpcap-1.3.0-1 libpipeline-1.2.2-1 libusb-1.0.8-2 [removal] libusb-compat-0.1.4-2 libusbx-1.0.14-1 linux-api-headers-3.6.3-1 linux-headers-raspberrypi-3.2.27-13 man-db-2.6.3-1 man-pages-3.43-1 mdadm-3.2.6-1 mkinitcpio-busybox-1.20.2-1 net-tools-1.60.20120804git-2 ntfs-3g-2012.1.15-3 pacman-mirrorlist-20120916-1 pciutils-3.1.10-1 pinentry-0.8.2-1 popt-1.16-5 ppp-2.4.5-5 procps-3.2.8-4 [removal] procps-ng-3.3.5-1 psmisc-22.19-1 readline-6.2.004-1 run-parts-4.3.4-1 sysfsutils-2.1.0-8 tzdata-2012h-1 usbutils-006-1 xz-5.0.4-1 zlib-1.2.7-1 Total Installed Size: 169.07 MiB Net Upgrade Size: -38.71 MiB Proceed with installation? [Y/n] y <— Répondre OUI ici ;) (51/51) checking package integrity [#################################################] 100% (51/51) loading package files [#################################################] 100% (51/51) checking for file conflicts [#################################################] 100% (….)

Patientez quelques minutes le temps que pacman charge et déploie ce premier lot de mises à jour.

Purge des paquets ayant des fichiers dans /lib (incluant la glibc 2.15)

L'étape suivante consiste à faire un repérage de tous les paquets installés sur la carte standby qui ont des fichiers dans le répertoire /lib (copie de cette liste est enregistrée dans le fichier /root/liste-lib.txt):

raspi ~# grep '^lib/' /mnt/var/lib/pacman/local/*/files | cut -d / -f 7 | uniq | tee /root/liste-lib.txt

cryptsetup-1.4.1-1 device-mapper-2.02.95-1 e2fsprogs-1.42.1-1 filesystem-2012.2-4 glibc-2.15-7 lvm2-2.02.95-1 pam-1.1.5-2 pcmciautils-017-1 udev-182-1 xfsprogs-3.1.8-1

La glibc 2.15 étant leur dépendance commune, il va falloir la supprimer (notez l'usage de la sous-option dd pour s'affranchir totalement des dépendances) :

raspi ~# pacman -b /mnt/var/lib/pacman -r /mnt -Rdd glibc

warning: glibc is designated as a HoldPkg. HoldPkg was found in target list. Do you want to continue? [y/N] y Targets: glibc-2.15-7 Total Removed Size: 32.93 MiB Do you want to remove these packages? [Y/n] y (1/1) removing glibc (…)

Même chose pour tous les autres paquets mentionnés dans le fichier /root/ que nous avons créé précédemment (il est possible de combiner les deux opération de suppression en une seule), ignorez le message d'erreur « call to execv failed … command failed to execute correctly » :

raspi ~# pacman -b /mnt/var/lib/pacman -r /mnt -Rdd cryptsetup device-mapper e2fsprogs filesystem lvm2 pam pcmciautils udev xfsprogs

Targets : cryptsetup-1.4.1-1 device-mapper-2.02.95-1 e2fsprogs-1.42.1-1 filesystem-2012.2-4 lvm2-2.02.95-1 pam-1.1.5-2 pcmciautils-017-1 udev-182-1 xfsprogs-3.1.8-1 Total Removed Size: 16.70 MiB Do you want to remove these packages? [Y/n] y (1/9) removing xfsprogs [#######################################################] 100% (2/9) removing pcmciautils [#######################################################] 100% (3/9) removing pam [#######################################################] 100% (4/9) removing lvm2 [#######################################################] 100% (5/9) removing filesystem [#######################################################] 100% warning: /mnt/etc/shells saved as /mnt/etc/shells.pacsave warning: /mnt/etc/shadow saved as /mnt/etc/shadow.pacsave warning: /mnt/etc/securetty saved as /mnt/etc/securetty.pacsave warning: /mnt/etc/resolv.conf saved as /mnt/etc/resolv.conf.pacsave warning: /mnt/etc/passwd saved as /mnt/etc/passwd.pacsave warning: /mnt/etc/ld.so.conf saved as /mnt/etc/ld.so.conf.pacsave warning: /mnt/etc/gshadow saved as /mnt/etc/gshadow.pacsave warning: /mnt/etc/group saved as /mnt/etc/group.pacsave warning: /mnt/etc/fstab saved as /mnt/etc/fstab.pacsave call to execv failed (No such file or directory) <—- /!\Ignorez cette erreur error: command failed to execute correctly <—- Idem (6/9) removing e2fsprogs [#######################################################] 100% (7/9) removing cryptsetup [#######################################################] 100% (8/9) removing device-mapper [#######################################################] 100% (9/9) removing udev [#######################################################] 100%

Revérifions combien de paquets ont encore des fichiers dans le répertoire /lib :

raspi ~# grep '^lib/' /mnt/var/lib/pacman/local/*/files | wc -l

0

Zéro? Parfait! Normalement il ne devrait plus rien rester dans le répertoire /lib de la carte standby à l'exception le lien symbolique vers les modules du noyau (3.2.27 dans notre cas) que nous avions précédemment créé:

raspi ~# ls -lR /mnt/lib

/mnt/lib: total 4 drwxr-xr-x 2 root root 4096 Jan 1 01:16 modules /mnt/lib/modules: total 0 lrwxrwxrwx 1 root root 32 Nov 9 2012 3.2.27-13-ARCH+ → /usr/lib/modules/3.2.27-13-ARCH+

Si d'autres fichiers existent, il faut identifier les paquets auxquels ils appartiennent puis supprimer ces paquets en utilisant l'option -Rdd de pacman pour ignorer totalement les dépendances). L'identification des paquets rattachés aux fichiers situés le répertoire /lib de la carte standby s'effectue par:

raspi ~# find /mnt/lib -exec pacman -b /mnt/var/lib/pacman -r /mnt -Qo – {} +

Une fois le ménage terminé ou si le répertoire /lib de la carte standby était déjà vide, il reste à supprimer ce dernier:

raspi ~# pi # rm -rf /mnt/lib

Mise à jour intégrale de l'environnement standby (seconde partie)

A présent nous pouvons ré-effectuer une mise à jour intégrale du système situé sur la carte standby (là encore ignorer la mise à jour de pacman) :

raspi ~# pacman -b /mnt/var/lib/pacman -r /mnt -Su

:: The following packages should be upgraded first : pacman :: Do you want to cancel the current operation :: and upgrade these packages now? [Y/n] n :: Starting full system upgrade… resolving dependencies… looking for inter-conflicts… Targets (45): binutils-2.23-1 ca-certificates-20120623-1 coreutils-8.20-1 cronie-1.4.8-3 curl-7.26.0-1 db-5.3.21-1 dbus-core-1.6.8-1 dnssec-anchors-20120422-1 e2fsprogs-1.42.6-1 filesystem-2012.10-2 gcc-libs-4.7.2-2 glib2-2.34.1-1 glibc-2.16.0-5 gmp-5.0.5-1 grep-2.14-1 inetutils-1.9.1-4 initscripts-2012.10.1-1 iproute2-3.6.0-2 iptables-1.4.16.2-1 iputils-20121011-1 krb5-1.10.3-1 ldns-1.6.14-1 less-451-1 libarchive-3.0.4-2 libldap-2.4.33-1 libssh2-1.4.2-1 logrotate-3.8.2-1 mkinitcpio-0.11.0-1 nss-myhostname-0.3-3 openntpd-3.9p1-19 openssh-6.1p1-3 openssl-1.0.1.c-1 pacman-4.0.3-3.1 pam-1.1.6-1 pambase-20120701-1 pcre-8.31-1 perl-5.16.2-1 shadow-4.1.5.1-1 syslog-ng-3.3.6-3 systemd-195-2 sysvinit-2.88-9 sysvinit-tools-2.88-9 util-linux-2.22.1-2 wget-1.14-2 wpa_supplicant-1.0-2 Total Installed Size: 211.23 MiB Net Upgrade Size: 56.37 MiB Proceed with installation? [Y/n] y <– Répondre OUI ici ;-) (45/45) checking for file conflicts [########################################################] 100% (45/45) loading package files [########################################################] 100% (45/45) checking for file conflicts [########################################################] 100% (45/45) checking available disk space [########################################################] 100% ( 1/45) installing glibc [########################################################] 100% ( 2/45) upgrading binutils [########################################################] 100% (…)

Si pacman proteste au sujet de la présence d'un répertoire /var/lock et/ou /var/run sur la carte standby, supprimez-les et recommencez la mise à jour:

(…) error: failed to commit transaction (conflicting files) filesystem: /mnt/var/lock exists in filesystem filesystem: /mnt/var/run exists in filesystem Errors occurred, no packages were upgraded. pi # rm -rf /mnt/var/lock /mnt/var/run pi # pacman -b /mnt/var/lib/pacman -r /mnt -Su :: The following packages should be upgraded first : pacman :: Do you want to cancel the current operation :: and upgrade these packages now? [Y/n] n <— Répondre NON ici :: Starting full system upgrade… (…)

Et voila c'est enfin terminé! Notez qu'il n'est pas anormal que la mise à jour de pacman soit poussée dans la carte standy même si nous avons répondu « Non » à « The following packages should be upgraded first : pacman ». Cette mise à jour concerne en fait le paquet pacman de notre environnement live. Arrêtez, proprement, le Raspberry Pi avec la commande halt ou la commande shutdown et démarrez le Raspberry Pi sur la carte standby qui devient à présent un environnement live (devons-nous vraiment préciser formellement qu'il vous est vivement conseillé de faire une une copie de secours de la carte standby ? ;-) ).

Post-configuration

A la niche !

Étant donné qu'à LinuQ nous laissons notre serveur Raspberry Pi dans des locaux auxquels nous n'avons pas accès 24h/24, il est souhaitable qu'il puisse redémarrer automatiquement en cas de problèmes (charge système trop importante, plantage noyau, « gel » brutal du au matériel…). Il est en pratique possible d'avoir cette fonctionnalité de redémarrage automatique car le SoC du Raspberry Pi abritant son CPU incorpore également un watchdog timer (ou chien de garde) : il s'agit d'un compteur matériel totalement indépendant du CPU et qui est remis périodiquement à zéro par un démon nommé tout naturellement watchdog et fonctionnant en espace utilisateur. Si le système plante, le démon ne pourra pas remettre le compteur du chien de garde à zéro avant que sa valeur limite soit atteinte ce qui a pour conséquence la réinitialisation CPU et donc le redémarrage du système. Bien évidemment il se peut que les systèmes de fichier n'ayant pas été démontés proprement comportent des erreurs cependant en général tout rendre facilement dans l'ordre sans (trop de) casse.

La première étape de la mise en place du chien de garde consiste à faire charger automatiquement au système le module noyau bcm2708_wdog. Ceci est réalisé en créant deux fichiers nommés /etc/modules-load.d/bcm2708_wdog.conf' et /etc/modules.d/bcm2708_wdog.conf dont le contenu est respectivement : # Delai avant RAZ du CPU: 15 secondes options bcm2708_wdog heartbeat=15 Fichier /etc/modules-load.d/bcm2708_wdog.conf bcm2708_wdog Fichier /etc/modules.d/bcm2708_wdog.conf Vérification avec un chargement manuel: raspi ~# modprobe bcm2708_wdog raspi ~# dmesg | grep watchdog [41535.205925] bcm2708 watchdog, heartbeat=15 sec (nowayout=0)

Information

A moins d'avoir explicitement activé l'option nowayout du module noyau bcm2708_wdog, le compteur du chien de garde s'arrêtera automatiquement si le périphérique caractère /dev/watchdog est fermé (ce qui se produit si démon watchdog s'arrête).

Tout va bien, le chien de garde est bel et bien réglé dans notre cas sur 15 secondes: une fois amorcé, le démon watchdog a 15 secondes pour remettre le compteur du chien de garde à zéro qui démarre alors immédiatement un nouveau décompte de 15 secondes devant lui aussi être annulé avant l'échéance et ainsi de suite. Notez que le fait d'insérer le module noyau bcm2708_wdog n'amorçe pas le chien de garde, cette action ne fait que que créer un périphérique caractère de majeure 10 et mineure 130 dans le répertoire /dev:

raspi ~# ls -l /dev/watchdog

crw——- 1 root root 10, 130 Dec 31 1969 /dev/watchdog

L'amorce de la course contre le temps commence réellement à l'instant ou démon watchdog démarre et ouvre le fichier le périphérique caractère /dev/watchdog pour y écrire périodiquement afin de remettre le compteur du chien de garde à zéro. Bien évidemment, si l'ordonnanceur de processus ne lui accorde pas de temps CPU, le compteur du chien de garde ne s'arrête pas pour autant et c'est le redémarrage si le décompte atteint sa limite.

Avant de lancer le démon watchdog et donc d'avoir le système sous surveillance, il est nécessaire de réviser la configuration du démon watchdog stockée dans le fichier /etc/watchdog.conf qui est ici reproduit en totalité:

#ping= 172.31.14.1

#ping= 172.26.1.255

#interface= eth0

#file= /var/log/messages

#change= 1407

# Uncomment to enable test. Setting one of these values to '0' disables it.

# These values will hopefully never reboot your machine during normal use

# (if your machine is really hung, the loadavg will go much higher than 25)

#max-load-1= 24

#max-load-5= 18

#max-load-15= 12

# Note that this is the number of pages!

# To get the real size, check how large the pagesize is on your machine.

#min-memory= 1

#repair-binary= /usr/sbin/repair

#repair-timeout=

#test-binary=

#test-timeout=

#watchdog-device= /dev/watchdog

# Defaults compiled into the binary

#temperature-device=

#max-temperature= 120

# Defaults compiled into the binary

#admin= root

interval = 3

#logtick = 1

#log-dir = /var/log/watchdog

# This greatly decreases the chance that watchdog won't be scheduled before

# your machine is really loaded

realtime = yes

priority = 1

# Check if syslogd is still running by enabling the following line

#pidfile = /var/run/syslogd.pid

Fichier /etc/modules.d/bcm2708_wdog.conf

La quasi-totalité des options reste commentée1) le seul changement apporté ici se situe au niveau de la ligne 31: la ligne est décommentée et l'intervalle d'écriture a été changé pour trois secondes. Il est cependant tout à fait possible de conserver la valeur par défaut qui est de une seconde. Remarquez au passage qu'il est possible de contrôler le comportement du démon de manière relativement fine et de lui demander de ne pas écrire dans le fichier /dev/watchdog lorsque par exemple:

  • non réponse à un ping(lignes 1 et 22) );
  • la charge système excède un certain seuil (lignes 10 à 12), les trois lignes sont pour la moyenne de charge à une, cinq et quinze minutes ;
  • le nombre de pages mémoire libres passe au dessous d'un certain seuil (ligne 16) ;
  • une commande donnée échoue ou met trop de temps à s'exécuter (lignes 20 et 21) ;
  • la température3) mesurée sur un capteur dépasse un certain seuil (lignes 26 et 27) ;

Pour le côté configuration, il ne reste plus qu'à s'assurer que le démon watchdog soit lancé automatiquement au démarrages du système en l'ajoutant au niveau de la ligne DAEMONS= du fichier /etc/rc.conf. Le démon étant lancé en arrière-plan, un caractère arobase précède son nom (votre ligne peut différer légèrement):

(…) \</nowiki></nowiki></nowiki></nowiki></nowiki> DAEMONS=(!hwclock @syslog-ng network @netfs @crond @sshd @watchdog) \ (…)

Fichier /etc/rc.conf/

Dernière étape! Le démon watchdog doit être lancé (à la main), ce qui est effectué par:

rapsi ~# /etc/rc.d/watchdog start

:: Starting Watchdog Daemon [DONE]

Une épée de Damoclès pend à présent en permanence sur le système :-)

Réseau à plein gaz

Le Raspberry Pi dispose d'un contrôleur FastEthernet 10/100 Mbit/s Ethernet-USB 2.0 de la série LAN95004) 5) du fabricant SMSC. La configuration de base de distributions Linux comme ArchLinuxARM est désactiver le mode dit turbo du contrôleur Ethernet-USB6) au niveau des paramètres noyau contenus dans le fichier /boot/cmdline.txt pour deux raisons7) :

  • la nécessiter de garantir au noyau Linux la disponibilité d'une certaine quantité de mémoire additionnelle et qui sera amputée à celle disponible pour les applications. Sachant que la mémoire est une ressource rare sur les Raspberry Pi…

Le mode turbo 9) 10) consiste grosso modo à accroitre la « vélocité » du LAN9500 en ne faisant transiter les trames au travers du bus USB non plus une a une mais par paquets de plusieurs, ce qui évite par la même occasion un certain bavardage sur le bus. Le fait de laisser le mode turbo du Raspberry Pi actif permet d'avoir des vitesses de transfert de réseau un peu plus importantes, le prix à payer étant de réduire la quantité de mémoire disponible pour les applications fonctionnant sur le Raspberry Pi.

Accroissement des tampons mémoire

Au cours des différentes recherches qui ont précédées l'écriture de cet article, il est a pu être noté sur divers forums traitant du Raspberry Pi que l'utilisation du mode turbo du LAN9500 requiert de changer la valeur du paramètre noyau vm.min_free_kbytes11) à 8192 (8 Mo). En pratique lors de transferts particulièrement intensifs avec le mode turbo actif, il a été constaté que cette valeur est quelque peu pessimiste (présence de messages « smsc95xx 1-1.1:1.0: eth0: kevent 2 may have been dropped » dans le journal noyau). la situation a cependant pu être corrigée en poussant vm.min_free_kbytes à 16384 (16 Mo).

Le changement de la valeur de la variable noyau vm.min_free_kbytes peut être effectué à la volée à l'aide de la commande sysctl :

raspi ~# sysctl -w vm.min_free_kbytes=16384

Pour le rendre le changement persistant à chaque démarrage, il suffit d'ajouter la variable et la valeur souhaitée au fichier /etc/sysctl.conf:

(…) \ vm.min_free_kbytes=16384 \ (…)

Fichier /etc/sysctl.conf

Activation du mode turbo du contrôleur LAN9500

L'opération est extrêmement simple et consiste en deux étapes:

  1. Editer le fichier /etc/cmdline.txt et effacer la directive smsc95xx.turbo_mode=N
  2. Redémarrer le Raspberry Pi. Il n'est pas possible d'influer sur le paramètre turbo_mode depuis la ligne de commande sous ArchLinux ARM, ce pilote étant inclus directement dans l'image du noyau.
Information

Il est possible que votre distribution propose le pilote smsc95xx en tant que module noyau, auquel cas il vous suffit de décharger (commande modprobe -r smsc95xx) puis recharger le module noyau à l'aide d'un simple modprobe smsc95xx sachant que, par défaut, le comportement du pilote du LAN9500 Linux est d'avoir le mode turbo actif.

La framboise met le turbo

Critique

Ne désactivez pas les limitations en courant / température du Raspberry Pi tout en le survoltant afin de le pousser au delà de 1 Ghz! Cela aurait la fâcheuse conséquence d'activer (définitivement) le bit « Overvolt » du CPU du Raspberry Pi (ce qui en annule la garantie) et pourrait également lui être fatal. Il en est de même si vous forcez l'utilisation du mode turbo (force_turbo) avec un survoltage. Les réglages que nous proposons ici sont ceux officiellement supportés par la Raspberry Pi Foundation.

Le coeur du Raspberry Pi est ce que l'on appelle un System on Chipet en l'occurrence un BCM2835 de Broadcom12) . Le BCM2835 intègre au sein d'un seul circuit intégré plusieurs composants dont:

Un CPU ARM modèle ARM1176JZ-F (famille ARM11, un dérivé de l'architecture ARMv6).

Un GPU Video Core IV (mc) bi-coeur divisé en plusieurs sous-blocs13) dont :

rendu 3D ;

Encodage/décodage vidéo ;

Image Sensor Pipeline (ISP) qui est dédié au traitement photo ;

Des contrôleurs de bus USB, I²C, RS-232 et SPI (les trois derniers sont disponibles au travers du socket de 26 broches jouxtant la sortie vidéo composite) ;

Un chien de garde ;

Le CPU, le GPU et la mémoire SDRAM disposent chacun de leur propre signal d'horloge14) généré au travers de trois boucles à verrouillage de phase (Phase Locked Loop ou PLL) indépendantes15) . Les unités de rendu 3D, l'encodeur H264 et l'ISP partagent la même PLL au travers de diviseurs de fréquence et ont donc des fréquences de fonctionnement multiples les unes des autres.

L'outil raspi-config dont le wiki/forums16) de la Raspberry Foundation font mention n'est pas pour le moment (novembre 2012) disponible sous ArchLinux/ARM. Il est cependant tout à fait possible de remplir à la main le fichier /boot/config.txt 17) et d'y ajouter les déclarations suivantes et de dé-commenter la série de lignes souhaitée (4 à 7 pour un léger overclocking, 11 à 14 pour un overclocking un peu plus agressif, etc.) :

# Modeste

#arm_freq=800

#core_freq=300

#sdram_freq=400

#over_voltage=0

# Moyen

#arm_freq=900

#core_freq=333

#sdram_freq=450

#over_voltage=2

# Élevé

#arm_freq=950

#core_freq=450

#sdram_freq=450

#over_voltage=6

# Turbo!

# Il a été rapporté des problèmes de corruption du contenu de la carte cartes SD avec ce réglage…

#arm_freq=1000

#core_freq=500

#sdram_freq=500

#over_voltage=6

Fichier /boot/config.txt


A moins d'utiliser un peu de paramètres en particulier, les valeurs par défaut18) sont:


Paramètre

Valeur par défaut

Notes

arm_freq

700

Fréquence d'horloge en Mhz du CPU en Mhz (700 = 700 Mhz)

gpu_freq

250

Fréquence d'horloge en Mhz du GPU. Fixe les valeurs de core_freq, h264_freq, isp_freq et v3d_freq à 250 Mhz

core_freq

250

Fréquence d'horloge en Mhz du coeur du GPU (forcée à 250 Mhz par gpu_freq). Attention, le cache L2 du CPU est également impacté par cette fréquence.

h264_freq

250

Fréquence d'horloge en Mhz du décodeur video (forcée à 250 Mhz par gpu_freq).

isp_freq

250

Fréquence d'horloge en Mhz de l'ISP (forcée à 250 Mhz par gpu_freq).

v3d_freq

250

Fréquence d'horloge en Mhz du bloc de rendu 3D (forcée à 250 Mhz par gpu_freq).

sdram_freq

400

Fréquence d'horloge en Mhz de la mémoire SDRAM.

over_voltage

0

Modificateur de sur/sous-voltage de l'alimentation du CPU et CPU exprimé en pas de 0,025 volts par rapport à la tension de référence 1,20V. 0 = fonctionnement à tension de référence 1,20V.

over_voltage_sdram

0

Modificateur de sur/sous-voltage de l'alimentation du contrôleur mémoire (SDRAM), joue sur plusieurs sous paramètres (tension du contrôleur/interface physique PHY et tension au niveau des bus d'E/S) pouvant être contrôlés inividuellement. 0 = fonctionnement à la tension de référence 1,20V.

force_turbo

0

Désactive le réglage automatique des fréquences de fonctionnement par le noyau Linux (pilote cpufreq ) des horloges CPU, GPU , mémoire SDRAM ainsi le survoltage automatique, aussi les valeurs spécifiées pour arm_freq, core_freq, sdram_freq et over_voltage seront celles utilisées en permanence. Activer force_turbo annule la garantie du Raspberry Pi si utilisée conjointement avec over_voltage > 0 et peut être fatale à l’appareil.

initial_turbo

0

Active les réglages maximaux donnés au travers de arm_freq, core_freq, sdram_freq et over_voltage pour une durée d'initial_turbo secondes (max. 60) ou jusqu'à ce que le pilote cpufreq du noyau Linux entre en action.

arm_freq_min

700

Valeur minimum d'arm_freq utilisée par le pilote cpufreq du noyau Linux

core_freq_min

250

Valeur minimum d'core_freq utilisée par le pilote cpufreq du noyau Linux

sdram_freq_min

400

Valeur minimum de sdram_freq utilisée par le pilote cpufreq du noyau Linux

over_voltage_min

0

Valeur minimum d'over_voltage utilisée par le pilote cpufreq du noyau Linux

temp_limit

85

Limite en température (degrés centigrades) au delà de laquelle tous les paramètres du micrologiciel du Raspberry Pi modifiant des fréquences d’horloge reviennent automatiquement à leur valeur par défaut. Pousser la valeur au delà de 85°C (valeur par défaut) annule la garantie du Raspberry Pi si utilisée conjointement avec over_voltage > 0 et peut être fatale à l'appareil.

current_limit_override

-

Désactive la limitation de l'intensité du courant provenant de la prise micro-USB d'alimentation électrique du Raspberry Pi. Peut aider en cas de problème de stabilité du à réglages d'overclocking agressifs. Désactiver cette limitation de courant annule la garantie du Raspberry Pi si utilisée conjointement avec over_voltage > 0 et peut être fatale à l’appareil.

Déploiement des outils servant au club

Serveur FTP

Le serveur FTP choisi ici est le bien connu vsFTP. Sa se résume à installer vsFTP à l'aide de la commande pacman:

raspi ~# pacman -S vsftp

Puis à éditer le fichier de configuration /etc/vsftp.conf (noter que par défaut les sessions FTP anonymes sont désactivées) pour activer les sessiosn FTP anonymes et changer les valeurs de quelques autres paramètres dont désactivation des sessions d'utilisateurs (ligne 5), le message de bienvenue (ligne 74), le chemin utilisé pour les sessions anonymes (ligne 110) :

# Allow anonymous FTP? (Beware - allowed by default if you comment this out).

anonymous_enable=YES

#

# Uncomment this to allow local users to log in.

local_enable=NO

#

# Uncomment this to enable any form of FTP write command.

#write_enable=YES

#

# Default umask for local users is 077. You may wish to change this to 022,

# if your users expect that (022 is used by most other ftpd's)

#local_umask=022

#

# Uncomment this to allow the anonymous FTP user to upload files. This only

# has an effect if the above global write enable is activated. Also, you will

# obviously need to create a directory writable by the FTP user.

#anon_upload_enable=YES

#

# Uncomment this if you want the anonymous FTP user to be able to create

# new directories.

#anon_mkdir_write_enable=YES

#

# Activate directory messages - messages given to remote users when they

# go into a certain directory.

dirmessage_enable=YES

#

# Activate logging of uploads/downloads.

xferlog_enable=YES

#

# Make sure PORT transfer connections originate from port 20 (ftp-data).

connect_from_port_20=YES

#

# If you want, you can arrange for uploaded anonymous files to be owned by

# a different user. Note! Using “root” for uploaded files is not

# recommended!

#chown_uploads=YES

#chown_username=whoever

#

# You may override where the log file goes if you like. The default is shown

# below.

#xferlog_file=/var/log/vsftpd.log

#

# If you want, you can have your log file in standard ftpd xferlog format.

# Note that the default log file location is /var/log/xferlog in this case.

xferlog_std_format=YES

#

# You may change the default value for timing out an idle session.

#idle_session_timeout=600

#

# You may change the default value for timing out a data connection.

#data_connection_timeout=120

#

# It is recommended that you define on your system a unique user which the

# ftp server can use as a totally isolated and unprivileged user.

#nopriv_user=ftpsecure

#

# Enable this and the server will recognise asynchronous ABOR requests. Not

# recommended for security (the code is non-trivial). Not enabling it,

# however, may confuse older FTP clients.

#async_abor_enable=YES

#

# By default the server will pretend to allow ASCII mode but in fact ignore

# the request. Turn on the below options to have the server actually do ASCII

# mangling on files when in ASCII mode.

# Beware that on some FTP servers, ASCII support allows a denial of service

# attack (DoS) via the command “SIZE /big/file” in ASCII mode. vsftpd

# predicted this attack and has always been safe, reporting the size of the

# raw file.

# ASCII mangling is a horrible feature of the protocol.

#ascii_upload_enable=YES

#ascii_download_enable=YES

#

# You may fully customise the login banner string:

ftpd_banner=Bienvenue sur serveur FTP de LinuQ. Tous les transferts sont consignés.

#

# You may specify a file of disallowed anonymous e-mail addresses. Apparently

# useful for combatting certain DoS attacks.

#deny_email_enable=YES

# (default follows)

#banned_email_file=/etc/vsftpd.banned_emails

#

# You may specify an explicit list of local users to chroot() to their home

# directory. If chroot_local_user is YES, then this list becomes a list of

# users to NOT chroot().

# (Warning! chroot'ing can be very dangerous. If using chroot, make sure that

# the user does not have write access to the top level directory within the

# chroot)

#chroot_local_user=YES

#chroot_list_enable=YES

# (default follows)

#chroot_list_file=/etc/vsftpd.chroot_list

#

# You may activate the “-R” option to the builtin ls. This is disabled by

# default to avoid remote users being able to cause excessive I/O on large

# sites. However, some broken FTP clients such as “ncftp” and “mirror” assume

# the presence of the “-R” option, so there is a strong case for enabling it.

#ls_recurse_enable=YES

#

# When “listen” directive is enabled, vsftpd runs in standalone mode and

# listens on IPv4 sockets. This directive cannot be used in conjunction

# with the listen_ipv6 directive.

listen=YES

#

# This directive enables listening on IPv6 sockets. To listen on IPv4 and IPv6

# sockets, you must run two copies of vsftpd with two configuration files.

# Make sure, that one of the listen options is commented !!

#listen_ipv6=YES

# Chemin vers le repertoire FTP public

anon_root=/storage/mirrors/pub

# Limite maximale par session (2 Mo/s) - pour le moment desactive

#anon_max_rate=2048000

Fichier /etc/vsftp.conf


Il reste ensuite à ajouter vsftp à la liste des démons à lancer au démarrage du système (fichier /etc/rc.conf) :

(…)
DAEMONS=(!hwclock @syslog-ng network @netfs @crond @sshd @watchdog @vsftpd)
(…)

Fichier /etc/rc.conf

raspi ~# /etc/rc.d/vsftpd start

Debmirror

Préalablement à Debmirror, il faut installer quelques paquets de modules PERL notamment perl-libwww et perl-lwp-protocol-https ainsi que, si ce n'est déjà fait, les paquets gcc et make :

raspi ~# pacman -S perl-libwww

resolving dependencies… looking for inter-conflicts… Targets (14): perl-encode-locale-1.03-1 perl-file-listing-6.04-1 perl-html-parser-3.69-2 perl-html-tagset-3.20-3 perl-http-cookies-6.01-1 perl-http-daemon-6.01-1 perl-http-date-6.02-1 perl-http-message-6.03-1 perl-http-negotiate-6.01-1 perl-lwp-mediatypes-6.02-1 perl-net-http-6.03-1 perl-uri-1.60-1 perl-www-robotrules-6.02-1 perl-libwww-6.04-1 (…)

raspi ~# pacman -S perl-lwp-protocol-https

resolving dependencies… looking for inter-conflicts… Targets (4): perl-io-socket-ssl-1.77-1 perl-mozilla-ca-20120309-1 perl-net-ssleay-1.49-1 perl-lwp-protocol-https-6.03-1 (…)


Il va falloir également quelques modules PERL aditionnels qui n'ont pas été empaquetés mais qui sont disponibles sur le Comprehensive Perl Archive Network.

Il faut ensuite décompresser et installer chacun d'eux. LockFile::Simple, Net::INET6Glue et IO::Socket::INET6 s'installent selon une démarche similaire à la suivante :

raspi ~# tar -zxvf LockFile-Simple-0.208.tar.gz

LockFile-Simple-0.208/ LockFile-Simple-0.208/MANIFEST LockFile-Simple-0.208/Lock/ LockFile-Simple-0.208/Lock/Simple.pm (…)

raspi ~# cd LockFile-Simple-0.208

raspi LockFile-Simple-0.208# perl Makefile.PL

Checking if your kit is complete… Looks good Writing Makefile for LockFile::Simple Writing MYMETA.yml and MYMETA.json (…)

raspi LockFile-Simple-0.208# make install

cp Manager.pm blib/lib/LockFile/Manager.pm cp Simple.pm blib/lib/LockFile/Simple.pm cp Lock.pm blib/lib/LockFile/Lock.pm cp Lock/Simple.pm blib/lib/LockFile/Lock/Simple.pm Manifying blib/man3/LockFile::Simple.3pm Appending installation info to /usr/lib/perl5/core_perl/perllocal.pod (…)

Pour ce qui est de Socket6:

raspi ~# tar -zxvf Socket6-0.23.tar.gz

Socket6-0.23/ Socket6-0.23/t/ Socket6-0.23/gai.h Socket6-0.23/getnameinfo.c Socket6-0.23/MANIFEST (…)

raspi ~# cd Socket6-0.23

raspi Socket6-0.23# perl Makefile.PL install

checking for gcc… gcc checking for C compiler default output file name… a.out checking whether the C compiler works… yes checking whether we are cross compiling… no (..) Writing Makefile for Socket6 Writing MYMETA.yml and MYMETA.json cp Socket6.pm blib/lib/Socket6.pm /usr/bin/perl /usr/share/perl5/core_perl/ExtUtils/xsubpp -noprototypes -typemap /usr/share/perl5/core_perl/ExtUtils/typemap Socket6.xs > Socket6.xsc && mv Socket6.xsc Socket6.c gcc -c -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -march=armv5te -O2 -pipe -fno-strict-volatile-bitfields -fstack-protector –param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 -DVERSION=\“0.23\” -DXS_VERSION=\“0.23\” -fPIC “-I/usr/lib/perl5/core_perl/CORE” Socket6.c (…) Installing /usr/lib/perl5/site_perl/auto/Socket6/Socket6.so Installing /usr/lib/perl5/site_perl/Socket6.pm Appending installation info to /usr/lib/perl5/core_perl/perllocal.pod

Debmirror n'a pas été empaqueté sur archlinux ARM, nous optons pour l'installation directe et de debmirror et quelques dépendances PERL additionnelles. La tarballe gzippée de Debmirror peut être récupérée sur n'importe quel miroir Debian depuis le répertoire pool/main/d/debmirror (la version 2.14 est la plus récente en date de rédaction). Vu que nous sommes au Canada nous utilisons donc le miroir canadien pour l'exemple suivant, le bon usage voudrait que vous utilisiez un mirroir géographiquement proche de chez vous :

raspi ~# wget ftp://ftp.ca.debian.org/debian/pool/main/d/debmirror/debmirror_2.14.tar.gz

NTP (Maintient automatique de l'heure système)

Passage à l'architecture ARMv6

L'image d'ArchLinux ARM utilise à la base des paquets binaires compatibles avec l'architecture ARM version 5. Cela ne pose pas réellement de problèmes car le CPU du Raspberry Pi bien qu'étant de la famille ARM11 (architcture ARM version 6) est retro-compatible. Il est possible de réaliser le passage de l'architecture ARM v5 à ARM v6 de deux manières :

  1. Directement sur un système fonctionnel (environnement live) ;
  2. En effectuant une copie de la carte SD contenant le système sur une seconde (environnement standby) qui sera elle mise à jour, la carte d'origine restant inchangée ;

Il n'existe pas de « meilleure » méthode, l'une ou l'autre convient parfaitement, la seconde est cependant détaillée dans cette section.


1)
Voir la page de manuel watchdog.conf (5) pour plus de détails.
2)
Remarquer l'usage de ce qui est une adresse de broadcast à la ligne 2: watchdog attendra alors qu'une des machines du réseau réponde.
3)
La lectures de la sonde de température du SoC du Raspberry Pi peut être obtenue en lisant le pseudo-fichier /sys/class/thermal/thermal_zone0/temp (le nombre est exprimé en millièmes de degrés centigrades)
6)
Aucun rapport avec le mode turbo du CPU qui est un fait un jeu de paramètres d'overcloking repoussant (raisonnablement) les limites du Raspberry Pi
7)
Les deux leitmotivs qui apparaissent avec un peu de recherches sont les deux cités.
8)
L'information à sujet n'est que très vague dans Google, plusieurs personnes ont rapportés des problèmes de tempêtes d'interruptions notamment fin 2011-début/mi 2012. La cause du problème n'est pas claire même en tentant de recouper les résultats dans Google… il semblerait que ce soit lié à certaines combinaisons de versions du noyau et micrologiciels et au contrôleur USB 2.0 DWC OTG équipant le Raspberry Pi. Dans les cas de figures problématiques il se produit un phénomène de tempête d'interruptions (interrupt storm) qui gèle le système ou fait paniquer le noyau. Le phénomène a pu être observé avec une charge réseau importante sur le contrôleur Ethernet-USB 2.0 du Raspberry Pi.
9)
Déduction faite à partir de très bref descriptifs trouvés dans le code source du noyau du pilote FreeBSD pour le pilote du LAN9500. Cette information est probablement en partie inexacte.
10)
Le code source du pilote Linux du LAN9500 est fort obscur, la datasheet du LAN9500 est également très avare de détails sur le sujet… le code source fait également état d'une capacité de décharge CPU (off-loading) en émission et réception, il est possible de vérifier avec la commande ethtool -k eth0
12)
Ses spécifications ne sont pas disponibles publiquement.
14)
Ne pas confondre le signal d'horloge avec l'horloge système… Un signal d'horloge agit comme un métronome pour un microprocesseur, plus le « tic » est rapide plus le processeur sera véloce.
17)
Ce fichier de configuration est utilisé par le micrologiciel (contenu dans le fichier /boot/start.elf) du Raspberry Pi.
auto-heber/rpi/serveur_archlinux_arm_sur_un_raspberry_pi.txt · Dernière modification : 2024/01/28 23:48 de 127.0.0.1