Manux a sa propre architecture de l'espace utilisateur, qui ne ressemble ? aucune autre. Essayons de la d?crire.
Tout d'abord, ?tudions la disposition des fichiers sur le disque dur. Pour comparaison, voici l'aspect de la racine d'une distribution Linux classique :
ecolbus@linux:~$ ls -F / bin/ etc/ lib/ opt/ sbin/ tmp/ vmlinuz.old@ boot/ home/ lost+found/ proc/ selinux/ usr/ cdrom/ initrd.img@ media/ root/ srv/ var/ dev/ initrd.img.old@ mnt/ run/ sys/ vmlinuz@
Montons ? pr?sent la partition racine d'un syst?me Manux, et voyons ce qu'elle contient :
root@linux:~# mount /mnt/manux-ro root@linux:~# ls -F /mnt/manux-ro/ lost+found/ packages/
Comme vous vous en rendez sans doute compte, ce n'est pas exactement ainsi que la racine d'un syst?me UNIX classique est sens?e appara?tre.
D?crivons rapidement ces ?l?ments. "lost+found" est un r?pertoire li? au syst?me de fichiers qui doit se trouver dans sa racine. "packages", qui correspondra effectivement ? "/packages" lorsque le syst?me fonctionnera, est le r?pertoire qui contient tous ses paquetages; toutefois, sous Manux, tous les fichiers font partie d'un paquetage. Donc, oui, "/packages" contient l'ensemble du syst?me d'exploitation. Enfin, "/" lui-m?me est un r?pertoire sp?cial, toujours inatteignable (sauf si vous d?cidez de monter la partition ailleurs), qui sert ? certains algorithmes du syst?me de fichiers virtuel (module noyau : sfv).
Bien. ? pr?sent, qu'y a-t-il dans "/packages" ?
root@linux:~# ls -F /mnt/manux-ro/packages/ core/ local/ std/
Ici, nous n'avons que 3 r?pertoires, parce que nous sommes dans la version 0.0.1. Chacun correspond ? une distribution, ou un distributeur (par exemple, si le roi Arthur d?cidait d'empaqueter et de distribuer son logiciel de recherche de Graal, il irait dans "/packages/table_ronde"), ? l'exception de "local", qui contient les paquetages sp?cifiques aux utilisateurs de la machine, comme leurs r?pertoires personnels.
En ce qui concerne les deux autres, "core" contient le coeur du syst?me d'exploitation, tandis que "std" contient la distribution initiale, avec des composants si communs (comme la glibc ou bash) qu'ils seront vraisemblablement r?utilis?s sans modifications par d'autres distributions.
Mais qu'y a-t-il dans ces r?pertoires? Essayons quelques commandes.
root@linux:~# ls -F /mnt/manux-ro/packages/std/0.0.1/vim/7.3 alias/ etc/ misc/ userdirs/ vim/ root@linux:~# ls -F /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim lnc/ lncb/ meta/ root/ userdirs
L?, les choses commencent ? devenir int?ressantes. Notons tout d'abord que tous les paquetages sont situ?s dans des arborescences organis?es de la m?me fa?on dans /packages : "distrib/version_distrib/logiciel/version_logiciel/portion_logiciel". A cet emplacement se trouvent deux r?pertoires obligatoires, "root" et "meta", respectivement le contenu et les m?tadonn?es du paquetage, ainsi que deux r?pertoires optionnels, "lncb" et "lnc", qui sont li?s ? la fa?on de lancer les ?ventuels ex?cutables du paquetage. Accessoirement, nous notons un curieux fichier nomm? "userdirs" :
root@linux:~# stat /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/userdirs Fichier : "/mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/userdirs" Taille : 4096 Blocs : 8 ES blocs : 4096 fichier ?trange Device : 807h/2055d Inode : 195906 Liens : 2 Acc?s : (0777/?rwxrwxrwx) UID : ( 0/ root) GID : ( 0/ root) Acc?s : 2013-07-06 15:34:38.000000000 +0200 Modi. : 2013-07-06 15:34:38.000000000 +0200 Chgt : 2013-07-06 15:34:38.000000000 +0200 Cr?? : -
Il s'agit en fait d'un lien mat?riel vers un r?pertoire, mais nous verrons cela plus loin.
Quel est l'aspect des choses dans "root"? Voyons, voyons :
root@linux:~# ls -F /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/root/ etc/ lib/ tmp/ usr/
Ah, ben ?a, ?a ressemble ? une racine standard!
Sous Manux, tous les programmes de l'espace utilisateur sont chroot?s, et leurs paquetages leurs servent de racines. Cela dit, mentionnons imm?diatement que ce r?pertoire n'a ce contenu que parce que nous observons un syst?me d?j? install?. Dans le r?pertoire "root", ce paquetage ne fournit en fait que le contenu de /usr/bin :
root@linux:~# ls -F /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/root/usr/bin/ vim*
(Bon, pour ?tre exact, il fournit aussi un fichier vide /etc/ld.so.cache, mais c'est sans importance.)
Qu'en est-il de "meta"?
root@linux:~# ls -F /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/meta/ crypto/ deps files identity install* origins userdirs
Il s'agit des donn?es requises par le syst?me de paquetages, dont la description sera le sujet d'un autre document.
Et "lncb" et "lnc"?
root@linux:~# ls -l /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/lnc{b,} /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/lnc: total 16 -rwxr-xr-t 2 root root 12784 juil. 6 15:34 vim /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/lncb: total 4 -rw-r--r-- 1 root root 390 janv. 1 1970 vim.lncb
Comme pr?c?demment mentionn?, ces r?pertoires sont li?s aux exacutables, donc dans le paquetage de vim, il n'est pas surprenant de ne trouver que des fichiers li?s ? vim. Le r?pertoire "lncb" contient un fichier fourni par le paquetage sp?cifiant comment lancer vim ("lnc" signifie "lanceur", le "b" indique le format binaire non-ex?cutable), tandis que "lnc" contient les v?ritables lanceurs cr??s ? partir des fichiers lncb durant l'installation du paquetage. (Pourquoi faire si compliqu?, demandez-vous? Et bien, nous devons g?rer le cas o? l'empaqueteur est en fait hostile. Le format lncb est tr?s limit?, mais il garantit que les lanceurs cr??s ? partir de lui demeureront inoffensifs).
Mais int?ressons-nous au fichier "lnc/vim". Il s'agit d'un ex?cutable :
root@linux:~# file /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/lnc/vim /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim/lnc/vim: sticky ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
Mais il est bien plus petit que le vrai ex?cutable de vim. De plus, il est li? statiquement, il a deux liens mat?riels, et son bit sticky est activ?. Qu'est-ce que cela signifie?
Comme nous l'avons dit, la t?che de ce fichier est de lancer vim lorsqu'il est appel?. Dans la mesure o? tous les processus sont chroot?s, si l'utilisateur appelle vim, son shell va devoir appeler ce lanceur depuis son chroot. C'est possible parce que ce lanceur est li? mat?riellement dans la racine de l'utilisateur - d'o? le second lien mat?riel. Si d'autres applications avaient une d?pendance sur vim, ou s'il y avait plus d'utilisateurs sur cette machine, il y aurait plus de liens mat?riels, mais ce n'est pas le cas.
Mais il y a un probl?me : quelle biblioth?que C est disponible dans le chroot de l'appelant? R?ponse : nous ne pouvons pas le savoir ? l'avance, aucune n'est garantie, et en plus, le paquetage appelant pourrait ?tre hostile, donc il n'est pas possible de d?pendre de ses biblioth?ques. C'est pourquoi tous les lanceurs sont li?s statiquement.
Finalement, comment ce binaire est-il sens? trouver le vrai binaire de vim lorsqu'il est appel? depuis un chroot externe arbitraire? C'est ici que le bit sticky entre en jeu.
La signification du bit sticky sur des fichiers r?guliers n'est pas sp?cifi?e, et en pratique, il n'est pas utilis?; j'ai donc d?cid? de le r?utiliser dans mon syst?me de fichiers. Dans ext2l, le bit sticky sur un fichier r?gulier informe l'utilisateur que ce fichier a un lien racine, un nouveau type de lien, semblable ? un lien mat?riel, qui associe asymm?triquement un fichier r?gulier ? un r?pertoire. Seul un processus ex?cutant ce fichier r?gulier peut en faire usage, et lorsqu'il le fait, son chroot change, et le r?pertoire vis? devient sa nouvelle racine (et son nouveau r?pertoire courant). Dans le cas habituel, le r?pertoire vis? est le "/root" du paquetage, mais il se trouve que vim est une exception - nous verrons pourquoi plus tard. Pour l'instant, voyons ce qui se passe lorsque quelqu'un appelle un programme plus standard, /bin/cat :
Ainsi, gr?ce au lien racine, une application est parvenue ? en appeler une autre sans qu'aucune n'aie jamais eu acc?s au chroot de l'autre.
Ne finissons pas cette discussion sans exmpliquer la sp?cificit? de vim. Ce qui s?pare vim de cat, techniquement, c'est que vim comporte des fichiers de configuration (~/.vim*). Les g?rer requiert une proc?dure bien plus complexe.
Tout d'abord, pr?cisons le terme. Un userdir est un r?pertoire contenant des fichiers sp?cifiques ? une combinaison {utilisateur, version d'une application}. Les syst?mes d'exploitation classiques stockent ces informations dans le r?pertoire personnel de l'utilisateur, mais cette approche simple ne fonctionnerait pas sous Manux, dans la mesure o? les programmes n'ont pas acc?s ? ce r?pertoire. D'o? la n?cessit? d'un emplacement sp?cial.
Observons ? nouveau nos commandes initiales :
root@linux:~# ls -F /mnt/manux-ro/packages/std/0.0.1/vim/7.3 alias/ etc/ misc/ userdirs/ vim/ root@linux:~# ls -F /mnt/manux-ro/packages/std/0.0.1/vim/7.3/vim lnc/ lncb/ meta/ root/ userdirs
Ah, oui, voil? l'userdir. Mais pourquoi y en a-t-il deux?
Souvenez-vous que la premi?re commande n'a fait que lister les paquetages pr?sents dans /packages/std/0.0.1/vim/7.3 . Donc le premier est un paquetage ind?pendant - sa raison d'?tre est de permettre ? l'empaqueteur de fournir une configuration par d?faut, et de stocker ces userdirs.
Et le second? Souvenez-vous de ce qui a ?t? dit ? son sujet plus haut : il s'agit d'un lien mat?riel vers un r?pertoire, plus pr?cis?ment vers le r?pertoire "root" du premier.
Pourquoi faire si compliqu?, demandez-vous? Et bien, tout d'abord, rien ne sp?cifie que vim 7.3 est tenu d'employer les userdirs de vim 7.3 - si la configuration ?tait rest?e compatible, et si un tel paquetage existait, il pourrait utiliser les userdirs de vim 7.2 (la fa?on dont le userdir est trouv? rel?ve du syst?me de paquetage). Donc, le premier n'est pas r?ellement utilisable.
De plus, il se trouve que, lorsqu'un logiciel a des userdirs, ses lanceurs ont un lien racine pointant vers le p?re imm?diat de leur r?pertoire "/root". Mais ? pr?sent, les explications th?oriques deviennent un peu compliqu?es, donc voyons en pratique les op?rations qui ont lieu lorsque quelqu'un lance vim :
De la sorte, la variable d'environnement HOME a ?t? modifi?e afin que vim y trouve les fichiers de configuration de l'utilisateur sans pouvoir acc?der ? la configuration d'autres personnes. Ce choix architectural implique que la variable HOME peut changer sans que l'utilisateur n'en aie le contr?le; c'est un prix ? payer pour la s?curit? du syst?me d'exploitation.
Ha! Vous pensiez r?ellement que nous avions fini? Regardez bien les exemples pr?c?dents, vous ne remarquez pas qu'il reste un probl?me?
J'explique. Si l'utilisateur d?cide de lancer "cat", tout ira bien, en effet. Mais que se passera-t-il s'il tape "cat mon_fichier.txt"?
Oui, regardez attentivement. Le lanceur va se chrooter, puis appeler cat, qui va chercher un fichier nomm? "mon_fichier.txt" dans son r?pertoire... Mais il a ?t? chroot? (et sous Manux, xchroot(2) implique chdir(2)), donc le fichier ne s'y trouvera pas. Comment est-ce sens? fonctionner?
Je vais l'expliquer, mais une remarque avant tout : cela ne peut pas ?tre montr? sur un syst?me Manux arr?t?. D?marrons-le donc, tapons notre login/mot de passe, et jetons un oeil ? notre r?pertoire personnel.
ecolbus@manux:~$ pwd /.../home/ecolbus
Ah! Il y a quelque chose de nouveau, ici! Ce n'est pas /home/ecolbus, mais /.../home/ecolbus . Bon, essayons d'autres commandes...
ecolbus@manux:~$ touch file ecolbus@manux:~$ ls -l file -rw-r--r-- 1 ecolbus ecolbus 0 20 juil. 01:33 file ecolbus@manux:~$ ls -l /.../home/ecolbus/file -rw-r--r-- 1 ecolbus ecolbus 0 20 juil. 01:33 /.../home/ecolbus/file
Jusqu'? pr?sent, tout va bien...
ecolbus@manux:~$ ls -l /bin/cat -rwxr-xr-t 4 sys sys 5264 13 juil. 15:05 /.../??/cat
Euh, quoi? Le nom du fichier a chang??
Oui, il a chang?. ? pr?sent, place aux explications.
/... est un syst?me de fichiers sp?cial, sans existence r?elle, comme /proc (son module noyau est p3p). A la diff?rence de /proc, /... peut toujours ?tre atteint, quel que soit le chroot. De plus, son contenu d?pend du processus qui le regarde, et le fait de savoir s'il est visible ou non dans / n'est pas sp?cifi? (actuellement, il ne l'est jamais).
Ce syst?me de fichiers ne peut contenir que des r?pertoires (et des liens symboliques), mais il est possible de lui demander d'?tablir des associations entre ses entr?es de r?pertoire et des fichiers "r?els" (voyez xchroot(2)). Par exemple, on peut lui demander "fais correspondre /.../abcd/efgh ? mon fichier /etc/hostname", et le nouveau chroot contiendra une entr?e /.../abcd/efgh correspondant au pr?c?dent /etc/hostname.
Le rapport avec notre affaire? Et bien, comme je l'ai dit, il y a un probl?me si quelqu'un tente de taper "cat mon_fichier.txt". Vous vous souvenez lorsque j'ai dit que le lanceur "effectuait diverses analyses"? C'est l? son autre fonction : il analyse la ligne de commande, s?parant ce qui est un fichier de ce qui n'en est pas un, et passe tous les fichiers n?cessaires dans le chroot de la nouvelle commande, dans son r?pertoire /... .
(Pour des raisons techniques, cela doit avoir lieu dans le m?me appel-syst?me que le chroot, c'est donc ? nouveau le travail de xchroot(2). Cette fois, au lieu des t?moins, ce sont les entr?es qui sont utilis?es.)
Bon, c'est tr?s joli, mais lorsqu'il a d?termin? quels ?taient les fichiers ? passer, comment le lanceur choisit-il leurs futurs chemin dans /... ?
R?ponse : ? chaque fois qu'il peut conserver l'ancien chemin, il le fait; lorsqu'il ne le peut pas ou qu'il n'en est pas certain, il choisit un chemin se terminant par le m?me nom que le pr?c?dent et dont il est certain qu'il n'entrera pas en collision avec un autre.
(Je n'entrerai pas ici dans le d?tail des techniques employ?es pour garantir cette unitit? (bien que ce soit peut-?tre l'algorithme le plus int?ressant du syst?me d'exploitation, une diagonalisation de Cantor sur 7 bits par octets, voyez le code source si cela vous int?resse); mais mentionnons une ?vidence : il ne peut pas y avoir de /... dans la racine du paquetage originel (les noms de fichiers points-seuls sont r?serv?s dans ext2l), donc nous sommes s?rs que tout ce que lanceur a ? faire, c'est d'?viter toute collision entre les chemins qu'il cr?e.)
C'est pour cela que le r?pertoire personnel de l'utilisateur a ?t? d?lib?r?ment plac? dans /... : de la sorte, nous sommes certain que tous ses fichiers peuvent ?tre pass?s ? n'importe quel programme sans avoir ? r??crire leur chemin. L'utilisateur les voir d?j? dans /... , donc le lanceur n'a qu'? garder ces noms.
De fa?on plus d?taill?e, voici ce qui se produit lorsqu'un utilisateur tape "cat mon_fichier.txt" :
Mais qu'en est-il des fichiers situ?s hors de /... ? Et bien, cette commande nous en a fourni un bon exemple :
ecolbus@manux:~$ ls -l /bin/cat -rwxr-xr-t 4 sys sys 5264 13 juil. 15:05 /.../??/cat
Dans ce cas, J'ai demand? ? /bin/ls d'op?rer sur /bin/cat, qui est situ? dans ma racine, pas dans mon /... . Le lanceur de ls a rep?r? le probl?me, mais n'avait qu'une seule option : choisir un nouveau chemin de fichier, situ? dans /... , de sorte que /bin/ls puisse l'acc?der depuis son chroot. Son algorithme lui a donn? un nom compos? de deux caract?res illisibles (que ls a remplac?s par des '?'), et, apr?s l'appel ? xchroot(2), le lanceur a modifi? la ligne de commande de ls afin qu'il op?re sur le nouveau chemin, et non sur l'ancien.
Il se trouve que "ls" est l'une des rares commandes qui nous permette d'observer ce m?canisme. Cela signifie aussi que Manux se comporte de fa?on l?g?rement diff?rente des syst?mes d'exploitation traditionnels, et que des incompatibilit?s peuvent en r?sulter. C'est un fait ind?niable, mais ce n'est qu'une cons?quence de sa s?curit? - une autre partie du prix ? payer pour l'obtenir.
Ceci conclut notre revue d'ensemble de l'architecture de l'espace utilisateur Manux. On pourrait encore dire bien des choses ? son sujet, mais il s'agit de principalement de connaissances arcanes (comme la fa?on dont start_session fonctionne, ou la m?thode d'auto-installation du syst?me), qui sont ? la fois nettement moins utiles et simplement bas?es sur les principes expos?s ici. Parvenus ? ce point, si vous d?sirez approfondir vos connaissances ? son sujet, la meilleure m?thode est encore de l'essayer.