Categorie: Administration réseau
faq

Découvrons la RIPE database

Le RIPE, comme tout RIR, dispose d'une base de données publique qui regroupe toutes (un maximum on va dire) les informations "technico-administratives" (à qui a été alloué telle ressource numérique unique ? qui est le responsable technique de ce réseau, quel AS doit annoncer tel préfixe IP ?, ...) concernant les réseaux informatiques publics en Europe (version large) et au Moyen-Orient.

Habituellement, on accède à cette base de données lorsque l'on fait une requête avec le protocole whois sur une ressource (plage d'IP, numéro d'AS, ...) allouée/assignée par le RIPE. Aujourd'hui, on va plutôt regarder de quoi est constituée cette base de données et comment les LIR et les opérateurs réseaux la mettent à jour (ou non, d'ailleurs).

Si tous les RIR ont une base de données, pourquoi je me focalise sur celle du RIPE ? Simplement car le RIPE est bien de chez nous et comme le format de la base (RPSL ou non, objets/attributs différents, ...) change entre RIR, autant étudier ce qui nous concerne. De plus, la RIPE DB est la mieux documentée, à mon humble avis.

Attention : ce billet n'est ni de la vulgarisation ni une source d'information fiable. Il s'agit juste d'un retour d'expérience et de quelques notes d'un n00b qui s'est penché sur le sujet.

Table des matières

De la documentation générique

Documentation spécifique

Quelques paramètres whois bien utiles

Ce que je retiens principalement des lectures précédentes, c'est des paramètres de la commande whois, qui sont spécifiques à certaines bases comme celle du RIPE mais qui n'en sont pas moins très utiles :

  • whois -t <type_objet> : afficher les attributs d'un type d'objet
  • whois -B : afficher toutes les infos (mail ...) de l'objet demandé (sans ça : « source: RIPE # Filtered »)
  • whois -L : remonter toute l'arborescence d'une allocation. Exemple pour un inetnum : organisation - LIR - RIR - IANA
  • whois -l : pareil que précédemment mais remonte uniquement d'un étage/d'une étape/d'un cran
  • whois -r -i org <id_organisation> : afficher toutes les ressources/objets assignés/alloués à une organisation (objet de type « organisation »)

RIPE TEST Database

Le RIPE met à disposition une base de données de test en libre-service pour que chacun puisse découvrir/s'entraîner à l'arrache. Je pense que c'est un excellent moyen de voir comment ça se passe de l'autre côté du whois. C'est vraiment intéressant et formateur.

Ci-dessous, je ne vais pas être exhaustif, juste donner des pistes et énoncer quelques "pièges" que j'ai rencontrés pour vous éviter de tomber dedans.

Dans mes exemples, je serais Jean-Kevin Boulay de l'association TESTASSO.

person/mntner

La première étape est de créer un objet de type « person ». Voyons les différents attributs disponibles :

whois -t person
person:         [mandatory]  [single]     [lookup key]
address:        [mandatory]  [multiple]   [ ]
phone:          [mandatory]  [multiple]   [ ]
fax-no:         [optional]   [multiple]   [ ]
e-mail:         [optional]   [multiple]   [lookup key]
org:            [optional]   [multiple]   [inverse key]
nic-hdl:        [mandatory]  [single]     [primary/lookup key]
remarks:        [optional]   [multiple]   [ ]
notify:         [optional]   [multiple]   [inverse key]
abuse-mailbox:  [optional]   [multiple]   [inverse key]
mnt-by:         [mandatory]  [multiple]   [inverse key]
changed:        [mandatory]  [multiple]   [ ]
source:         [mandatory]  [single]     [ ]

Hum ... mnt-by doit pointer un objet de type « mntner » (maintainer) ... Quels sont ses attributs ?

whois -t mntner
mntner:         [mandatory]  [single]     [primary/lookup key]
descr:          [mandatory]  [multiple]   [ ]
org:            [optional]   [multiple]   [inverse key]
admin-c:        [mandatory]  [multiple]   [inverse key]
tech-c:         [optional]   [multiple]   [inverse key]
upd-to:         [mandatory]  [multiple]   [inverse key]
mnt-nfy:        [optional]   [multiple]   [inverse key]
auth:           [mandatory]  [multiple]   [inverse key]
remarks:        [optional]   [multiple]   [ ]
notify:         [optional]   [multiple]   [inverse key]
abuse-mailbox:  [optional]   [multiple]   [inverse key]
mnt-by:         [mandatory]  [multiple]   [inverse key]
referral-by:    [mandatory]  [single]     [ ]
changed:        [mandatory]  [multiple]   [ ]
source:         [mandatory]  [single]     [ ]

Il y a une référence circulaire : un objet person dépend d'un objet de type maintainer mais un objet maintainer dépend aussi d'un objet de type person (attribut « admin-c »).

La solution ? Utiliser le formulaire pour les nouveaux arrivants dans la RIPE Database.

Mode d'emploi rapide :

  • Source : bien choisir la TEST Database
  • Person : prénom nom. Exemple : J-K Boulay
  • NIC hdl : ne peut pas être vide contrairement à ce qui est indiqué. Il s'agit de la clé primaire de l'objet. Elle doit être unique dans la base donc la base l'attribue elle-même. Il faut mettre la valeur « AUTO-1 » pour laisser complètement le choix à la base ou « AUTO-1<abréviation> ». Abréviation est composée de 1 à 4 lettres. Exemple : AUTO-1JKB
  • Address : FR suffit, par exemple
  • Phone : +33123456789 suffit, par exemple
  • Email : ripedb@example.com suffit, par exemple
  • Pour le mntner, le nom est une clé et on reprend souvent le nom de l'organisation à laquelle la personne qui s'inscrit est rattachée. Exemple : Maintainer name : TESTASSO-MNT

Normalement, vous obtenez le message suivant :

We have created two RIPE Database objects for you, please make a note of the primary keys (shown in bold letters) for these two objects for future reference:
 
person nic-hdl: JKB1-TEST
 
person:         J-K Boulay
address:        FR
phone:          +33123456789
e-mail:         ripedb@example.com
nic-hdl:        JKB1-TEST
mnt-by:         TESTASSO-MNT
changed:        ripedb@example.com 20140418
source:         TEST
 
maintainer name: TESTASSO-MNT
 
mntner:         TESTASSO-MNT
descr:          Startup maintainer
admin-c:        JKB1-TEST
upd-to:         ripedb@example.com
auth:           MD5-PW blabla
mnt-by:         TESTASSO-MNT
referral-by:    TESTASSO-MNT
changed:        ripedb@example.com
source:         TEST

Petite note : un objet de type maintainer est un verrou qui empêche la modification et la suppression inopinée de vos enregistrements présents dans la base. Il recense également les moyens qui permettent d'authentifier le requérant d'une modification/suppression. Actuellement, la base supporte une auth par mot de passe (stocké sous forme de hash MD5 dans la base) ou par signature PGP des objets (uniquement par mail, pas par l'interface web. Oui, on peut créer/modifier des objets par mail.). Pour l'instant, nous n'avons qu'une auth par mot de passe.

Vous pouvez effectuer une recherche pour vérifier que vos objets ont bien été créés : https://apps.db.ripe.net/search/query.html.

Si vous souhaitez modifier vos objets, c'est par là : https://apps.db.ripe.net/webupdates/search.html. Cependant, lors de la soumission de vos modifications, vous allez recevoir l'erreur : « No authorisation has been supplied ». En effet, vous n'avez pas prouvé votre identité selon l'un des mécanismes prévus dans l'objet maintainer qui verrouille l'objet que vous souhaitez modifier. Pour vous authentifier, il suffit de saisir votre mot de passe de maintainer dans la zone « Session Passwords » dans le menu de droite.

À partir de maintenant, vous pouvez créer vos objets à l'adresse suivante : https://apps.db.ripe.net/webupdates/select-type.html. Deux méthodes de saisies sont disponibles : format brut (que du texte) ou formulaire avec uniquement les attributs obligatoires.

organisation

Un objet de type « organisation » permet de regrouper toutes les ressources associées/allouées à une organisation donnée. Très pratique mais pas obligatoire. Les autres objets peuvent pointer dessus avec un attribut « org ». L'attribut organisation fonctionne comme le NIC-hdl d'une person donc « AUTO-1<abréviation> ».

Exemple :

organisation: 	ORG-TSTA1-TEST
org-name: 	Association TESTASSO
org-type: 	OTHER
address: 	FR
e-mail: 	ripedb@example.com
mnt-ref: 	TESTASSO-MNT
mnt-by: 	TESTASSO-MNT
changed: 	ripedb@example.com 20140418
source: 	TEST

inetnum/inetnum6

Passons au plus intéressant : une plage d'adresses IPv4 : un inetnum (ou v6 avec inetnum6, ça fonctionne pareil).

En situation réelle, vous n'aurez pas besoin de créer cet objet : c'est le boulot de votre LIR qui vous mettra en mnt-* si vous le souhaitez pour que vous ayez des droits sur vos allocations. De plus, en situation réelle, le processus d'allocation de ressources ne se passe pas aussi facilement en mode "ho, cette plage est disponible, je la prends". Néanmoins, ici, je choisis 192.0.2.0/24 qui est une plage réservée à la documentation.

Ici, il faudra l'accord de la hiérarchie, c'est à dire de l'organisation (RIR ou LIR) a qui a été attribuée la plage d'adresses IP qui englobe celle que cette organisation vous a attribuée. Pour trouver quel est le maintainer responsable, il suffit de faire une recherche.

Via l'interface web :

  • Search term : 192.0.2.0 - 192.0.2.255
  • Sources : TEST Database
  • Hierarchy Flags : l (l comme lapin)

Ou via whois : whois -h whois-test.ripe.net -l 192.0.2.0 - 192.0.2.255

Voilà un extrait de la réponse :

inetnum:         0.0.0.0 - 255.255.255.255
netname:         IANA-BLK
descr:           The whole IPv4 address space
country:         EU # Country is really world wide
org:             ORG-TT1-TEST
admin-c:         AA1-TEST
tech-c:          AA2-TEST
status:          ALLOCATED UNSPECIFIED
remarks:         The country is really worldwide.
mnt-by:          TEST-ROOT-MNT
mnt-lower:       TEST-DBM-MNT
mnt-routes:      TEST-DBM-MNT
remarks:         This is an automatically created object.
source:          TEST # Filtered

On regarde l'attribut « mnt-lower: ». Le maintainer est « TEST-DBM-MNT ». Dans cette base de test, le mot de passe est donné dans un attribut « remark » de cet objet mntner. Je vous laisse le retrouver et l'ajouter à vos « Session Passwords » (menu de droite, tout ça ...).

Maintenant, vous pouvez enregistrer un inetnum. Exemple :

inetnum: 	192.0.2.0 - 192.0.2.255
netname: 	TESTASSO-MAIN
descr:		IPv4 TESTASSO allocation
country: 	FR
admin-c: 	JKB1-TEST
tech-c: 	JKB1-TEST
status: 	ASSIGNED PA
mnt-by: 	TESTASSO-MNT
changed: 	ripedb@example.com 20140418
source: 	TEST

Remarquez que le statut est fantaisiste et ne correspond pas à la réalité : l'IANA n'alloue pas directement des ressources. Le RIPE le faisait (PI + allocation directe). Mais c'est fini (famine IPv4, tout ça et il me semble que c'est pareil en IPv6). Donc, au minimum, il faudrait un RIR et un LIR entre TESTASSO et l'IANA avec autant d'objets. Si ça vous tente de faire une maquette plus réaliste ... Ce n'est pas difficile, juste répétitif.

ASN

Pour un numéro de système autonome (ASN), le type d'objet est « aut-num ». Sa création ne pose pas de problèmes si vous êtes arrivé jusque-là.

Délégation zone reverse

Pour la délégation d'une zone reverse v4/v6, c'est un objet de type « domain » qu'il vous faut. Mais dans la base de test, sa création échouera car le niveau supérieur (0/0 en v4) n'a pas configuré les serveurs de noms qui font autorité sur cette zone reverse (et pour cause ...).

Politiques de routage inter-AS

Pour ce qui est des politiques de routage, on a les objets de type route/route6 qui permettent de dire : « tel préfixe IPv4 ou IPv6 est annoncé par tel AS » ou des choses plus marrantes comme « quelle est l'adresse IP de la machine que ce réseau met à disposition du public pour servir d'amer ? ».

Pour les politiques de routage, on a aussi d'autres objets (filter-set, par exemple) et des attributs dans l'objet « aut-num » : import, export et les types liés (as-set, route-set). Tout cela constitue l'Internet Routing Registry (IRR). Exemple :

aut-num: AS197422
as-name: TETANEUTRAL-NET-AS
[...]
from AS31576 accept ANY
from AS6777 accept ANY
from AS6939 accept ANY
[...]
to AS31576 announce AS197422
to AS6939 announce AS197422
to AS6777 announce AS197422
[...]

Ici, ce FAI toulousain annonce que ses pairs sont GIXE (transitaire), l'AMS-IX (point d'échange néerlandais) et Hurricane Electric (gros opérateur). Tetaneutral.net récupère toutes les routes auprès d'eux sans prioriser un pair vis-à-vis d'un autre. Enfin, Tetaneutral annonce ses préfixes à ses pairs.

Cogestion

Et pour faire de la cession de droits ou, à minima, de la cogestion sur des objets ? Il suffit de leur associer de nouveaux objets de type mntner dans leurs attributs « mnt-by » ou « mnt-* » pour des droits plus fins. Exemples : mnt-routes pointe sur un objet maintainer qui aura le droit d'ajouter des objets de type route/route6 en rapport avec l'objet courant ; mnt-domain = même principe mais pour les reverse v4/v6. L'authentification fonctionne selon un OU logique : toute personne qui aura un des mécanismes d'authentification d'un des maintainers pourra modifier l'objet.

Faire le ménage dans la base de test

Pour supprimer tous les objets que vous avez créés dans la base de test, il faut les rechercher et choisir l'option « delete ». À cause de la référence circulaire entre vos objets de types mntner et person, vous ne pourrez pas les supprimer directement. Néanmoins, sur cette base de test, on peut ruser : casser la référence circulaire en définissant « TEST-DBM-MNT » comme mntner de l'objet personn et « AA1-TEST » comme admin-c de l'objet mntner. Ça fonctionne uniquement car nous avons le mot de passe de « TEST-DBM-MNT ». J'imagine qu'il existe une méthode plus pragmatique voire un bête formulaire web mais je ne l'ai pas trouvé.

Dernières remarques

On notera que les attributs « tech-c » et « admin-c » de tous les objets peuvent pointer sur un seul et même objet de type person.

Enfin, si l'on souhaite visualiser les objets de la base du RIPE sous un format graphique conviviale, l'onglet « Database » de l'outil Ripestat est là pour ça.

privacy
partner

Sécuriser le routage sur Internet

Aujourd'hui, je vous propose un long billet sur le routage inter-domaine, sa sécurité actuelle et RPKI+ROA.

Attention : RPKI+ROA est encore un mécanisme tout jeune. Cela signifie que, bien que les concepts de base ne changeront pas et que ce travail date de mai 2013, certaines informations contenues dans ce travail vont devenir obsolètes à plus ou moins long terme.

Pour lire la version HTML, il suffit de cliquer sur le lien "Lire la suite" (et/ou de poursuivre ci-dessous). Pour ceux qui préfèrent lire un si gros pavé en PDF, c'est par là : Sécuriser le routage sur Internet.

Je mets également les sources LaTeX à votre disposition. Ces sources LaTeX peuvent servir de base à d'autres documents. Sources.

Vous pouvez également récupérer la maquette (vous comprendrez la raison de son existence en lisant le pavé). Elle peut servir pour mieux visualiser le fonctionnement de RPKI+ROA ou pour simplement tester ses différents composants. Elle repose sur LXC. Le tar contient la maquette compressée avec LZMA ainsi que les instructions d'utilisation au format texte. Maquette RPKI-ROA. Les fichiers de configurations principaux pour refaire une maquette from scratch sont disponibles ici : Fichiers de configuration principaux de ma maquette RPKI-ROA.

Et pour terminer, vous pouvez également récupérer le visuel projeté durant ma soutenance et ses sources. Support visuel soutenance | Sources LaTeX support visuel soutenance.

Si vous voulez tout récupérer (maquette, sources, pdf) en un seul coup, c'est par là : Sécuriser le routage sur Internet - Pack all-in-one.

Le tout (les sources LaTeX, les pdf, les images, la maquette, ...) est diffusé sous la licence habituelle de ce blog, à savoir : CC-BY-SA 3.0 France.

Lire la suite >>

news
research

Mettre en place un Route Reflector BGP avec Quagga pour s’amuser

Un court billet sur comment monter un Route Reflector avec Quagga sur une maquette.

Les termes Route Reflector (RR) et Route Server (RS) sont souvent confondus et on lit de tout sur le web, même sur les sites web qui disposent d'un bon crédit de fiabilité (univ-*.fr, *.edu) : « RR c'est pour monter un looking glass derrière, de la pure collecte passive, RS c'est pour redistribuer les routes », « RR c'est au contraire collecte + redistribution intelligente », « un RR fait du traitement, un RS redistribue "as-is", dans l'état ». Bref, personne ne semble être d'accord.

Pour y voir plus clair, je vous propose les deux ressources suivantes :

Personnellement, je retiens ce qui suit :

  • Les deux sont une solution (plus ou moins complexe, plus ou moins convenable en fonction de la topologie d'un réseau) au problème du full-mesh : que ce soit en interne d'un AS ou sur un GIX, établir des sessions iBGP (ou eBGP sur un GIX) entre tous les routeurs qui causent BGP en présence, c'est juste impossible, ça ne passe pas à l'échelle.
  • Un Route Reflector fait de la redistribution "as-is", dans l'état. Le choix des meilleures routes est donc centralisé, ce qui n'est pas toujours convenable selon l'emplacement du RR dans le cluster et dans l'AS (meilleure route pour un préfixe du point de vue du RR ne veut pas dire que ce soit forcement la meilleure route pour un client, possibilité de boucle, ...).
  • Un Route Server fait aussi de la redistribution mais effectue un traitement des annonces qu'il reçoit pour chacun de ses clients. On a donc plusieurs RIB, une par client du RS. Chacune contient les meilleures routes pour un client donné. Le client participe au choix de la meilleure route pour chaque préfixe connu grâce à ses filtres (route-map, ...) en entrée. La décision n'est donc pas centralisée.
  • Un RS est plus approprié pour un GIX, un RR est plus approprié pour de la redistribution interne à un AS.

Donc nous voulons bien mettre en place un Route Reflector : un truc qui redistribue bêtement (sans traitement) toutes les routes entre tous les routeurs d'un même AS, avec des sessions iBGP. On veut une topologie avec deux RR. Les deux RR sont reliés directement entre eux. Chaque autre routeur de cette topologie monte une session iBGP avec chacun des RR, pour la redondance.

Pour l'instant, nous n'avons pas de sessions eBGP entre nos RR et l'extérieur.

Pour ceux qui ont le cœur à creuser le paramètre « cluster-id » : Understanding BGP Originator-ID and Cluster-ID. Nous ne l'utiliserons pas ici.

Informations utiles pour s'y retrouver et comprendre les fichiers de config' :

  • IP du premier RR (loopback) : 198.18.3.1/32
  • IP du premier RR (loopback) : 198.18.3.15/32
  • Clients (loopbacks) : 198.18.3.2-30/32
  • Chaque client annonce un /30 subnetté dans 198.19.0.0/16
  • Les adresses des loopback sont prises dans 198.18.3/24. 198.18.0.0/16 est annoncé via un IGP. Mais ce n'est pas ce qui nous intéresse ici.

Voici les directives de configuration qu'il faut utiliser pour monter un Route Reflector avec Quagga. Source : Virtual Laboratory Networking Exercises – BGP Route Reflector Configuration.

Fichier « bgpd.conf » du premier RR :

hostname RR1
 
line vty
	no login
 
log syslog warnings
 
 
router bgp 64500
        # Qui suis-je ?
	bgp router-id 198.18.3.1
 
 
	## RR2
	neighbor 198.18.3.15 remote-as 64500
	neighbor 198.18.3.15 description RR2
	neighbor 198.18.3.15 update-source 198.18.3.1
 
 
	## Clients
	neighbor 198.18.3.2 remote-as 64500
	neighbor 198.18.3.2 description Client-1
	neighbor 198.18.3.2 route-reflector-client
	neighbor 198.18.3.2 update-source 198.18.3.1
 
        neighbor 198.18.3.3 remote-as 64500
	neighbor 198.18.3.3 description Client-2
	neighbor 198.18.3.3 route-reflector-client
	neighbor 198.18.3.3 update-source 198.18.3.1
 
        [...]

Fichier « bgpd.conf » du second RR :

hostname RR2
 
line vty
	no login
 
log syslog warnings
 
 
router bgp 64500
        # Qui suis-je ?
	bgp router-id 198.18.3.15
 
 
	## RR1
	neighbor 198.18.3.1 remote-as 64500
	neighbor 198.18.3.1 description RR1
	neighbor 198.18.3.1 update-source 198.18.3.15
 
 
	## Clients
	neighbor 198.18.3.2 remote-as 64500
	neighbor 198.18.3.2 description Client-1
	neighbor 198.18.3.2 route-reflector-client
	neighbor 198.18.3.2 update-source 198.18.3.15
 
	neighbor 198.18.3.3 remote-as 64500
	neighbor 198.18.3.3 description Client-2
	neighbor 198.18.3.3 route-reflector-client
	neighbor 198.18.3.3 update-source 198.18.3.15
 
        [...]

Fichier « bgpd.conf » d'un client (c'est pareil pour tous les autres clients) :

hostname C1
 
line vty
	no login
 
log syslog warnings
 
 
router bgp 64500
        # Qui suis-je ?
	bgp router-id 198.18.3.2
	network 198.19.0.0/30
 
 
        ## RR
	neighbor 198.18.3.1 remote-as 64500
	neighbor 198.18.3.1 description RR1
	neighbor 198.18.3.1 update-source 198.18.3.2
 
	neighbor 198.18.3.15 remote-as 64500
	neighbor 198.18.3.15 description RR2
	neighbor 198.18.3.15 update-source 198.18.3.2

Maquetter des réseaux avec LXC

Ce billet va tenter de résumer la manière dont j'utilise LXC pour créer et utiliser des maquettes de grande taille pour tester des choses (protocoles, logiciels, ...) ayant trait aux réseaux informatiques.

Table des matières

Pourquoi maquetter ?

Cela peut être utile de simuler la présence et les interactions d'un nouvel élément avant sa mise en production effective sur le réseau physique voire de maquetter un nouveau réseau complet pour voir s'il répond aux objectifs fixés avant d'acheter le matériel.

Maquetter permet aussi de découvrir et d'apprendre : mettre en œuvre des techniques, des protocoles, ... dans une maquette permet de les découvrir plus efficacement que d'étudier simplement la théorie.

Maquetter est aussi utile dans la recherche, pour faire des expériences et les rendre reproductibles, savoir quels facteurs sont aggravants (en les isolant les uns après les autres), trouver des solutions et les tester.

Les avantages de LXC pour maquetter

Bien que LXC puisse être utilisé pour isoler des applications, notamment pour un usage serveur, il présente également des avantages pour maquetter les machines d'un réseau.

LXC reste plus léger que de la virtualisation de type KVM : un ordinateur portable relativement modeste avec 3G de RAM fait tourner une maquette de 40 routeurs qui font de l'OSPF, du BGP et s'échangent un peu de trafic.

Dans un milieu plus "apprentissage/découverte", LXC est meilleur que Netkit (et ses frontend graphiques comme Marionnet), à mon avis, car LXC est maintenu activement et il offre la possibilité d'utiliser un noyau plus récent (2.26 avec Netkit, 2.19 avec Marionnet), ce qui n'est pas négligage quand on veut tester des fonctionnalités nouvelles ou quand certaines applications (notamment des démons) ont trop évoluées et ne sont plus capables de se binder sur un vieux noyau (il me semble avoir vu un cas avec Apache httpd). Sans compter la facilité de modification du système de base dans le cas de LXC (alors que c'est un véritable calvaire avec Netkit). Je ne sais pas ce qu'apporte (ou non) LXC comparé à User Mode Linux utilisé directement, sans passer par Netkit. ÉDIT du 19/09/2013 à 19h05 : Comme le mentionne Kartoch dans les commentaires, on peut utiliser Netkit sans avoir les droits root (modulo que /dev/shm ne doit pas être en noexec), ce qui a son intérêt dans une salle de TP à la fac/IUT/autre. Fin de l'édit

Néanmoins, autant dans un usage d'isolation des applications sur un serveur, je peux entrevoir les limites de LXC, la sécurité (un conteneur compromis qui permettrait de remonter au noyau et de mettre le zouk dans le reste du système/des autres conteneurs, cela ne me surprendrait pas), autant j'avoue ne pas savoir dans quels cas le fait que ce soit le même noyau dans l'hôte et dans tous les conteneurs est nuisible à un maquettage. Je peux simplement dire que cela me semble être utile dans les expériences aux timings serrés ou pour faire des mesures car la vision du temps est identique dans tous les conteneurs : l'instant T est le même dans tous les conteneurs.

Mettre des conteneurs LXC en réseau

Pour relier les conteneurs entre eux, on peut utiliser un ou plusieurs bridges. C'est intégré de base dans LXC et cela permet de voir tout le trafic de la maquette en dumpant simplement le trafic qui passe sur le bridge avec tcpdump/wireshark. Très pratique pour débugger, faire des stats, ... De plus, comme un bridge mémorise les MAC, comme un switch physique, le trafic unicast n'est pas transféré aux conteneurs qui n'en sont pas les destinataires.

Si l'on a besoin de fonctionnalités plus avancées (VLAN, agrégation de liens, ...), on peut utiliser Open vSwitch. J'avais testé pour découvrir : la communication entre conteneurs LXC juste marche. J'ai entendu dire que VDE ne fonctionnait pas avec les interfaces TAP de LXC. N'ayant jamais eu besoin de plus qu'un bridge, je n'ai jamais vérifié.

J'ignore s'il est possible d'interfacer LXC avec des routeurs Cisco/Juniper émulés. Dynamips semble pouvoir utiliser VDE mais comme LXC semble ne pas pouvoir ...

Adressage

Pour adresser/nommer votre maquette, je vous conseille fortement d'utiliser les ressources réservées à l'IANA : IPv4/v6, ASN, TLD, ... Cela fait sérieux et évite les collisions avec le réseau local (quand vous aurez eu à dépatouiller un tel cas, vous vous mettrez à utiliser les ressources réservées, je vous le garantit !).

Rendre la maquette plus réaliste

Au niveau réseau, Netem (network emulator) permet de rajouter de la latence, de la perte, de la corruption, ... sur les liens entre les différents conteneurs LXC. Pour que cela ne fasse pas trop artificiel, il est possible de faire varier la latence, la perte, ... en utilisant une distribution à la normale. On trouve plein d'exemples sur le web : Netem | The Linux Foundation, Simuler un lien WAN sous Linux chez NicoLargo, ... Netem est juste indispensable dès lors que l'on essaye de reproduire des réseaux réels ou, au moins, des conditions réelles.

Au niveau de chaque conteneur, les cgroups (control groups) permettent d'affecter des priorités d'accès aux ressources (CPU, réseau, ...) différentes pour chaque conteneur. Cela permet de favoriser un conteneur plutôt qu'un autre. Dans le cadre de maquettes réseau, cela permet de tenir compte des disparités que l'on trouve sur un réseau physique : on n'a des modèles de routeurs différents avec des capacités de traitement différentes ... Cela permet aussi de mesurer le comportement d'algorithmes de routage dans des situations défavorables. LXC lui-même est basé sur les cgroups. Je n'ai pas encore utilisé les cgroups dans une maquette donc je n'ai pas de ressources à conseiller plus que d'autres.

Automatiser le tout

Je vais vous montrer comment j'automatise la création et la gestion d'une grosse maquette avec des conteneurs LXC. L'ennui, c'est qu'il y a du besoin spécifique dedans (routing, forward, ...). Je vais essayer de tout bien vous expliquer pour que vous puissiez adapter à vos projets.

Preseed-file

Mes conteneurs sont tous basés sur Debian puisque Debian, c'est la vie. Pour créer des dizaines de conteneurs LXC à la chaîne, il est nécessaire d'avoir un preseed-file bien foutu qui configurera une bonne partie du conteneur (login, logiciels supplémentaires à installer, ...) lors de la création dudit conteneur sans poser aucune question dans une interface semi-graphique (ça ne passe pas à l'échelle ce genre de chose). Or, un preseed-file bien foutu, qui juste marche, bah ça ne court pas le web.

Voici celui que j'utilise, issu de quelques trouvailles personnelles minoritaires et de la fusion de ces deux modèles : Creating a Debian sliver template sur wiki.confine-project.eu et Debian wheezy preseed file for lxc-create -t debian lxc version 0.9.0.alpha2.

Pour le résumer :

  • Les conteneurs auront l'architecture amd64 et seront créés à partir du dépôt sid ;
  • Packages supplémentaires : less iputils-ping iptables telnet traceroute wget nano rsyslog bash-completion quagga et openssh-server ;
  • Utilisation d'un bridge nommé br0 ;
  • MAC fixe (on la remplacera plus loin vu que LXC ne sait pas faire tout seul) ;
  • On ne supprime pas la capabilitie « sys_admin » car elle est nécessaire à Zebra ;
  • On ne crée pas un compte utilisateur normal ;
  • Le mot de passe root est « toor » ;
  • On utilise le fuseau horaire « Europe/Paris » ;
# # Debian preseed file for CONFINE sliver template
# Tested on lxc 0.9.0~alpha3-2 and live-debconfig 4.0~a17.
 
# ## Distribution and packages
lxc-debconfig lxc-debconfig/distribution string sid
lxc-debconfig lxc-debconfig/architecture string amd64
lxc-debconfig lxc-debconfig/archives multiselect none
lxc-debconfig lxc-debconfig/mirror string ftp://ftp2.fr.debian.org/debian/
lxc-debconfig lxc-debconfig/archive-areas multiselect main
lxc-debconfig lxc-debconfig/packages string less iputils-ping iptables telnet traceroute wget nano rsyslog bash-completion quagga
 
# ## Network
# Please adjust to the name of the bridge used in your host.
lxc-debconfig lxc-debconfig/eth0-bridge string br0
# Private MAC address, to be replaced on sliver creation.
lxc-debconfig lxc-debconfig/eth0-mac string 52:C0:A1:AB:BA:1A
# Private veth interface name, to be replaced on sliver creation.
#lxc-debconfig lxc-debconfig/eth0-veth string veth-sliver
 
# ## Other container options
lxc-debconfig lxc-debconfig/auto boolean false
# Use live-debconfig to further configure the container.
lxc-debconfig lxc-debconfig/lxc-debconfig-with-live-debconfig boolean true
lxc-debconfig lxc-debconfig/apt-recommends boolean false
# Avoid debconf questions.
lxc-debconfig lxc-debconfig/debconf-frontend select noninteractive
## (default value)
##lxc-debconfig lxc-debconfig/debconf-priority string medium
 
# For running commands in the container and host at the end.
#lxc-debconfig lxc-debconfig/late-command string
#lxc-debconfig lxc-debconfig/late-host-command string 
 
 
# Capabilities to be dropped from the container.
lxc-debconfig lxc-debconfig/capabilities string \
    audit_control audit_write ipc_lock mac_admin mac_override \
    sys_module sys_pacct sys_rawio sys_resource sys_time \
    syslog wake_alarm
 
# For mounting filesystems in container.
#lxc-debconfig lxc-debconfig/mount0/entry string
##lxc-debconfig lxc-debconfig/mount0/comment string \
##    Bind mount host path in container
 
# ## Live-debconfig scripts configuration
 
# (For some reason live-debconfig options must be on a single line
# or the following options are not interpreted correctly.)
 
live-debconfig live-debconfig/components multiselect openssh-server, passwd
 
# ### LXC (sysvinit)
# Perform LXC tweaks in the container.
live-debconfig live-debconfig/sysvinit/lxc-enable boolean true
## (default values)
##live-debconfig live-debconfig/sysvinit/lxc-consoles string 6
##live-debconfig live-debconfig/sysvinit/lxc-disable-services string checkroot.sh hwclockfirst.sh hwclock.sh kmod module-init-tools mountall.sh mountkernfs.sh umountfs umountroot
 
### Hardware clock access (util-linux)
live-debconfig live-debconfig/util-linux/hwclockaccess boolean false
 
# ### Host name (hostname)
# Host name, to be replaced on sliver creation.
live-debconfig live-debconfig/hostname/hostname string sliver
 
# ### Network configuration (ifupdown)
live-debconfig live-debconfig/ifupdown/lo-comment string The loopback interface
live-debconfig live-debconfig/ifupdown/lo-enable boolean true
 
# Private interface method, to be replaced on sliver creation.
live-debconfig live-debconfig/ifupdown/eth0-ipv4-comment string The private interface
live-debconfig live-debconfig/ifupdown/eth0-ipv4-method select dhcp
 
# For static configuration of network interfaces.
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-method select static
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-address string 1.2.3.4
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-netmask string 255.255.255.0
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-gateway string 1.2.3.1
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-network string 1.2.3.0
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-broadcast string 1.2.3.255
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-mtu string 1500
##live-debconfig live-debconfig/ifupdown/eth0-ipv4-post-up string post-command
 
# For static configuration of DNS.
##live-debconfig live-debconfig/ifupdown/nameserver-addresses string 5.6.7.8 9.10.11.12
##live-debconfig live-debconfig/ifupdown/nameserver-domain string example.com
##live-debconfig live-debconfig/ifupdown/nameserver-search string lan example.com
##live-debconfig live-debconfig/ifupdown/nameserver-options string debug
 
# ### Users (passwd)
live-debconfig live-debconfig/passwd/shadow boolean true
live-debconfig live-debconfig/passwd/root-login boolean true
live-debconfig live-debconfig/passwd/make-user boolean false
live-debconfig live-debconfig/passwd/root-password string toor
live-debconfig live-debconfig/passwd/root-password-again string toor
 
# FUSEAU HORAIRE
tzdata tzdata/Areas select Europe
tzdata tzdata/Zones/Etc select UTC
tzdata tzdata/Zones/Europe select Paris

Depuis peu, il n'est plus possible d'utiliser un preseed-file avec le template Debian sauf à utiliser le package « lxc » qui se trouve dans le dépôt « experimental » de Debian. Voir : 0.9.0~alpha3-2+deb8u1 : “lxc” package : Debian .

Scripts

Ensuite, il faut des scripts pour automatiser la création, le démarrage, l'arrêt et l'éventuelle destruction des conteneurs. Ci-dessus, vous trouverez les scripts que j'utilise. Ce n'est pas du grand art mais ça fait ce qui doit être fait.

Commun

Commun est un fichier qui sert à positionner les variables et les tests utiles à plusieurs scripts comme le nom de tous les conteneurs de la maquette LXC ou vérifier les droits.

MACHINES="R1 R2 R3 R4"
 
if [ $USER != "root" ]
then
	echo "Vous devez exécuter ce script en étant root."
	exit 1
fi
Créer

Pour que vous puissiez comprendre ce script, je dois vous expliquer comment je hiérarchise les différents éléments qui permettent de créer la maquette.

Racine de la maquette
|-- network
|-- routing
|-- scripts
|-- tests

Network contient des fichiers nommés « config.$NOM_DU_ROUTER ». Chacun d'entre eux contient les instructions qui permettent de mettre en place le réseau sous LXC (« lxc.network.type », « lxc.network.ipv4 », « lxc.network.hwaddr », ...). Elles seront ajoutées au fichier « config » du conteneur correspondant lors de la création de la maquette. C'est aussi dans ce dossier que je stocke un fichier « hosts » qui fait la correspondance entre le nom de mes machines (voir des interfaces quand j'ai besoin d'une telle granularité (exemple : « 198.18.0.1 eth0.r1.local. »)) et leur adresse IP "principale" (une loopback, par exemple).

Routing contient, quand j'en ai besoin, les fichiers de configuration de Quagga. Exemple : bgpd.conf, ospfd.conf, zebra.conf, ... Tous sont suffixés avec le nom du conteneur LXC sur lequel devra être mis le fichier. Exemple : « zebra.conf.R1 ». Ils seront copiés dans le dossier /etc/quagga lors de la création de la maquette.

Scripts contient tous les scripts shell de gestion de la maquette. Typiquement ceux que je suis en train de vous présenter. :P

Tests contient des scripts ou des binaires qui permettent d'effectuer des tests sur la maquette. Le script bash « pingall » (voir plus bas) est typiquement un de ces moyens de test. Ils seront copiés dans /root.

Ceci étant dit, voici le script le plus complet que j'ai écrit pour construire une maquette avec LXC :

#!/bin/bash
 
source commun
 
HERE=`pwd`
PARENT=$HERE/..
 
for i in $MACHINES
do
	# Création du conteneur
	lxc-create -n $i -t debian -- --preseed-file=$HERE/preseed-file
 
 
	# Proc doit être en RW pour permettre l'activation de l'ip_forward
	sed -i 's/proc proc proc ro/proc proc proc rw/' /var/lib/lxc/$i/config
 
 
	# Pour que SSH accepte les connexions
	sed -i 's/UsePAM yes/UsePAM no/' /var/lib/lxc/$i/rootfs/etc/ssh/sshd_config
 
 
	# Mise en place du réseau
	head -n-6 /var/lib/lxc/$i/config > /var/lib/lxc/$i/config.tmp
	mv /var/lib/lxc/$i/config.tmp /var/lib/lxc/$i/config
	cat $PARENT/network/config.$i >> /var/lib/lxc/$i/config
 
	# Toutes les interfaces sont sur le même bridge donc les réponses ARP ne venant 
	# pas de la bonne interface peuvent être gênantes. Pour eviter ça, on active arp_filter
	echo "net.ipv4.conf.all.arp_filter = 1" >> /var/lib/lxc/$i/rootfs/etc/sysctl.conf
	echo "net.ipv4.conf.default.arp_filter = 1" >> /var/lib/lxc/$i/rootfs/etc/sysctl.conf
 
	intSurCeRouteur=`grep -Eo "eth[0-9]" /var/lib/lxc/$i/config`
 
	for j in $intSurCeRouteur
	do
			echo "net.ipv4.conf.$j.arp_filter = 1" >> /var/lib/lxc/$i/rootfs/etc/sysctl.conf
	done
 
 
	# Associations IP<->nom
	cat $PARENT/network/hosts >> /var/lib/lxc/$i/rootfs/etc/hosts
 
 
	# Routing (on veut zebra + ospf + bgp)
	cp $PARENT/routing/zebra.conf.$i /var/lib/lxc/$i/rootfs/etc/quagga/zebra.conf
	cp $PARENT/routing/ospfd.conf.$i /var/lib/lxc/$i/rootfs/etc/quagga/ospfd.conf
	cp $PARENT/routing/bgpd.conf.$i /var/lib/lxc/$i/rootfs/etc/quagga/bgpd.conf
	sed -i 's/^zebra=no/zebra=yes/' /var/lib/lxc/$i/rootfs/etc/quagga/daemons
	sed -i 's/^ospfd=no/ospfd=yes/' /var/lib/lxc/$i/rootfs/etc/quagga/daemons
	sed -i 's/^bgpd=no/bgpd=yes/' /var/lib/lxc/$i/rootfs/etc/quagga/daemons
 
 
	# Forward
	sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /var/lib/lxc/$i/rootfs/etc/sysctl.conf
 
 
	# Tests
	cp $PARENT/tests/pingall.sh /var/lib/lxc/$i/rootfs/root/
	chmod u+x /var/lib/lxc/$i/rootfs/root/pingall.sh
done
Lancer

On met en place ce qu'il faut (cgroups, création du bridge, on ne drop pas les paquets qui passent d'un conteneur à l'autre, ..) puis on lance les conteneurs et on vérifie qu'ils sont bien lancés.

#!/bin/bash
 
source commun
 
mount -t cgroup none /sys/fs/cgroup
 
brctl addbr br0 
ip link set up dev br0
 
iptables -P FORWARD ACCEPT
ip6tables -P FORWARD ACCEPT
 
for i in $MACHINES
do
	lxc-start -d -n $i
done
 
sleep 10
 
for i in $MACHINES
do
	echo "$i :"	
	lxc-info -n $i
	echo -e "\n"
done

Alors oui, ce script causera l'affichage d'erreurs lors d'utilisations successives car il n'y a pas de contrôles et que le bridge existe déjà et que les cgroups sont déjà montés. Rien de grave donc, juste trois lignes de textes sur la console. :P

Stopper

On arrête les conteneurs et on vérifie qu'ils ont bien été arrêtés.

#!/bin/bash
 
source commun
 
for i in $MACHINES
do
	lxc-stop -n $i
done
 
sleep 10
 
for i in $MACHINES
do
	echo "$i :"	
	lxc-info -n $i
	echo -e "\n"
done

Je sens que je vais me faire troller sur l'utilisation de « lxc-stop » qui fait un arrêt violent des conteneurs en lieu et place de « lxc-halt » qui laisse les conteneurs s'éteindre par eux-mêmes. L'explication est simple : sur chacune de mes maquettes, lxc-halt fonctionne pour quelques conteneurs très minoritaires même en attendant et je dois lancer lxc-stop ensuite ... Et comme je n'ai remarqué aucun dégât en utilisant uniquement lxc-stop ... bah j'utilise uniquement lxc-stop.

Détruire

Permet de détruire tous les conteneurs LXC de la maquette.

#!/bin/bash
 
source commun
 
for i in $MACHINES
do
	lxc-destroy -n $i
done
Netem

Pour ajouter une latence calculée et différente entre chaque lien sans utiliser de distribution à la normale :

#!/bin/bash
 
# À lancer sur l'hôte, après que toutes les interfaces du lab 
# aient été créées ... soit environ start.sh + 10 secondes
 
modprobe sch_netem
 
# Un groupe de lignes = un routeur. Ici R1
tc qdisc add dev lxc_R1_R2 root netem delay 1.180890283ms
tc qdisc add dev lxc_R1_R3 root netem delay 2.3495148631ms
 
# R2
tc qdisc add dev lxc_R2_R1 root netem delay 1.180890283ms
 
# R3
tc qdisc add dev lxc_R3_R1 root netem delay 2.3495148631ms
tc qdisc add dev lxc_R3_R4 root netem delay 0.8994545122ms
 
# R4
tc qdisc add dev lxc_R4_R3 root netem delay 0.8994545122ms

Pour appliquer d'autres caractéristiques (perte, corruption) sur un ou plusieurs liens, il suffit d'ajouter des lignes à ce script.

Pingall

Pour vérifier que le réseau de mes maquettes est opérationnel, j'utilise, en premier lieu, un bête script qui ping toutes les adresses IPs allouées (en utilisant les noms, comme ça, on teste aussi la validé du fichier /etc/hosts ;) ) et qui s'arrête à la première erreur rencontrée.

J'utilise souvent une loopback adressée sur chaque routeur. Cela permet de considérer les routeurs comme des destinations, ce qui est toujours utile (qui à dit MPLS ? :) ). Cela permet aussi "d'accrocher" les protocoles de routage dynamiques (exemple : BGP et « update-source ») dessus.

#!/bin/bash
 
INTERFACES_PHY="eth0.r1.local eth1.r1.local eth0.r2.local eth0.r3.local eth1.r3.local eth0.r4.local "
 
INTERFACES_LO="lo.r1.local lo.r2.local lo.r3.local lo.r4.local"
 
 
echo -e "\033[0;32m\n\n---------- Testons d'abord chaque lien ----------\n\033[0;39;49m"
j=0
for i in $INTERFACES_PHY
do
	ping -c 2 -w 2 $i
 
	if [ $? -ne 0 ]
	then
		echo -e "\033[0;31m\n\n---------- ÉCHEC ----------\n\033[0;39;49m"
		exit 5
	fi
 
	echo -e "\n"
done
 
 
echo -e "\033[0;32m\n\n---------- Testons ensuite chaque loopback ----------\n\033[0;39;49m"
j=0
for i in $INTERFACES_LO
do
	ping -c 2 -w 2 $i
 
	if [ $? -ne 0 ]
	then 
		echo -e "\033[0;31m\n\n---------- ÉCHEC ----------\n\033[0;39;49m"
		exit 5
	fi
 
	echo -e "\n"
done
 
 
echo -e "\033[0;32m\n\n---------- SUCCÈS ----------\n\033[0;39;49m"
exit 0
faq

Auto-hébergement sur OLinuXino

Aujourd'hui, je vous propose un billet sur les ordinateurs monocarte OLinuXino, concurrents (comme d'autres) du Raspberry Pi. On fera une comparaison des deux avant de voir comment on s'auto-héberge sur un OLinuXino.

Je vous conseille la lecture (ou au moins l'ouverture en parallèle) de mon billet sur comment s'auto-héberger avec un Raspberry Pi car je vais faire des parallèles et je tiendrai pour acquis la connaissance de certaines informations.

Je suis désolé pour la mise en forme minable de certaines parties ... On fait ce que l'on peut avec un WordPress. ;)

Table des matières

Quelle alternative libre au RPi ?

Il y a tout un tas d'ordinateurs monocarte concurrents du RPi sur le marché : OLinuXino, Cubieboard, Gooseberry, Hackberry, PandaBoard ... Lequel choisir ?

Tous les constructeurs utilisent plus ou moins les mêmes composants, notamment pour le CPU : les Allwinner AXX (exemples : A13, A20) et TI OMAPXX sont courants. Cela permet d'avoir plus de documentation pour une même erreur puisque l'erreur sera commune à plusieurs modèles d'ordinateurs monocarte. Cela rapproche aussi "les communautés" : j'ai remarqué ce fait entre la communauté autour des CubbieBoard et celle autour des OLinuXino.

Tous les fabricants prétendent faire de l'Open Source et de l'Open Hardware ...

Et tous les ordinateurs monocarte ont des inconvénients éthiques du point de vue de la liberté qu'ils accordent à leurs utilisateurs. Quelques exemples (tirés de : Single-board computers - Free Software Foundation) :

  • le GPU du RPi utilise un blob propriétaire ... et comme c'est lui qui fait l'amorçage du système ... ;
  • le chip WiFi des Cubieboard, Gooseberry et A13-OLinuXino-WIFI utilise un driver/firmware propriétaire ;
  • le GPU des BeagleBoard, OLinuXino, Cubieboard, Gooseberry, Hackberry et PandaBoard utilise un driver/firmware propriétaire. Le driver libre, Lima, n'est pas totalement abouti d'après ce je lis à droite et à gauche ;

Comme c'est bonnet blanc et blanc bonnet entre tous ces ordinateurs, je me suis contenté d'en choisir un parmi ceux :

  • qui ont des morceaux proprios uniquement dans les composants que je n'utilise pas et qui ont un comportement bien connu et attendu (exemple : le GPU sur OLinuXino ; contre-exemple : le GPU sur RPi qui sert aussi à booter le système d'exploitation) ;
  • qui sont distribués depuis la zone euro histoire d'éviter de me taper des conversions monétaires ;
  • qui ont un minimum de documentation potable.

C'est ainsi que j'ai choisi de me prendre un OLinuXino.

Quel OLinuXino choisir ?

Le modèle d'OLinuXino qui se rapproche le plus d'un Raspberry Pi modèle B, c'est l'OLinuXino A10S, le modèle sans la mémoire NAND 4G qui permet de se passer de SD pour booter/utiliser la carte mais dont le bootloader libre ne permet pas de tirer partie. L'OLinuXino A13 est supérieur au RPi en terme de puissance CPU, équivalent en terme de RAM disponible, ... mais ne dispose pas d'un port réseau. Il n'est donc pas comparable au RPi. L'OLinuXino iMX233 dispose d'un port réseau mais n'est pas comparable au RPi en terme de quantité de RAM disponible et de puissance CPU.

L'OLinuXino A10S coûte 54 € (TTC, hors frais de port) contre 37 € (TTC, hors frais de port) pour le RPi modèle B au moment où je l'ai acheté. Aujourd'hui, un RPi modèle B se trouve, dans la même boutique, pour 31 € (TTC, hors frais de port) donc l'écart se creuse mais nous verrons plus loin que la qualité des deux prestations n'est strictement pas équivalente. De même, il ne faut pas oublier que les prix du RPi sont tirés vers le bas à cause de sa popularité (popularité -> ils commandent des volumes plus gros de composants/production -> coûts tirés vers le bas -> gain répercuté sur le prix de vente).

Bien qu'un RPi modèle B soit déjà trop puissant pour faire office de petit serveur (DNS + mail + web + XMPP principalement) pour un ou pas beaucoup d'utilisateurs et que donc un OLinuXino A10S aurait largement suffit à ces usages, je me suis laissé tenté par un OLinuXino A20 à 66 € (TTC, hors frais de port). Un CPU double cœur, 1 GB de RAM, plus de connectique, ... Bref, tout ce qui sert à rien pour l'usage serveur précédemment décrit. :D Le surplus de puissance me permettra de monter du monitoring (usage qui à l'air d'être assez vorace sur un RPi), de tester des trucs, ce genre de choses ... Pour 10 € de plus, l'appel de l'usage futur est tentant. :)

Coût total d'acquisition

Pour ceux qui veulent se faire une idée du coût total d'acquisition (ie : quand on n'a ni l'adaptateur secteur, ni une carte SD, bref quand on n'a rien sous la main). Tous les prix sont TTC, souvent arrondis au supérieur. Bien sûr, ce qui suit est purement indicatif, vous trouverez peut-être des boutiques moins chères mais je ne rembourse pas deux fois la différence. :P

RPi (37 €) + adaptateur secteur/USB (7,43 €) + câble USB A vers micro USB B (pour aller de l'adaptateur au RPi) (2,93 €) + une carte SD (environ 10-12 € pour un produit décent) + transport (15-20 € pour un service décent avec assurance) : 75-80 € au total.

OLinuXino A20 (66 €) + transfo électrique (8,31 €) + carte SD (10-12 €) + transport (15-20 €) : 100-105 € au total.

Pour un OLinuXino A10S, le coût total s'élève à 87-92 €.

Pour le RPi, on peut aussi ajouter un boîtier à 7 €. À ma connaissance, il n'existe rien de tel pour les OLinuXino (sauf pour les IMX233).

OLinuXino A20 versus Raspberry Pi modèle B

Éthique

  • Le RPi est un projet de la Raspberry Pi Foundation, une association sans but lucratif reconnue comme œuvre de bienfaisance basée en Angleterre. OLinuXino est un produit d'Olimex, une société basée en Bulgarie. J'ai entendu une remarque selon laquelle c'est mieux de s'équiper en RPi plutôt qu'en OLinuXino car cela aide une association reconnue comme œuvre de bienfaisance. Sauf que, pour l'instant, je n'ai pas vu la RPi Foundation effectuer une donation ou un projet humanitaire. Si l'argent reste dans la caisse, ça permet, certes, d'investir, mais où est l'œuvre de bienfaisance ? Simplement fournir un ordinateur monocarte avec de bons morceaux propriétaires dedans ? Obtenir des réductions fiscales ? Bref, ma conscience est tranquille même si j'ai acheté un produit auprès d'une saloperie de société capitaliste qui exploite des Bulgares (et des Chinois -> Allwinner AXX) !
  • OLinuXino, plus libre que RPi ? Vaste question. Voici quelques éléments de réponse :
    • Au niveau des packages installés par défaut, je n'ai rien vu venant de contrib ou de non-free sur l'OLinuXino A20 avec vrms.

      Sur le RPi, les packages non-free suivants sont installés par défaut : firmware-atheros, firmware-brcm80211, firmware-libertas, firmware-ralink, firmware-realtek. Comme vous le voyez, il s'agit de firmwares pour cartes réseaux WiFi donc si vous n'utilisez pas de dongle WiFi, vous pouvez les désinstaller.

    • Sur le RPi, le GPU est totalement propriétaire. Donc le boot du système, l'affichage 2D/3D et le décodage/encodage vidéo matériel sont faits avec du logiciel sur lequel personne (sauf Broadcom) n'a le contrôle.

      Sur l'OLinuXino, le GPU et le chargement d'un OS depuis la flash interne (pour les modèles qui en sont équipés) sont totalement propriétaires. Donc l'affichage 2D/3D et le décodage/encodage vidéo matériel sont faits avec du logiciel sur lequel personne n'a le contrôle. Lima, le driver libre pour l'affichage 2D/3D ne semble pas être encore prêt pour mesa. Le VPU, un CedarX nécessite lui aussi des blobs propriétaires mais une alternative libre, basée sur du reverse engineering, est en train d'émerger mais reste encore à l'état de PoC bien que sachant déjà décoder le MPEG2 et H264. Notons que le GPU n'est pas responsable du chargement de l'OS donc, pour ceux qui veulent un serveur at home et pas un media center, l'OLinuXino me paraît être plus libre qu'un RPi.

    • Au niveau matériel, la RPi Foundation ne communique pas les schémas ni même les datasheet complètes (et pour cause, Broadcom les distribue uniquement sous NDA). Le RPi n'est donc pas un projet open hardware.

      Olimex semble distribuer l'intégralité des schémas et des datasheet. Voir :

      Olimex distribue tout ça sous licence CC-BY-SA. Les morceaux de code produits par Olimex sont sous GPL. Je vous laisse regarder le dépôt Github par vous même pour le reste des composants et les autres modèles d'OLinuXino.

      Je ne suis pas compétent pour affirmer si c'est de l'open hardware complet ou s'il manque des schémas ou des données techniques. J'émets néanmoins un bémol : on n'a pas les schémas des composants Allwinner (CPU,GPU,VPU). Comment fonctionnent-ils vraiment ? J'ai l'impression que seul le travail d'Olimex est distribué sous licence libre. Est-ce suffisant ?

    • Il est regrettable qu'Olimex utilise des formats de fichiers propriétaires et des services centralisés dans un projet qui se veut le plus ouvert et libre possible. Pour les services centralisés, je parle de Github (qui contient tous les documents importants) et de Google Docs (sur lequel sont stockés certains éléments comme les images Debian/Android des cartes SD). Un dépôt git, ça se met chez soi. Des images bien lourdes, ça se diffuse en torrent. Pour les formats de fichiers propriétaires, je parle principalement des rar disponibles ça et là dans le dépôt git. gzip, lzma, 7z existent ! Je ne jugerai pas l'usage du logiciel propriétaire Eagle vu que je suis un zéro pointé dès que l'on parle de conception de PCB. J'ai fait remonter ces griefs à Olimex. Réponse : « You are right that we still have some files in rar archives but those are files that we have already received as a rar from other sources (Allwinner technology and other manufacturers). In respect to their packaging we have kept the same package. All files modified or created by Olimex LTD are packed in zip archives. ». Ce à quoi je réponds : quid de l'image Debian pour carte SD qui est distribuée en rar via Google Docs ? ÉDIT du 13/09/2013 à 00h35 : « You are correct about the rar. We will try to upload files in 7-zip now on. » Fin de l'édit
    • Le dernier point problématique concerne le noyau fourni dans l'image officielle. Comme l'indique la page consacrée à l'OLinuXino A20 sur le wiki d'Olimex : « Note: Kernel 3.3 is based on Android SDK Kernel and may contain GPL violations which are behind our control, it's not recommended to use it nor to improve/contribute to it for this purpose better use Linux-Sunxi 3.4 kernel which have everything working exept the LCD touchscreen. We work on the TS issue to solve. »

      J'ai essayé de compiler le noyau 3.4. La compilation se passe bien mais le noyau ne boot pas : les fichiers de logs ne sont pas modifiés sur la carte SD. Je n'ai pas d'écran à brancher sur mon OLinuXino ni d'adaptateur série/USB sous la main donc je ne peux pas debugguer plus loin. Apparemment, je ne suis pas le seul à être en échec.

      Pour ceux qui voudraient essayer, je recommande les ressources suivantes :

Technique

  • Comme je l'ai écrit plus haut, entre un RPi et un OLinuXino, on n'est clairement pas dans le même niveau de prestation :
    • L'OLinuXino est livré dans une boîte en carton alors que le RPi est livré nu.
    • Les OLinuXino A10 et A20 sont équipés d'une horloge matérielle (RTC) ... mais comme il n'y a pas de batterie de base (on peut en acheter une, il y a un port matériel pour la brancher), je n'en vois pas l'intérêt (avoir une plus grande précision ?) : l'horloge se perd en cas de coupure de l'alimentation électrique. Ce point n'est pas gênant dans un usage serveur puisque tout administrateur consciencieux utilise NTP sur ses serveurs.
    • L'OLinuXino possède plusieurs boutons. Certains sont fortement utiles (RESET/PWR) mais le reste est totalement futile à mon avis. En effet, les boutons restants servent dans un contexte de media-center. Or, dans un tel contexte, qui va se bouger le cul pour aller appuyer sur ces boutons ? Télécommande powa.
    • L'OLinuXino utilise des bus séparés pour les ports USB là où le RPi utilise un même bus ce qui peut s'avérer limitant pour certains usages fortement consommateurs en capacité de transfert (webcam (OpenCV par exemple) + disque dur c'est déjà trop) puisqu'elle est partagée entre tous les périphériques de tous les ports. De même, la carte réseau de l'OLinuXino n'est pas greffée sur un contrôleur USB, contrairement à celle du RPi.
    • Pour ceux qui veulent faire de l'électronique et non pas un serveur avec leur OLinuXino (ce qui est quand même la destinée première de ces ordinateurs), ce dernier possède plus d'entrée/sorties que le RPi : sur le RPi, on parle de 17 entrées/sorties (dont 2*i2c et 2*UART) dont 5 sont partagées sur un même bus (source : GNU Linux Magazine France numéro 156). Sur l'OLinuXino A20, on parle de 160 GPIO (répartis sur 3 bus) + 2*UEXT + 1*UART ... Reste à voir combien de GPIO sont exploitables en parallèle.
    • Le reste de la connectique (audio, HDMI, USB, ...) reste quand même bonnet blanc et blanc bonnet entre le RPi et l'OLinuXino, à mon avis.
    • Un boîtier acheté en supplément peut contenir le RPi. À ma connaissance, rien n'est commercialisé ni même prévu pour les OLinuXino, à l'exception de l'iMX233. La boîte en carton de livraison semi-ouverte + une mousse non-conductrice et antistatique (pour le surélever dans la boîte) permet de compenser un peu ce manque ...
    • À l'inverse du RPi, l'OLinuXino A20 dispose d'une unique LED allumée en permanence : celle qui indique que la carte est sous-tension. Elle est de couleur rouge donc, à l'inverse des LEDs oranges et vertes du RPi, elle est moins irritante la nuit. Et la LED de l'OLinuXino ne pulse pas, contrairement à celles du RPi qui éclairent la moitié d'une pièce.
  • L'OLinuXino permet des transferts via le réseau plus rapides que le RPi.

    Pour l'envoi d'un fichier de 512 Mo, au contenu issu de /dev/zero, depuis mon RPi vers un desktop, en scp, j'obtiens un débit stable de 3,2 Mo/s.

    Ce n'est pas une limitation de la carte SD qui fournit 25 Mo/s environ en lecture. C'est une limitation du CPU du RPi :

    %Cpu(s): 51,8 us, 30,4 sy,  0,0 ni,  0,0 id,  0,0 wa,  1,3 hi, 16,6 si,  0,0 st
    25420 root    20   0  8912 1340  804 R  88,8  0,3   0:19.20 sshd                                                                  
    25421 root    20   0  2196  720  592 S   5,5  0,1   0:01.23 scp

    En utilisant netcat (« nc -vv -l -p 1234 > test » sur le desktop, « nc -vv <IP> 1234 < test » sur le RPi,), toujours sur TCP, pour transférer le même fichier, j'obtiens 5,6 Mo/s (mesuré avec iftop). Mais, même là, j'ai l'impression que le transfert est limité par la puissance du CPU du RPi :

    %Cpu(s):  4,5 us, 55,5 sy,  0,0 ni,  0,0 id,  0,6 wa,  2,9 hi, 36,5 si,  0,0 st
    25458 root    20   0  2344  724  600 R  89,3  0,1   0:41.71 nc
       36 root    20   0     0    0    0 S   4,5  0,0   3:43.15 mmcqd/0

    Sur mon OLinuXino A20, j'obtiens 5,2 Mo/s avec scp. On est CPU-limited : sshd n'utilise qu'un seul core, le CPU passe encore 40 % de son temps à idler :

    %Cpu(s): 31,5 us, 15,1 sy,  0,0 ni, 40,1 id,  0,0 wa,  0,0 hi, 13,3 si,  0,0 st
    2552 glucas    20   0  7892 1212  664 R  93,3  0,1   0:38.70 sshd
    2553 glucas    20   0  1772  648  520 R   9,3  0,1   0:03.06 scp

    Avec netcat, je ne suis plus limité par le CPU et j'obtiens 11,5 Mo/s.

  • La température de l'OLinuXino A20 est inférieure à celle du RPi. Je n'ai pas de thermomètre qui permettrait de prendre en compte uniquement la chaleur dégagée par l'ordinateur ni de caméra thermique donc c'est du pur ressenti bien subjectif. Peut-être que la plus grande surface de l'OLinuXino permet une dissipation thermique supérieure ...
  • Un RPi équipé de Raspbian utilise ses propres dépôts dont je ne sais pas si je peux avoir confiance (même si plein de miroirs sont hébergés par des gens sérieux, ça ne veut rien dire). J'ai tenté d'utiliser les dépôts Debian traditionnels sur mon RPi, je me suis pris une avalanche d'erreurs (même en désactivant la "branche" « RPi »), j'ai abandonné. Quid des mises à jour de sécurité ? En combien de temps sont-elles distribuées ? Je n'en sais rien, ce n'est pas documenté. Lors de la dernière faille de sécurité dans BIND, la mise à jour est apparue 1 jour plus tard que dans les dépôts Debian traditionnels. Ce délai peut être long dans le cas d'un usage serveur.

    L'OLinuXino utilise les dépôts Debian traditionnels pour les mises à jour/installations. Donc la team Debian, Debian-security, ....

    Notons que dans les deux cas, des logiciels sont installés en dehors du mécanisme apt. C'est le cas du noyau, par exemple. Il faudra voir ce que ça donne lorsqu'une faille de sécurité sera découverte sur ces logiciels là.

Autre

  • En une semaine, c'est acheté et livré. Et je parle bien de l'intégralité de ma commande. Contrairement au RPi où j'ai attendu plus d'un mois et demi avant de tout recevoir ... Oui, l'adaptateur USB/secteur c'est moins utile sans RPi ... Et RPi + adaptateur, c'est moins utile sans le cable USB/micro USB ... Pourtant, je n'ai pas commandé mon RPi durant leur période de gloire où tout le monde en voulait un.

Les grandes lignes pour transformer son OLinuXino en serveur

J'utilise l'image Debian fournie par Olimex sur leur wiki.

  • Si vous avez acheté la carte SD avec l'image Debian dessus, le /etc/network/interfaces est incorrect : l'interface eth0 ne sera pas montée au boot car la ligne « auto eth0 » est commentée et même si elle ne l'était pas, l'interface est configurée avec un adressage statique en 192.168.0.244/24. Il faut donc changer ça en mettant la SD dans un lecteur de cartes mémoires puis en modifiant /etc/network/interfaces. Rien à signaler sur l'image téléchargée. J'ai fait remonter l'info au support d'Olimex.
  • Pour faire booter la carte, il n'y a pas de manipulations compliquées, c'est comme avec le RPi : alimentez-la en électricité et ça part tout seul. Après quelques dizaines de secondes, un nmap -sV vous montrera qu'un serveur SSH tourne sur l'OLinuXino. Il suffit donc de s'y connecter : root/olimex.
  • Comme avec le RPi, la première chose à faire est de créer un utilisateur normal puis de changer le mot de passe du compte root pour un mot de passe fort. Puis déposer sa clé publique, modifier la configuration du serveur SSH pour ne pas autoriser les connexions en tant que root (su est là pour l'élévation de privilèges) et pour autoriser uniquement l'authentification par clés, ... Bref, tout ça c'est du classique.
  • Il convient de compléter le fichier /etc/apt/sources.list qui est notoirement incomplet : il manque les dépôts debian-security et volatile (renommé stable-updates depuis wheezy).
    # STABLE
    deb ftp://ftp.debian.org/debian/ wheezy main
     
    # STABLE-UPDATES (EX-VOLATILE)
    deb ftp://ftp.debian.org/debian/ wheezy-updates main
     
    # SECURITY
    deb ftp://security.debian.org/debian-security/ wheezy/updates main

    Bien sûr, il faudra faire un apt-get update, as usual.

  • Faire les mises à jour (sauf si l'installation est fraîche, of course) :
    apt-get -y update && apt-get -y upgrade &&  apt-get -y dist-upgrade && apt-get -y autoremove && apt-get -y autoclean
  • Changer (ou pas) d'IO scheduler pour un scheduler plus adapté aux mémoires flash :
    L'intérêt de cette manipulation fait souvent débat de ce que j'ai vu dans les forums. Je vous conseille de tester vous même car cela dépend de la carte SD. Pour moi, le résultat est sans appel :

    Avec le scheduler deadline :

    dd if=/dev/zero of=test bs=1M count=512
    512+0 records in
    512+0 records out
    536870912 bytes (537 MB) copied, 52.2637 s, 10.3 MB/s
     
    rm test
     
    sleep 60 && pkill -2 dd &
    dd if=/dev/zero of=test
    1122023+0 records in
    1122023+0 records out
    574475776 bytes (574 MB) copied, 60.1867 s, 9.5 MB/s
    [1]+  Done                    sleep 60 && pkill -2 dd

    Avec le scheduler NOOP :

    dd if=/dev/zero of=test bs=1M count=512
    512+0 records in
    512+0 records out
    536870912 bytes (537 MB) copied, 44.4487 s, 12.1 MB/s
     
    rm test
     
    sleep 60 && pkill -2 dd &
    dd if=/dev/zero of=test
    1167132+0 records in
    1167132+0 records out
    597571584 bytes (598 MB) copied, 63.1541 s, 9.5 MB/s
    [1]+  Done                    sleep 60 && pkill -2 dd

    De plus, j'ai un sentiment d'une meilleure réactivité du système, en cas de fortes lectures/écritures avec le scheduler noop.

    Pour voir le scheduler actif et le changer temporairement (pour modifier, il faut être root, of course) :

    echo noop > /sys/block/mmcblk0/queue/scheduler
    cat /sys/block/mmcblk0/queue/scheduler
    [noop] deadline

    Pour le changer définitivement, il faut créer un fichier « uEnv.txt » à la racine de la première partition de votre carte SD (là où il y a « script.bin » et « uImage ») qui contient :

    extraargs=elevator=noop

    Ce fichier est utilisé par U-boot pour compléter sa variable « bootargs » qui permet de passer des paramètres au noyau (cmdline).

    J'ai trouvé le mécanisme sur la page suivante : linux-sunxi/u-boot-sunxi.

    Normalement, lors du prochain reboot de votre OLinuXino, le scheduler noop sera utilisé et cat /proc/cmdline affichera ceci :

    console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait loglevel=8 panic=10 elevator=noop
  • Changer le fuseau horaire : soit tzselect, soit :
    echo "Europe/Paris" > /etc/timezone 
    cp /usr/share/zoneinfo/Europe/Paris /etc/localtime
  • Configurer les applications pour le français :
    dpkg-reconfigure locales
     
    # Et comme ça ne fonctionne pas ...
    sed -i 's/LANG=en_US.UTF-8/LANG=fr_FR.UTF-8/' /etc/environment
  • Désinstaller l'inutile pour un serveur (gain : environ 550 Mo) :
    apt-get autoremove --purge gnome-* xserver-* desktop-* consolekit hicolor-icon-theme vim-* aspell aspell-en tsconf scratch notification-daemon dictionaries-common lightdm lightdm-gtk-greeter gcc g++ mplayer alsa-base alsa-utils gcc-4.6 gcc-4.6-base dosfstools esound-common wireless-tools wpasupplicant mpg321 mpg123 wdiff patch isc-dhcp-client
  • Installer l'indispensable :
    apt-get install iptables telnet traceroute rsyslog bash-completion tcpdump ethtool dnsutils
  • Installer votre indispensable (screen/tmux, vim/nano/emacs, bash/dash/zsh, ...).
  • Installer vos logiciels serveur et les configurer avec vos réglages habituels. Ces configurations ne changent pas.

Notes :

  • Pas besoin de charger le module ipv6, il est compilé "en dur" dans le noyau, contrairement au RPi.
  • Pour le split de la RAM entre CPU et GPU, je ne sais pas comment cela se passe sur OLinuXino. Je n'ai rien trouvé de convaincant à ce sujet. Pas même dans les fichiers scripts.(bin|fex). Je constate que j'ai 975 Mo de RAM adressables par le système.

Les problèmes

Un manque de neutralité

Les problèmes liès à mon Fournisseur d'Accès à Internet, qui ne permet pas à ses clients d'installer un serveur et donc d'être vraiment sur Internet, restent évidemment inchangés entre mon RPi et mon OLinuXino. Je vous invite donc à lire la section « Les problèmes » de mon billet sur le RPi pour un usage serveur.

OpenDNSSEC/SoftHSM

SoftHSM ne segfault plus lors de l'initialisation des token mais l'erreur « error parsing RR at line » se manifeste ici aussi.

Un load average toujours supérieur ou égal à 1

Avec l'image Debian (apparemment, cela ne se produit pas avec l'image Android), on constate que la charge système ne cesse de monter dès le boot pour se stabiliser à 1 et ne plus jamais redescendre sous ce seuil quand bien même aucun service n'est lancé ... juste le noyau et les démons de base (log, sshd, ...).

Avec la commande top, on observe que c'est ksoftirqd, processus dédié à la mise en queue des interruptions logicielles (qui sont souvent traitées suite à des interruptions matérielles) lorsqu'il y en a trop, qui est le processus le plus consommateur de CPU. On observe également qu'environ 5 % du temps CPU part dans le traitement d'interruptions logicielles :

%Cpu(s):  0,3 us,  0,9 sy,  0,0 ni, 93,7 id,  0,0 wa,  0,0 hi,  5,1 si,  0,0 st

En regardant dans /proc/interrupts, on constate que deux interruptions se démarquent nettement et que leurs nombres de déclenchements progressent très rapidement (environ 100 par seconde) :

           CPU0       CPU1       
 29:      28685      43852       GIC  arch_timer
 30:          0          0       GIC  arch_timer
 32:          0          0       GIC  axp_mfd
 33:        161          0       GIC  serial
 37:          1          0       GIC  RemoteIR
 39:      14059          0       GIC  sun7i-i2c.0
 40:          0          0       GIC  sun7i-i2c.1
 41:          0          0       GIC  sun7i-i2c.2
 54:       3294          0       GIC  timer0
 56:          0          0       GIC  sunxi-rtc alarm
 59:          0          0       GIC  dma_irq
 64:      33270          0       GIC  sunxi-mmc
 67:          0          0       GIC  sunxi-mmc
 71:          0          0       GIC  ehci_hcd:usb2
 72:          0          0       GIC  ehci_hcd:usb4
 76:     151786          0       GIC  dev_name
 77:          0          0       GIC  dev_name
 79:      75888          0       GIC  dev_name
 80:          0          0       GIC  dev_name
 87:       6823          0       GIC  eth0
 96:          0          0       GIC  ohci_hcd:usb3
 97:          0          0       GIC  ohci_hcd:usb5
IPI0:          0          0  Timer broadcast interrupts
IPI1:      18364      17755  Rescheduling interrupts
IPI2:          0          0  Function call interrupts
IPI3:         23        109  Single function call interrupts
IPI4:          0          0  CPU stop interrupts
IPI5:          0          0  CPU backtrace
Err:          0

Évidemment, les dev' n'ont pas donné un nom représentatif à leurs interruptions, sinon ça serait trop facile.

La solution est détaillée ici : loadavg always >=1.00 on debian sur le forum Olimex. Cette surcharge est générée par port mini-USB (qui peut être utilisé en USB OTG) et par le fait que « The whole USB support is flawed in 3.3. » (et apparemment, le sous-système USB de la version 3.4 provoque d'autres bugs).

Voici comment contourner ce problème (tutoriel issu de la combinaison du lien précédent et de documentation related to script.bin/script.fex sur le forum Olimex) :

Il faut récupérer les sunxi-tools :

git clone https://github.com/linux-sunxi/sunxi-tools

Les compiler (non, pas de ./configure) :

cd sunxi-tools
make

La compilation va échouer pour des problèmes de dépendances. Mais ce n'est pas grave : les outils dont nous avons besoin, bin2fex et fex2bin, ont été compilés avec succès.

On transforme le fichier script.bin qui se trouve sur la première partition de votre carte SD en fichier humainement compréhensible (non, on n'est pas obligé de stocker le fichier script.fex sur la carte SD, je fais ça pour m'y retrouver et pour le conserver) :

./bin2fex /path/to/SD/card/script.bin > /path/to/SD/card/script.fex

On effectue les modifications. Pour rappel, ces modifications sont (le reste de la section « [usbc0] » reste inchangée) :

[usbc0]
usb_port_type = 1
usb_detect_type = 0
usb_host_init_state = 1

On fait une copie de sauvegarde puis on crée le nouveau script.bin :

cp /path/to/SD/card/script.bin ~/script.bin.save
./fex2bin /path/to/SD/card/script.fex > /path/to/SD/card/script.bin

En bootant l'OLinuXino, on se rend compte que le load average n'est plus bloqué à 1 mais qu'il est largement inférieur. Par contre, environ 5 % du temps CPU est encore occupé par les mêmes interruptions logicielles qui se déclenchent toujours à la même fréquence ...

Je ne comprends pas ...

D'une part, en regardant le fichier arch/arm/plat-sunxi/include/plat/irqs.h de linux-sunxi, on se rend compte que eth0 utilise l'interruption numéro 87 :

#define SW_INT_IRQNO_EMAC		(55 + SW_INT_START) // SW_INT_START = 32

Cela correspond donc bien à la réalité. En suivant la même logique, l'IRQ 76 (celle qui pose problème) est attribuée à SW_INT_IRQNO_LCDCTRL0 et l'IRQ 79 est attribuée à SW_INT_IRQNO_DEFEBE0. Pour l'IRQ 79, je ne sais pas aller plus loin. Mais pour l'IRQ 76, je peux dire que je n'ai pas d'écran LCD sur mon OLinuXino et que c'est peut-être ce qui pose problème.

J'ai tenté de désactiver lcd(0|1) dans script.(fex|bin) en passant la valeur de « lcd_used » à 0, en supprimant tout sauf cette ligne (sans les mapping, la carte ne devrait pas savoir exploiter l'éventuel LCD) ainsi que de passer la valeur de « disp_init_enable » à 0, mais rien n'y fait : la charge est toujours >= 1. Par contre, les interruptions 76 et 79 ne se déclenchent plus (« 0 » dans /proc/interrupts).

D'autre part, ce n'est pas les hi (hardware interrupts) qui prennent environ 5 % du temps CPU mais les si (software interrupts). Les interruptions logicielles sont souvent traitées suite à des interruptions matérielle mais sait-on jamais ... Donc le fichier à regarder est /proc/softirqs. Mais je ne vois rien d'anormale ... Les interruptions qui se déclenchent le plus sont TIMER et SCHED ... comme sur mon RPi ou sur mes desktop. Du coup, je ne vois pas comment elles peuvent consommer environ 5 % du temps CPU alors qu'elles consomment 0 % sur mes autres systèmes.

Mes compétences s'arrêtent ici.

Reproche

Mon seul reproche à Olimex sera l'utilisation d'un format de fichier propriétaire (rar) ainsi que l'hébergement de certains éléments, comme les images de carte SD, sur Google Docs ... Sérieusement ... Comme je l'ai écrit plus haut, j'ai fait remonter ces griefs au support d'Olimex.

privacy
partner
news
Bear
research