unionfs sur répertoire racine

unionfs sur répertoire racine - Installation - Linux et OS Alternatifs

Marsh Posté le 08-11-2010 à 08:55:28    

Bonjour,
 
je souhaite passer tout mon système de fichier en lecture seule, et d'effectuer les écritures sur un tmpfs.
 
La manip serait donc de faire un unionfs entre "/" et mon tmpfs, mais cela ne fonctionne pas. J'y arrive bien pour n'importe quel autre répertoire de la racine, mais pas la racine elle même.  
 
Je suppose que cela vient du fait que mon tmpfs est monté dans un sous-répertoire de la racine ( forcément ...) , par conséquent, on aurait un phénomène récursif quand on accède à un fichier du tmpfs.
 
Pourtant, je pense que c'est possible à faire puisque les livecd fonctionnent comme ça.
 
J'ai bien peur qu'il faille passer par un root temporaire (genre un ramdisk ) qui va me monter ma compact flash dans un répertoire , le tmpfs dans un autre , qui va faire un unionfs de tout ça , et qui finit par un chroot.
 
Est ce la bonne méthode ? Sinon, comment faire , d'autant plus que je vais partir d'une distribution existante ( mandriva ou ubuntu , avec préférence pour mandriva ).
 
Merci bien  :jap:

Reply

Marsh Posté le 08-11-2010 à 08:55:28   

Reply

Marsh Posté le 08-11-2010 à 09:55:59    

Ma passerelle Debian fonctionne comme cela, elle tourne sur une CompactFlash :).
Au début j'étais aussi parti sur de l'UnionFS, mais n'étais arrivé à pas grand chose. J'ai tenté ma chance avec AuFS qui est en quelque sorte un fork d'UnionFS.
Le support d'AuFS n'étant pas intégré au noyau, il faut donc recompiler celui-ci (j'en ai profité pour l'alléger). Je m'étais inspiré en grand partie de ce tuto.


Message édité par Gavrinis le 08-11-2010 à 09:57:16
Reply

Marsh Posté le 08-11-2010 à 10:08:16    

Merci pour ce tuto :) j'aurais aimé utiliser debian, mais j'ai besoin absolument de version récente de noyau, xorg et driver intel (ce qui n'est pas le cas avec debian lenny 5.0 ), du coup c'est plus simple pour moi de prendre une distrib qui comprend déjà tout plutot que de mettre tout à jour :(  
 
Je sens par contre que la distrib va me poser d'autres problèmes pour la passer en unionfs (ou aufs ).
 
 
D'ailleurs , qu'est ce que aufs t'a permis de faire que tu ne pouvais pas faire avec unionfs ?

Reply

Marsh Posté le 08-11-2010 à 10:33:19    

Je n'ai rien fait de plus avec AuFS que UnionFS. N'ayant pas réussi à passer mon système en RO avec UnionFS, j'ai tenté AuFS qui fonctionné.

Reply

Marsh Posté le 08-11-2010 à 11:33:44    

J'ai commencé à analyser le script, et je tombe sur des difficultés.
 
En effet, une des premières choses effectuées est :
 


mount --move ${rootmnt} /ro  


 
Je suppose que ${rootmnt} est "/" .  
 
Je n'ai pas le droit d'exécuter cette commande une fois le système démarré, le message d'erreur est le suivant : "too many levels of symbolic links".
 
Le script est démarré dans le initramfs mais c'est une spécificité de ubuntu ( je ne sais pas sur debian) , mais sur les autres distributions, ce n'est pas comme ça. Or, je suppose que le script est mis dans initramfs car c'est une opération qu'il faut impérativement faire dès le démarrage de l'OS.
 
Je ne sais pas comment faire ça de façon générique ( c'est à dire, indépendamment de la distribution) .
 
 
J'analyse quand même la suite du script :  
 
Le montage du disque est donc déplacé dans /ro , et le tmpfs dans /rw
 
 
Ensuite un aufs est fait entre /ro et /rw , et le résultat est dans /aufs  (je suis déjà un peu perdu )
 
 
Ensuite, les répertoire /ro et /rw sont recréé dans /aufs , pourquoi ? et surtout pourquoi après le mount aufs précédent.
 
Encore moins compréhensible, /ro et /rw sont déplacé vers /aufs/ro et /aufs/rw .
 
 
Ensuite, un tas de choses sont faites (notamment au niveau des fstab )
 
et pour finir un mount --move /aufs  /  
 
Je ne comprends pas pourquoi il faut passer par une étape intermédiaire avec /aufs
 
Pourquoi ne pas avoir fait directement  
 


mount -t aufs  -o dirs=/rw:/ro=ro aufs /


 
plutot que  
 


mount -t aufs  -o dirs=/rw:/ro=ro aufs /aufs


 
 
 
Bref, que de questions

Reply

Marsh Posté le 15-11-2010 à 14:22:06    

Je suis en train d'analyser la construction d'un LiveCD ( par exemple le live one de mandriva ) en le décortiquant à fond, et ma foi, ça correspond à peu près à ce que je souhaite faire.  
 
Seulement, quelques points m'échappent.
 
Le contenu d'un live CD comprend un noyau de démarrage  ( qu'on trouve dans /boot) , un fichier ramdisk ( initrd.tgz ) , et un système de fichier compressé en squashfs.
 
Le chargeur de démarrage est un isolinux , et démarre le noyau avec en paramètre le fichier ramdisk. Celui-ci contient un script /linuxrc et le nécessaire pour faire un tas d'initialisation comme le montage / démontage de volume, et aussi un utilitaire appelé plymouth qui apparemment est un gestionnaire de splashscreen.
 
En gros et sans détailler, le script linuxrc charge un certain nombre de modules ( dont unionfs et squashfs , tous situés dans le ramdisk), puis créé un tmpfs en rw ,et monte squashfs en ro , et fait un unionfs des 2. C'est exactement ce que je souhaiterai faire.
 
Seulement, je ne comprends pas par quel mécanisme il file la suite du travail à l'OS se trouvant dans le répertoire squashfs , c'est à dire en utilisant le noyau contenu dans celui-ci et non plus le noyau de démarrage ( je pense que ce n'est pas possible), et d'autre part, exécuter tous les scripts de démarrage dans /etc/rcX.d. Il me semblait que ce dernier point était géré par le binaire /sbin/init qui est lancé par défaut par le noyau, sauf si celui-ci a autre chose en paramètre, et me semble-t-il ici qu'il s'agit du script /linuxrc du ramdisk. Bref, je ne comprends pas tout ( et vous devez ptet lire des énormités ) , si quelqu'un peut m'éclairer car là, je suis un peu perdu.
 
Autre point : puis-je utiliser isolinux comme chargeur de démarrage avec une compact flash plutot qu'un CDROM ou faut-il utiliser autre chose ? (grub etc ...).
 
Merci :)

Reply

Marsh Posté le 15-11-2010 à 15:00:37    

Je pense que mettre tout en unionfs risque d'être vraiment complexe. Mais bon... si certains veulent continuer sur cette idée, je conseillerais plutôt d'analyser comment est construit une distribution sur une clé usb car là on peut écrire par la suite. Par exemple, on peut utiliser un CD live d'ubuntu puis créer une clé bootable.
 
Sinon, il y a peut-être plus simple en mettant uniquement /usr en unionfs.  
Explication simple: https://wiki.archlinux.org/index.ph [...] ing_.2Fusr
et qui reprend le travail de quelqu'un sur le forum de gentoo: http://forums.gentoo.org/viewtopic-t-646289.html
 
Normalement les distributions compilent le noyau avec squashfs mais c'est à vérifier.

Reply

Marsh Posté le 15-11-2010 à 15:11:57    

Salut :)
 
Merci pour ta réponse.
 
Le but de mettre tout en unionfs est malheureusement une contrainte nécessaire. En effet, je dois créer une distribution capable de supporter des coupures intempestives à n'importe quel moment du démarrage. Or, l'expérience passée me montre que si le système de fichier n'est pas en lecture seule, il arrivera par moment que celui-ci se corrompt et fasse que le système ne démarre plus sans une opération de maintenance manuelle ( généralement un fsck ou autre ).
 
Je pourrais effectivement faire comme tu dis ( et la version précédente qu'on a faite s'en rapproche) , et mettre en unionfs tous les répertoires de la racine et non pas lui même , et de monter la racine en lecture seule, ce qui reviendrait quasiment au même, mais je ne trouve pas ça "propre" ( j'essaie de faire les choses bien, bien que je ne comprenne pas tout :p ).
 
De plus, pour des raisons d'évolutivité, ça me semble pas trop mal d'avoir à copier une version d'OS ( compressée en un seul fichier squashfs ) dans un répertoire, plutôt que de devoir redéployer toute l'arborescence. Mais je peux me tromper !

Reply

Marsh Posté le 15-11-2010 à 15:49:47    

OK je pense avoir compris ton but.

 

Bon je donne une autre piste à mettre sous le coude au cas où l'idée de l'unionfs serait trop compliquée. Il me semble que linux a besoin d'écrire uniquement dans /var/log/ et créé en ram /proc /dev et /sys. Et quand il démarre, un script dans /etc fait le remount de ro en rw. C'est, il me semble, /etc/rc.sysinit . Donc là on pourrait faire en sorte de rester en ro et mettre /var/log sur une autre partition.

 

Pour en revenir à l'unionfs, il y a un an ou 2, j'avais analysé des scripts qui construisent des CDs Live et notamment un script qui faisait des mini CDs de Debian et de Ubuntu. Là c'est plus simple à comprendre car il y a que le strict nécessaire. Je pense que tu devrais chercher ces scripts et ça devrait t'aider.

 


Message édité par ogaby le 15-11-2010 à 15:50:19
Reply

Marsh Posté le 16-11-2010 à 15:32:45    

Salut :)
 
Bon, je commence à y voir un peu plus clair en regardant avec détail le fichier script /linuxrc du ramdisk du liveCD, et également en lisant la page de manuel d'initrd.
 
Cependant, il y a quelques points que je ne comprends pas. Je commence par initrd  ( http://pwet.fr/man/linux/fichiers_speciaux/initrd ) :
 

Citation :


 
DÉMARRAGE DU SYSTÈME
 
Quand il démarre en utilisant initrd, le système procède comme suit:
 
1. Le chargeur place une copie du noyau en mémoire, ainsi que le contenu de /dev/initrd.
 
2. Au démarrage du noyau, celui-ci décompresse et recopie le contenu du périphérique /dev/initrd sur le disque virtuel /dev/ram0 puis libère la mémoire utilisée par /dev/initrd.
 
3. Le noyau monte en lecture-écriture le périphérique /dev/ram0 comme racine initiale du système de fichiers.
 
4. Si la racine désirée pour le système de fichiers est également celle que l'on vient de monter (par ex. /dev/ram0), le noyau passe directement à la dernière étape du démarrage.
 
5. Si un fichier exécutable /linuxrc est présent sur le système de fichiers racine initial, ce fichier est exécuté avec l'uid 0. (Le fichier /linuxrc doit avoir la permission d'exécution. Ce peut être n'importe quel exécutable, y compris un shell-script.)
 
6. Si /linuxrc n'est pas exécuté ou lorsqu'il se termine, la racine normale du système de fichiers est montée. (Si /linuxrc se termine en ayant monté d'autres systèmes de fichiers sur la racine initiale, alors le comportement du noyau est INDÉTERMINÉ. Voir le paragraphe NOTES pour le comportement effectif.)
 
7. Si la racine normale dispose d'un répertoire /initrd, le périphérique /dev/ram0 est déplacé depuis / vers /initrd. Sinon, si le répertoire /initrd n'existe pas, le périphérique /dev/ram0 est démonté. (Lors du déplacement de / vers /initrd, /dev/ram0 n'est pas démonté, aussi des processus peuvent continuer à s'exécuter depuis ce périphérique. Si le répertoire /initrd n'existe pas sur le système de fichiers normal, et si des processus continuent à s'exécuter depuis /dev/ram0 lorsque /linuxrc se termine, le comportement du noyau est INDÉTERMINÉ. Voir le paragraphe NOTES pour le comportement effectif.)
 
8. La séquence de démarrage habituelle (invocation de /sbin/init) est alors effectuée depuis le système de fichiers normal.  
 


 
Je ne comprends pas bien le point 6. Qu'entendent-ils par "si /linuxrc se termine en ayant monté d'autres systèmes de fichiers sur la racine initiale, alors ..."
 
Cela signifie : si on a fait des mounts supplémentaires ( genre dans /mnt/toto ou autre ), ou bien si on a remplacé la racine ( qui est à ce moment là /dev/ram0 qui est en fait le initrd.gz ) par autre chose  ( genre, dans ce cas là, le unionfs que je souhaite faire ) ?
 
 
J'ai globalement compris le reste du détail de la séquence de démarrage, et je pense que c'est exactement avec ce mécanisme que je vais pouvoir faire ce que je souhaite faire, d'ailleurs si je regarde en détail le /linuxrc du live CD de mandriva , cela confirmerait mon hypothèse.
 
 
Je passe à la suite.
 
Apparemment, le paragraphe suivant de la page man explique qu'on peut effectivement se servir d'initrd pour changer la racine du système de fichier. Serait-ce l'explication à mon interrogation précédente ? A savoir, on ne peut pas changer la racine ( voir 6. ) SAUF si on applique ce qui est expliqué dans ce paragraphe ?
 
je cite :
 

Citation :


Le système de fichiers utilisé comme racine par défaut est celui qui est compilé dans le noyau (ou configuré avec rdev), ou celui qui est spécifié par une option du chargeur. Pour accéder à un système de fichiers monté par NFS, il faut utiliser les options de démarrage nfs_root_name et nfs_root_addrs pour la configuration NFS. Pour plus d'information sur les racines de systèmes de fichiers montées par NFS, consultez le fichier nfsroot.txt, dans la documentation du noyau. Pour plus d'informations sur la configuration de la racine du système de fichiers, voyez également les documentations de LILO et LOADLIN.
 
On peut aussi faire effectuer la modification de la racine normale par l'exécutable /linuxrc. Pour ce faire, le système /proc doit être monté. Ensuite, /linuxrc modifie le périphérique racine en écrivant directement dans les fichiers /proc/sys/kernel/real-root-dev, /proc/sys/kernel/nfs-root-name, et /proc/sys/kernel/nfs-root-addrs. Pour un périphérique physique monté à la racine, le changement s'effectue en écrivant le numéro de périphérique du nouveau système de fichiers dans /proc/sys/kernel/real-root-dev. Pour un système monté par NFS, la modification se fait en écrivant la configuration NFS dans les fichiers /proc/sys/kernel/nfs-root-name et /proc/sys/kernel/nfs-root-addrs puis en inscrivant 0xff (c.-à-d. le numéro de pseudo-périphérique NFS) dans le fichier /proc/sys/kernel/real-root-dev. Par exemple, la ligne de commande suivant basculerait le périphérique racine normale sur /dev/hdb1:
 
        echo 0x365 >/proc/sys/kernel/real-root-dev
 
La ligne suivante modifierait le périphérique normal en un répertoire NFS /var/nfsroot sur un serveur local ayant l'adresse IP 193.8.232.7, ceci sur un système nommé idefix, se trouvant à l'adresse 193.8.232.7:
 
 echo /var/nfsroot >/proc/sys/kernel/nfs-root-name
 echo 193.8.232.2:193.8.232.7::255.255.255.0:idefix \
   >/proc/sys/kernel/nfs-root-addrs
 echo 255 >/proc/sys/kernel/real-root-dev
 


 
Dans cette explication, cela parle beaucoup de NFS, je ne suis pas dans ce cas. Je souhaite monter la racine sur un unionfs d'un squashfs en ro d'un coté, et un tmpfs en rw de l'autre ( comme un liveCD en fait). Et ce squashfs serait stocké sur une CF , dans laquelle il y aurait également le noyau et l'initrd ( quasiment comme un liveCD - bis ).
 
Si j'ai bien compris, c'est la ligne : echo 0x365 >/proc/sys/kernel/real-root-dev qui me permettrait d'avoir le droit de changer la racine avec linuxrc.  
 
Passons maintenant au détail du fichier /linuxrc de l'initrd du liveCD mandriva 2010.
 

Code :
  1. #!/bin/nash
  2. nash-mount -t proc /proc /proc
  3. nash-mount -t sysfs /sys /sys
  4. /bin/plymouthd
  5. plymouth --show-splash
  6. probe-modules ide_core
  7. probe-modules ide_cd_mod
  8. probe-modules scsi_mod
  9. probe-modules sr_mod
  10. probe-modules nls_iso8859_1
  11. probe-modules nls_iso8859_2
  12. probe-modules nls_iso8859_3
  13. probe-modules nls_iso8859_4
  14. probe-modules nls_iso8859_5
  15. probe-modules nls_iso8859_6
  16. probe-modules nls_iso8859_7
  17. probe-modules nls_iso8859_9
  18. probe-modules nls_iso8859_13
  19. probe-modules nls_iso8859_14
  20. probe-modules nls_iso8859_15
  21. probe-modules nls_utf8
  22. probe-modules isofs
  23. probe-modules fat
  24. probe-modules vfat
  25. probe-modules crc_t10dif
  26. probe-modules sd_mod
  27. probe-modules usbcore
  28. probe-modules usb_storage
  29. probe-modules uhci_hcd
  30. probe-modules ohci_hcd
  31. probe-modules ehci_hcd
  32. probe-modules loop max_loop=64
  33. probe-modules squashfs
  34. probe-modules unionfs
  35. probe-modules --cdrom
  36. sh -c 'if grep -q initrd_debug /proc/cmdline; then plymouth --quit; exec sh </dev/console >/dev/console 2>/dev/console; fi'
  37. for i in seq 1 5; do showlabels --removable | grep LABEL=One-2010S-KDE4; if [ $? -eq 0 ]; then break; fi; sleep 1; done
  38. showlabels --removable
  39. nash-mount -o ro -t iso9660 LABEL=One-2010S-KDE4 /live/media
  40. /bin/losetup /dev/loop0 /live/media/loopbacks/distrib-lzma.sqfs
  41. nash-mount -o ro -t squashfs /dev/loop0 /live/distrib
  42. mount -t tmpfs -o mode=755 /live/memory /live/memory
  43. sh -c 'mount -o dirs=/live/memory=rw:/live/distrib=ro -t unionfs unionfs /live/union'
  44. plymouth --newroot=/live/union
  45. echo 0x0100 > /proc/sys/kernel/real-root-dev
  46. umount /sys
  47. sh -c 'umount /proc/bus/usb 2>/dev/null'
  48. umount /proc
  49. pivot_root /live/union /live/union/initrd
  50. sh -c 'rmdir /initrd/live/union'
  51. sh -c 'cd /initrd/live; for i in `ls -1`; do [ -d $i ] || continue; mkdir -p /live/$i; mount -n --move $i /live/$i; rmdir $i; done'
  52. rmdir /initrd/live
  53. nash-mount -o mode=0755 -t tmpfs /dev /dev
  54. sh -c 'rm -rf /dev/loop'
  55. sh -c 'mv /initrd/dev/* /dev/'


 
nash-mount doit être un utilitaire équivalent à mount ( pourquoi ils utilisent celui-là, mystère ...) ,et plymouth à l'air d'être un gestionnaire de splashscreen.
 
 
Première chose effectuée ( je passe les inits diverses ) : montage du CDROM dans /live/media  (ligne 39)
 

Code :
  1. nash-mount -o ro -t iso9660 LABEL=One-2010S-KDE4 /live/media


 
ensuite montage du squashfs en 2 étapes ( car nash-mount ne doit pas savoir gérer les périphériques loop ) dans /live/distrib (ligne 40 et 41)
 

Code :
  1. /bin/losetup /dev/loop0 /live/media/loopbacks/distrib-lzma.sqfs
  2. nash-mount -o ro -t squashfs /dev/loop0 /live/distrib


 
ensuite montage du tmpfs dans /live/memory ( ligne 42 )
Bizarre, ici ils utilisent mount et non nash-mount
 

Code :
  1. mount -t tmpfs -o mode=755 /live/memory /live/memory


 
Ensuite , création du unionfs entre /live/memory et /live/distrib, resultat dans /live/union ( ligne 43 )
 

Code :
  1. sh -c 'mount -o dirs=/live/memory=rw:/live/distrib=ro -t unionfs unionfs /live/union'


 
Ensuite, commande qui je ne sais pas à quoi elle sert ( ligne 44 )

Code :
  1. plymouth --newroot=/live/union


 
Ensuite, la ligne dont je parlais précédemment à propos de l'initrd ( ligne 45 )

Code :
  1. echo 0x0100 > /proc/sys/kernel/real-root-dev


 
Que représente 0x0100 ? Pourquoi ce choix ? Comment choisir le numéro que je dois mettre dans mon cas ( décrit plus haut )
 
 
Ensuite proc et sys sont démonté ( certainement parce qu'ils seront remontés plus tard par un des scripts appelés par /sbin/init ) , ligne 46 à 48
 

Code :
  1. umount /sys
  2. sh -c 'umount /proc/bus/usb 2>/dev/null'
  3. umount /proc


Pourquoi démonter également /proc/bus/usb alors que je ne l'ai pas monté ?
 
Puis, une commande qui d'après la page man , permet de changer la racine. C'est exactement ce que je veux. Je suis juste étonné qu'on n'en parle pas dans la page man de initrd ( ligne 49 )
 

Code :
  1. pivot_root /live/union /live/union/initrd


 
D'après la page man de pivot_root , cette commande permet de changer la racine, la nouvelle étant le premier paramètre, et l'ancienne est bougée dans le 2eme paramètre.
 
Donc si je détaille bien cet appel :
 
avant l'appel : / est /dev/ram0 ( le contenu de mon initrd.gz )
 
après l'appel : / devient /live/union ( donc ( l'union de squashfs et tmpfs ) , et /dev/ram0  bouge dans le sous répertoire  /live/union/initrd ... ET comme /live/union devient / , alors le contenu de /dev/ram0 se trouve en réalité dans /initrd
 
/initrd contient donc la totalité de mon ramdisk + /initrd/live/union ( qui est maintenant vide ) + /initrd/live/memory ( qui est mon tmpfs ) + /initrd/live/distrib ( qui est mon squashfs ).
 
les lignes 50-51-52 nettoie ce répertoire /initrd/live en enlevant tous les répertoires, et en déplacant les montages directement dans /live
 
ensuite ligne 53-54-55

Code :
  1. nash-mount -o mode=0755 -t tmpfs /dev /dev
  2. sh -c 'rm -rf /dev/loop'
  3. sh -c 'mv /initrd/dev/* /dev/'


 
Je ne comprends pas le besoin de faire ces appels. Si je comprends bien, le but est de déplacer tous les fichiers de périphériques du ramdisk vers un tmpfs créé. Mais il y a également un répertoire /dev provenant du squashfs, qui se retrouve donc au même endroit. Que se passe-t-il ? Le montage ligne 53 écrase le /dev du squashfs ? Ou alors il y a fusion ?
 
 
 
Fin du script.
 
Si je reprends le détail de initrd, ensuite s'exécute normalement /sbin/init et la séquence de démarrage va partir du unionfs entre squashfs et tmpfs.
 
 
Sauf que si je reprends le point 6 qui me posait problème :
 
 - ne sommes-nous pas dans le cas : "Si /linuxrc se termine en ayant monté d'autres systèmes de fichiers sur la racine initiale, alors le comportement du noyau est INDÉTERMINÉ."
 
 - sinon , quelle opération a permis de dire que nous ne sommes pas dans un cas indeterminé ? ( ex  : le echo 0x0100 > /proc/sys/kernel/real-root-dev ) ?
 
 
En espérant que pour ceux qui m'ont lu jusque là, qu'ils auront encore le courage de me donner des réponses à mes nombreuses interrogations  :jap:  
 
( bien entendu, lorsque j'aurai réussi à faire fonctionner comme je le souhaite, je donnerai tout le détail, ça pourra servir de tutoriel à d'autres qui seront confrontés aux mêmes besoins).
 
 
 
 
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed