{"id":4245,"date":"2014-12-14T03:53:08","date_gmt":"2014-12-14T02:53:08","guid":{"rendered":"http:\/\/www.blaess.fr\/christophe\/?p=4245"},"modified":"2014-12-15T09:30:25","modified_gmt":"2014-12-15T08:30:25","slug":"le-systeme-overlayfs-de-linux-3-18","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2014\/12\/14\/le-systeme-overlayfs-de-linux-3-18\/","title":{"rendered":"Le syst\u00e8me Overlayfs de Linux 3.18"},"content":{"rendered":"<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/2014\/12\/14\/le-systeme-overlayfs-de-linux-3-18\/overlayfs-mini\/\" rel=\"attachment wp-att-4272\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-4272\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2014\/12\/overlayfs-mini.png\" alt=\"Overlayfs\" width=\"200\" height=\"102\" \/><\/a>Dans le noyau 3.18 un nouveau syst\u00e8me de fichiers est apparu&nbsp;: <strong>overlayfs<\/strong>. Je l&rsquo;avais d\u00e9j\u00e0 utilis\u00e9 \u00e0 maintes reprises sur des syst\u00e8mes embarqu\u00e9s, mais cela n\u00e9cessitait jusqu&rsquo;alors l&rsquo;ajout de patches suppl\u00e9mentaires. J&rsquo;ai eu envie de v\u00e9rifier si cette fonctionnalit\u00e9 \u00e0 pr\u00e9sent disponible dans le nouveau noyau <em>mainline<\/em> fonctionnait comme je la connaissais auparavant.<\/p>\n<p>\n<!--more-->\n<\/p>\n<h1>Syst\u00e8me Overlayfs<\/h1>\n<p style=\"text-align: justify;\">Le syst\u00e8me <em>overlayfs<\/em> n&rsquo;est pas \u00e0 proprement parler un v\u00e9ritable syst\u00e8me de fichiers, mais un m\u00e9canisme de montage permettant de superposer dans un r\u00e9pertoire le contenu de plusieurs autres r\u00e9pertoires. La configuration la plus simple est celle de deux r\u00e9pertoires, appelons-les <em>upper<\/em> et <em>lower<\/em> que l&rsquo;on peut imaginer comme des calques contenant des fichiers. Lorsque l&rsquo;on veut lire le contenu d&rsquo;un fichier, on regarde tout d&rsquo;abord sur le calque sup\u00e9rieur &#8211; <em>upper<\/em> &#8211; puis, si aucun fichier ne correspond au nom recherch\u00e9 on ira examiner ensuite le contenu du calque inf\u00e9rieur.<\/p>\n<p>\u00a0<a href=\"http:\/\/www.blaess.fr\/christophe\/2014\/12\/14\/\" rel=\"attachment wp-att-4264\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4264 size-medium\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2014\/12\/overlayfs-300x152.png\" alt=\"Overlayfs\" width=\"300\" height=\"152\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2014\/12\/overlayfs-300x152.png 300w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2014\/12\/overlayfs.png 527w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Ce qui est particuli\u00e8rement int\u00e9ressant dans un contexte embarqu\u00e9, est le fait que le r\u00e9pertoire <em>lower<\/em> est consid\u00e9r\u00e9 comme accessible en lecture seulement. Les modifications que l&rsquo;on apporte aux fichiers issus de la superposition des deux calques affecteront uniquement le calque sup\u00e9rieur, et jamais celui sous-jacent (qui peut lui m\u00eame \u00eatre un montage <em>overlay<\/em> d&rsquo;autres r\u00e9pertoires&#8230;)<\/p>\n<p style=\"text-align: justify;\">Cela implique une gestion interne assez compliqu\u00e9e&nbsp;:<\/p>\n<ul>\n<li style=\"text-align: justify;\">Lorsqu&rsquo;on veut modifier un fichier du r\u00e9pertoire <em>lower<\/em>, cela cr\u00e9e tout d&rsquo;abord une copie dans le r\u00e9pertoire <em>upper<\/em> qui sera effectivement modifi\u00e9e. Le fichier de <em>lower<\/em> ne sera jamais touch\u00e9.<\/li>\n<li style=\"text-align: justify;\">La suppression d&rsquo;un fichier existant uniquement dans le r\u00e9pertoire <em>upper<\/em> est assez simple. En revanche, effacer un fichier appartenant \u00e0 <em>lower<\/em> met en \u0153uvre une m\u00e9canique complexe, car il ne faut pas modifier r\u00e9ellement le r\u00e9pertoire <em>lower<\/em> (consid\u00e9r\u00e9 comme accessible en lecture seulement). Le syst\u00e8me <em>overlayfs<\/em> utilise un troisi\u00e8me r\u00e9pertoire de travail, dans lequel il m\u00e9morise l&rsquo;\u00e9tat des \u00e9l\u00e9ments de <em>lower<\/em> qu&rsquo;il doit faire dispara\u00eetre de l&#8217;empilement des calques<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Dans le cas d&rsquo;un syst\u00e8me embarqu\u00e9, la robustesse face aux erreurs li\u00e9es aux syst\u00e8mes de fichiers est une pr\u00e9occupation constante. Dans ce but, on pr\u00e9f\u00e8re g\u00e9n\u00e9ralement monter les partitions contenant les fichiers syst\u00e8me (<code>\/bin<\/code>, <code>\/lib<\/code>, <code>\/etc<\/code>, <code>\/usr<\/code>&#8230;) en lecture seule. Toutefois, il est parfois n\u00e9cessaire de modifier des \u00e9l\u00e9ments de configuration (par exemple le nom d&rsquo;h\u00f4te stock\u00e9 dans <code>\/etc\/hostname<\/code>). La possibilit\u00e9 de disposer d&rsquo;une partition ind\u00e9pendante que l&rsquo;on viendra placer en calque sup\u00e9rieur dans un r\u00e9pertoire dont le contenu reste inamovible est tr\u00e8s int\u00e9ressante.<\/p>\n<p style=\"text-align: justify;\">Pour tester le nouveau syst\u00e8me de fichiers, j&rsquo;ai choisi de construire un syst\u00e8me minimal avec Buildroot et le nouveau noyau Linux 3.18 pour une cible que je trouve plut\u00f4t sympathique&nbsp;: la carte OLinuXino iMX233 d&rsquo;Olimex (<a title=\"https:\/\/www.olimex.com\/Products\/OLinuXino\/iMX233\" href=\"https:\/\/www.olimex.com\/Products\/OLinuXino\/iMX233\" target=\"_blank\">https:\/\/www.olimex.com\/Products\/OLinuXino\/iMX233<\/a>) plus pr\u00e9cis\u00e9ment dans sa version \u00ab\u00a0micro\u00a0\u00bb.<\/p>\n<h1>\u00a0Noyau Linux 3.18 sur OLinuXino iMX233<\/h1>\n<p style=\"text-align: justify;\">Pour pr\u00e9parer mon image, j&rsquo;ai fait appel \u00e0 Buildroot en utilisant la derni\u00e8re version, celle de novembre 2014.<\/p>\n<pre>[~]$ <strong>wget <a title=\"http:\/\/buildroot.uclibc.org\/downloads\/buildroot-2014.11.tar.bz2\" href=\"http:\/\/buildroot.uclibc.org\/downloads\/buildroot-2014.11.tar.bz2\" target=\"_blank\">http:\/\/buildroot.uclibc.org\/downloads\/buildroot-2014.11.tar.bz2<\/a><\/strong>\n[~]$ <strong>tar xjf buildroot-2014.11.tar.bz2<\/strong>\n[~]$ <strong>cd buildroot-2014.11\/<\/strong>\n[buildroot-2014.11]$ <strong>ls configs\/<\/strong>\n   [...]\natstk100x_defconfig            nitrogen6x_defconfig                 qmx6_defconfig\nbeaglebone_defconfig           olimex_imx233_olinuxino_defconfig    raspberrypi_defconfig\ncalao_qil_a9260_defconfig      openblocks_a6_defconfig              s6lx9_microboard_defconfig\n   [...]<\/pre>\n<p style=\"text-align: justify;\">Nous voyons qu&rsquo;il existe bien une cible <code>olimex_imx233_olinuxino_defconfig<\/code> pr\u00e9d\u00e9finie pour Buildroot, v\u00e9rifions sa configuration&#8230;<\/p>\n<pre>[buildroot-2014.11]$ <strong>make olimex_imx233_olinuxino_defconfig<\/strong>\n  [...]\n[buildroot-2014.11]$ <strong>make menuconfig<\/strong>\n<\/pre>\n<p style=\"text-align: justify;\">Dans le menu de configuration \u00ab\u00a0<em>Kernel<\/em>\u00ab\u00a0, nous voyons que la version actuellement propos\u00e9e est le noyau 3.17. Il nous suffit de remplacer cette version par 3.18. Nous devons \u00e9galement activer le support du syst\u00e8me <em>overlayfs<\/em> dans la configuration du noyau\u00a0:<\/p>\n<pre>[buildroot-2014.11]$ <strong>make linux-menuconfig<\/strong>\n<\/pre>\n<p style=\"text-align: justify;\">Ceci s&rsquo;obtient dans le menu \u00ab\u00a0<em>File Systems<\/em>\u00a0\u00bb en activant l&rsquo;option \u00ab\u00a0<em>Overlay filesystem support<\/em>\u00ab\u00a0. Puis nous lan\u00e7ons la compilation avec un simple<\/p>\n<pre>[buildroot-2014.11]$ <strong>make<\/strong><\/pre>\n<p style=\"text-align: justify;\">Au bout de quelques minutes, nous obtenons&nbsp;:<\/p>\n<pre>[buildroot-2014.11]$ <strong>ls output\/images\/<\/strong>\nimx23_olinuxino_dev_linux.sb  imx23-olinuxino.dtb  rootfs.ext2  zImage<\/pre>\n<p style=\"text-align: justify;\">Nous devons pr\u00e9parer une carte micro-SD pour notre syst\u00e8me cible. Il faut n\u00e9cessairement cr\u00e9er au moins deux partitions, pour accueillir le syst\u00e8me de boot et l&rsquo;arborescence des fichiers. J&rsquo;ai choisi de rajouter une troisi\u00e8me partition pour le calque sup\u00e9rieur.<\/p>\n<ul>\n<li style=\"text-align: justify;\">Partition 1&nbsp;: 16 Mo. On notera &#8211; c&rsquo;est une particularit\u00e9 de l&rsquo;OLinuXino iMX233 &#8211; qu&rsquo;il faut obligatoirement que cette partition de d\u00e9marrage soit dot\u00e9e du type <strong>53<\/strong> (hexad\u00e9cimal).<\/li>\n<li style=\"text-align: justify;\">Partition 2&nbsp;: 32 Mo ext4 pour le syst\u00e8me en lecture-seule.<\/li>\n<li style=\"text-align: justify;\">Partition 3&nbsp;: 32 Mo ext4 pour les modifications apport\u00e9es \u00e0 la configuration syst\u00e8me.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">J&rsquo;ins\u00e8re une carte SD vierge sur mon PC de d\u00e9veloppement, elle appara\u00eet sous le nom <code>\/dev\/sdb\/<\/code> (\u00e0 v\u00e9rifier sur votre syst\u00e8me&nbsp;!)<\/p>\n<pre>[buildroot-2014.11]$ <strong>sudo umount \/dev\/sdb?<\/strong>\n[buildroot-2014.11]$ <strong>sudo fdisk \/dev\/sdb<\/strong>\n\nCommande (m pour l'aide)\u00a0: <strong>p<\/strong>\nDisque \/dev\/sdb\u00a0: 3924\u00a0Mo, 3924819968\u00a0octets\n28 t\u00eates, 40 secteurs\/piste, 6844 cylindres, total 7665664 secteurs\nUnit\u00e9s = secteurs de 1 * 512 = 512 octets\nTaille de secteur (logique \/ physique)\u00a0: 512\u00a0octets \/ 512\u00a0octets\ntaille d'E\/S (minimale \/ optimale)\u00a0: 512\u00a0octets \/ 512\u00a0octets\nIdentifiant de disque\u00a0: 0x361d7260\n\nP\u00e9riph\u00e9rique Amor\u00e7age  D\u00e9but         Fin      Blocs    Id. Syst\u00e8me\n\/dev\/sdb1            2048     7665663     3831808    c  W95 FAT32 (LBA)\n\nCommande (m pour l'aide)\u00a0: <strong>d<\/strong>\nPartition s\u00e9lectionn\u00e9e 1\n\nCommande (m pour l'aide)\u00a0: <strong>n<\/strong>\nPartition type:\n   p   primary (0 primary, 0 extended, 4 free)\n   e   extended\nSelect (default p): <strong>p<\/strong>\nNum\u00e9ro de partition (1-4, 1 par d\u00e9faut)\u00a0: <strong>1<\/strong>\nPremier secteur (2048-7665663, 2048 par d\u00e9faut)\u00a0: <strong>(<em>entr\u00e9e<\/em>)<\/strong>\nUtilisation de la valeur 2048 par d\u00e9faut\nDernier secteur, +secteurs ou +taille{K,M,G} (2048-7665663, 7665663 par d\u00e9faut)\u00a0: <strong>+16M<\/strong>\nCommande (m pour l'aide)\u00a0: <strong>t<\/strong>\nPartition s\u00e9lectionn\u00e9e 1\nCode Hexa (taper L pour lister les codes): <strong>53<\/strong>\nType syst\u00e8me de partition modifi\u00e9 de 1 \u00e0 53 (OnTrack DM6 Aux3)\nCommande (m pour l'aide)\u00a0: <strong>n<\/strong>\nPartition type:\n   p   primary (1 primary, 0 extended, 3 free)\n   e   extended\nSelect (default p): <strong>p<\/strong>\nNum\u00e9ro de partition (1-4, 2 par d\u00e9faut)\u00a0: <strong>2<\/strong>\nPremier secteur (34816-7665663, 34816 par d\u00e9faut)\u00a0: <strong>(<em>Entr\u00e9e<\/em>)<\/strong>\nUtilisation de la valeur 34816 par d\u00e9faut\nDernier secteur, +secteurs ou +taille{K,M,G} (34816-7665663, 7665663 par d\u00e9faut)\u00a0: <strong>+32M<\/strong>\n\nCommande (m pour l'aide)\u00a0: <strong>n<\/strong>\nPartition type:\n   p   primary (2 primary, 0 extended, 2 free)\n   e   extended\nSelect (default p): <strong>p<\/strong>\nNum\u00e9ro de partition (1-4, 3 par d\u00e9faut)\u00a0: <strong>3<\/strong>\nPremier secteur (100352-7665663, 100352 par d\u00e9faut)\u00a0: <strong>(<em>Entr\u00e9e<\/em>)<\/strong>\nUtilisation de la valeur 100352 par d\u00e9faut\nDernier secteur, +secteurs ou +taille{K,M,G} (100352-7665663, 7665663 par d\u00e9faut)\u00a0: <strong>+32M<\/strong>\nCommande (m pour l'aide)\u00a0: <strong>p<\/strong>\n\nDisque \/dev\/sdb\u00a0: 3924\u00a0Mo, 3924819968\u00a0octets\n28 t\u00eates, 40 secteurs\/piste, 6844 cylindres, total 7665664 secteurs\nUnit\u00e9s = secteurs de 1 * 512 = 512 octets\nTaille de secteur (logique \/ physique)\u00a0: 512\u00a0octets \/ 512\u00a0octets\ntaille d'E\/S (minimale \/ optimale)\u00a0: 512\u00a0octets \/ 512\u00a0octets\nIdentifiant de disque\u00a0: 0x361d7260\n\nP\u00e9riph\u00e9rique Amor\u00e7age  D\u00e9but         Fin      Blocs    Id. Syst\u00e8me\n\/dev\/sdb1            2048       34815       16384   53  OnTrack DM6 Aux3\n\/dev\/sdb2           34816      100351       32768   83  Linux\n\/dev\/sdb3          100352      165887       32768   83  Linux\n\nCommande (m pour l'aide)\u00a0: <strong>w<\/strong>\nLa table de partitions a \u00e9t\u00e9 alt\u00e9r\u00e9e.\n\nAppel d'ioctl() pour relire la table de partitions.\nSynchronisation des disques.\n[buildroot-2014.11]$<\/pre>\n<p style=\"text-align: justify;\">Copions les deux images produites par Buildroot sur leurs partitions respectives, et formatons la troisi\u00e8me partition.<\/p>\n<pre>[buildroot-2014.11]$ <strong>sudo  dd  if=output\/images\/imx23_olinuxino_dev_linux.sb  of=\/dev\/sdb1  bs=512  seek=4<\/strong>\n  [...]\n[buildroot-2014.11]$ <strong>sudo  dd  if=output\/images\/rootfs.ext2  of=\/dev\/sdb2  bs=1M<\/strong>\n  [...]\n[buildroot-2014.11]$ <strong>sudo  mkfs.ext4  \/dev\/sdb3 <\/strong>\nmke2fs 1.42.9 (4-Feb-2014)\n\u00c9tiquette de syst\u00e8me de fichiers=\nType de syst\u00e8me d'exploitation\u00a0: Linux\nTaille de bloc=1024 (log=0)\n[...]<\/pre>\n<p style=\"text-align: justify;\">On peut alors d\u00e9marrer le syst\u00e8me OLinuXino iMX233 en observant les traces sur la console s\u00e9rie.<\/p>\n<pre>PowerPrep start initialize power...\nBattery Voltage = 0.92V\nNo battery or bad battery detected!!!.Disabling battery\nEMI_CTRL 0x1C084040\nFRAC 0x92926192\ninit_ddr_mt46v32m16_133Mhz\npower 0x00820710\nFrac 0x92926192\nstart change cpu freq\nhbus 0x00000003\ncpu 0x00010001\nLLLLLLLFCLJ[    0.000000] Booting Linux on physical CPU 0x0\n[    0.000000] Linux version 3.18.0 (cpb@TR-B-01) (gcc version 4.8.3 (Buildroot 2014.11) ) #1 Sat Dec 13 16:37:23 CET 2014\n[    0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f\n[    0.000000] CPU: VIVT data cache, VIVT instruction cache\n[    0.000000] Machine model: i.MX23 Olinuxino Low Cost Board\n[    0.000000] Memory policy: Data cache writeback\n[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256\n[    0.000000] Kernel command line: console=ttyAMA0,115200 root=\/dev\/mmcblk0p2 rw rootwait\n[    0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)\n[...]\n[    1.730000] EXT4-fs (mmcblk0p2): re-mounted. Opts: errors=remount-ro\nStarting logging: OK\nStarting mdev...\nInitializing random number generator... [    2.510000] random: dd urandom read with 5 bits of entropy available\ndone.\nStarting network...\n\nWelcome to Buildroot\nbuildroot login: <strong>root<\/strong><\/pre>\n<h1>Mise en place de l&rsquo;<em>overlay<\/em><\/h1>\n<p style=\"text-align: justify;\">Je commence par cr\u00e9er un point de montage sp\u00e9cifique pour le calque sup\u00e9rieur de mon montage <em>overlay<\/em>.<\/p>\n<pre># <strong>mkdir \/data<\/strong><\/pre>\n<p style=\"text-align: justify;\">Je pr\u00e9f\u00e8re remonter tout de suite ma partition syst\u00e8me en lecture-seule.<\/p>\n<pre># <strong>mount \/ -o ro,remount<\/strong>\n[  129.290000] EXT4-fs (mmcblk0p2): re-mounted. Opts: errors=remount-ro<\/pre>\n<p style=\"text-align: justify;\">V\u00e9rifions que le contenu du r\u00e9pertoire <code>\/etc<\/code> est accessible en lecture seulement.<\/p>\n<pre># <strong>cat \/etc\/hostname<\/strong>\nbuildroot\n# <strong>echo HELLO &gt; \/etc\/hostname<\/strong>\n-sh: can't create \/etc\/hostname: Read-only file system<\/pre>\n<p style=\"text-align: justify;\">Je vais monter la partition num\u00e9ro 3 sur <code>\/data<\/code> et y cr\u00e9er les r\u00e9pertoires indispensables. Sur l&rsquo;OLinuXino, la carte SD est vue comme un p\u00e9riph\u00e9rique bloc <code>\/dev\/mmcblk0<\/code> contrairement au PC qui la voyait en <code>\/dev\/sdb<\/code> (par l&rsquo;interm\u00e9diaire d&rsquo;un lecteur USB).<\/p>\n<pre># <strong>mount \/dev\/mmcblk0p3 \/data\/ -t ext4<\/strong>\n[  182.390000] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)\n# <strong>mkdir \/data\/etc<\/strong>\n# <strong>mkdir \/data\/work<\/strong><\/pre>\n<p style=\"text-align: justify;\">Enfin nous pouvons r\u00e9aliser le montage <em>overlay<\/em> de <code>\/data\/etc<\/code> en superposition sur <code>\/etc<\/code>, tout en utilisant <code>\/data\/work<\/code> comme r\u00e9pertoire de travail interne.<\/p>\n<pre># <strong>mount none -t overlayfs -o lowerdir=\/etc,upperdir=\/data\/etc,workdir=\/data\/work \/etc<\/strong><\/pre>\n<p style=\"text-align: justify;\">Essayons de consulter puis modifier un fichier <code>\/etc\/<\/code>.<\/p>\n<pre># <strong>cat \/etc\/hostname<\/strong>\nbuildroot\n# <strong>echo OLinuXino &gt; \/etc\/hostname<\/strong>\n# <strong>cat \/etc\/hostname<\/strong>\nOLinuXino<\/pre>\n<p style=\"text-align: justify;\">La modification semble normale. Essayons d&rsquo;y ajouter un nouveau fichier.<\/p>\n<pre># <strong>ls \/etc\/<\/strong>\nfstab         init.d        ld.so.conf    network       protocols     services\ngroup         inittab       ld.so.conf.d  os-release    random-seed   shadow\nhostname      inputrc       mdev.conf     passwd        resolv.conf\nhosts         issue         mtab          profile       securetty\n# <strong>echo HELLO &gt; \/etc\/new-file<\/strong>\n# <strong>ls \/etc\/<\/strong>\nfstab         init.d        ld.so.conf    network       profile       securetty\ngroup         inittab       ld.so.conf.d  <strong>new-file<\/strong>      protocols     services\nhostname      inputrc       mdev.conf     os-release    random-seed   shadow\nhosts         issue         mtab          passwd        resolv.conf<\/pre>\n<p style=\"text-align: justify;\">Le fichier est bien visible. Mais qu&rsquo;en est-il du r\u00e9pertoire <code>\/etc<\/code> sous-jacent&nbsp;? Pour le savoir, d\u00e9montons l&rsquo;architecture <em>overlay<\/em> et v\u00e9rifions.<\/p>\n<pre># <strong>umount \/etc<\/strong>\n# <strong>ls \/etc\/<\/strong>\nfstab         init.d        ld.so.conf    network       protocols     services\ngroup         inittab       ld.so.conf.d  os-release    random-seed   shadow\nhostname      inputrc       mdev.conf     passwd        resolv.conf\nhosts         issue         mtab          profile       securetty\n# <strong>cat \/etc\/hostname<\/strong>\nbuildroot<\/pre>\n<p style=\"text-align: justify;\">Le r\u00e9pertoire inf\u00e9rieur est donc intact. O\u00f9 sont stock\u00e9es les modifications que nous avons r\u00e9alis\u00e9es&nbsp;? Naturellement, dans <code>\/data\/etc<\/code>.<\/p>\n<pre># <strong>ls \/data\/etc\/<\/strong>\nhostname  new-file\n# <strong>cat \/data\/etc\/hostname<\/strong>\nOLinuXino\n# <strong>cat \/data\/etc\/new-file<\/strong>\nHELLO<\/pre>\n<h1>Montage overlay d\u00e8s le boot<\/h1>\n<p style=\"text-align: justify;\">Je souhaite que la partition racine soit mont\u00e9e en lecture seule, et que le r\u00e9pertoire <code>\/etc<\/code> soit accessible en <em>overlay<\/em> d\u00e8s le boot. Pour cela je dois modifier deux fichiers syst\u00e8me qui se trouvent dans <code>\/etc<\/code>. Le premier est <code>inittab<\/code>.<\/p>\n<pre><strong>\/etc\/inittab:<\/strong>\n[...]\n# Startup the system\nnull::sysinit:\/bin\/mount -t proc proc \/proc\n<strong>#<\/strong>null::sysinit:\/bin\/mount -o remount,rw \/\nnull::sysinit:\/bin\/mkdir -p \/dev\/pts\nnull::sysinit:\/bin\/mkdir -p \/dev\/shm\nnull::sysinit:\/bin\/mount -a                                                   \n<strong>null::sysinit:\/bin\/mount none -t overlay -o lowerdir=\/etc,upperdir=\/data\/etc,workdir=\/data\/work \/etc<\/strong>\nnull::sysinit:\/bin\/hostname -F \/etc\/hostname\n[...]<\/pre>\n<p style=\"text-align: justify;\">J&rsquo;ai ajout\u00e9 un <code>#<\/code> pour mettre en commentaire la ligne qui remonte <code>\/<\/code> en lecture-\u00e9criture, et une ligne de montage <em>overlay<\/em> avant celle qui invoque <code>hostname<\/code>. En outre je modifie la table des syst\u00e8mes de fichiers \u00e0 monter automatiquement.<\/p>\n<pre><strong>\/etc\/fstab:<\/strong>\n#                 \n\/dev\/root       \/              ext2     r<strong>o<\/strong>,noauto         0      1\nproc            \/proc          proc     defaults          0      0\ndevpts          \/dev\/pts       devpts   defaults,gid=5,mode=620   0      0\ntmpfs           \/dev\/shm       tmpfs    mode=0777         0      0\ntmpfs           \/tmp           tmpfs    mode=1777         0      0\nsysfs           \/sys           sysfs    defaults          0      0\n<strong>\/dev\/mmcblk0p3  \/data          ext4     defaults          0      0<\/strong><\/pre>\n<p style=\"text-align: justify;\">J&rsquo;ai remplac\u00e9 une option &lsquo;<code>rw<\/code>&lsquo; par &lsquo;<code>ro<\/code>&lsquo; dans le montage de <code>\/dev\/root<\/code> et une ligne pour monter la troisi\u00e8me partition sur <code>\/data<\/code>.<\/p>\n<p style=\"text-align: justify;\">Je reboote le syst\u00e8me&nbsp;:<\/p>\n<pre>[...]\n[    1.160000] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)\nStarting logging: OK\nStarting mdev...\nInitializing random number generator... [    1.940000] random: dd urandom read with 6 bits of entropy available\ndone.\nStarting network...\n\nWelcome to Buildroot\nOLinuXino login:<\/pre>\n<p style=\"text-align: justify;\">Visiblement, le nom d&rsquo;h\u00f4te (juste avant \u00ab\u00a0<code>login<\/code>\u00ab\u00a0)\u00a0 a \u00e9t\u00e9 fix\u00e9 en lisant bien le fichier <code>hostname<\/code> du calque sup\u00e9rieur. Toutefois, un souci persiste.<\/p>\n<pre>OLinuXino login: <strong>root<\/strong>\n# <strong>echo HELLO &gt; \/abcd<\/strong>\n# <strong>cat \/abcd<\/strong>\nHELLO\n# <strong>rm \/abcd<\/strong><\/pre>\n<p style=\"text-align: justify;\">Notre partition racine n&rsquo;est pas mont\u00e9e en lecture seulement, malgr\u00e9 notre configuration. Ceci est d\u00fb aux options que le noyau re\u00e7oit au d\u00e9marrage.<\/p>\n<pre># <strong>cat \/proc\/cmdline<\/strong>\nconsole=ttyAMA0,115200 root=\/dev\/mmcblk0p2 rw rootwait<\/pre>\n<p style=\"text-align: justify;\">L&rsquo;option \u00ab\u00a0rw\u00a0\u00bb lui indique de monter la racine en lecture-\u00e9criture. Nous devons modifier cette option.<\/p>\n<h1>Partition syst\u00e8me en lecture-seule<\/h1>\n<p style=\"text-align: justify;\">La premi\u00e8re chose \u00e0 faire lorsqu&rsquo;on d\u00e9sire conserver une partition syst\u00e8me en lecture seulement, est de s&rsquo;assurer que le noyau ne la montera pas automatiquement en lecture-\u00e9criture. Pour cela, retournons dans la configuration du kernel.<\/p>\n<pre>[buildroot-2014.11]$ <strong>make linux-menuconfig<\/strong><\/pre>\n<p style=\"text-align: justify;\">Dans le menu \u00ab\u00a0<code>Boot Options<\/code>\u00ab\u00a0, je modifie l&rsquo;option \u00ab\u00a0<code>Default kernel command string<\/code>\u00a0\u00bb pour<\/p>\n<pre>(console=ttyAMA0,115200 root=\/dev\/mmcblk0p2 <strong>ro<\/strong> rootwait) Default kernel command string<\/pre>\n<p style=\"text-align: justify;\">(on notera le <code>ro<\/code> \u00e0 la place de <code>rw<\/code>). En outre, par pr\u00e9caution, je modifie l&rsquo;option \u00ab\u00a0<code>Kernel command line type<\/code>\u00a0\u00bb en<\/p>\n<pre> (X) Always use the default kernel command string<\/pre>\n<p style=\"text-align: justify;\">Apr\u00e8s avoir quitt\u00e9 ce menu de configuration, je m&rsquo;assure que Buildroot va recr\u00e9er l&rsquo;image de la partition de boot, et je relance la compilation.<\/p>\n<pre>[buildroot-2014.11]$ <strong>rm output\/build\/mxs-bootlets-10.12.01\/.stamp_built<\/strong>\n[buildroot-2014.11]$ <strong>make<\/strong><\/pre>\n<p style=\"text-align: justify;\">Apr\u00e8s installation de la nouvelle version, le boot est conforme \u00e0 nos attentes.<\/p>\n<pre>[    0.970000] VFS: Mounted root (ext2 filesystem) <strong>readonly<\/strong> on device 179:2.\n[    0.990000] devtmpfs: mounted\n[    0.990000] Freeing unused kernel memory: 148K (c0527000 - c054c000)\n[    1.160000] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)\nStarting logging: OK\nStarting mdev...\nInitializing random number generator... [    1.940000] random: dd urandom read with 6 bits of entropy available\ndone.\nStarting network...\n\nWelcome to Buildroot\nOLinuXino login: <strong>root<\/strong>\n# <strong>echo HELLO &gt; abcd<\/strong>\n-sh: can't create abcd: Read-only file system\n#<\/pre>\n<h1>Conclusion<\/h1>\n<p style=\"text-align: justify;\">Nous disposons ainsi facilement d&rsquo;un syst\u00e8me dont la configuration \u00ab\u00a0usine\u00a0\u00bb reste inamovible dans le r\u00e9pertoire <code>\/etc<\/code> inf\u00e9rieur tandis que les modifications de l&rsquo;utilisateur restent sur le r\u00e9pertoire sup\u00e9rieur. Le retour aux param\u00e8tres \u00ab\u00a0<em>factory defaults<\/em>\u00a0\u00bb se fait tr\u00e8s facilement en effa\u00e7ant (reformatant \u00e9ventuellement) la partition 3.<\/p>\n<p style=\"text-align: justify;\">J&rsquo;ai utilis\u00e9 ici un montage automatique de cette derni\u00e8re via le fichier <code>\/etc\/fstab<\/code>. Sur un v\u00e9ritable syst\u00e8me embarqu\u00e9, je pr\u00e9f\u00e9rerais un montage par script qui v\u00e9rifie d&rsquo;abord l&rsquo;int\u00e9grit\u00e9 de la partition et la reformate si elle est d\u00e9fectueuse (ou bascule sur une version de secours).<\/p>","protected":false},"excerpt":{"rendered":"<p>Dans le noyau 3.18 un nouveau syst&egrave;me de fichiers est apparu&nbsp;: overlayfs. Je l&rsquo;avais d&eacute;j&agrave; utilis&eacute; &agrave; maintes reprises sur des syst&egrave;mes embarqu&eacute;s, mais cela n&eacute;cessitait jusqu&rsquo;alors l&rsquo;ajout de patches suppl&eacute;mentaires. J&rsquo;ai eu envie de v&eacute;rifier si cette fonctionnalit&eacute; &agrave; pr&eacute;sent disponible dans le nouveau noyau mainline fonctionnait comme je la connaissais auparavant.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,5,8],"tags":[],"class_list":["post-4245","post","type-post","status-publish","format-standard","hentry","category-actualite","category-embarque","category-linux-2"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/comments?post=4245"}],"version-history":[{"count":25,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4245\/revisions"}],"predecessor-version":[{"id":4273,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4245\/revisions\/4273"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=4245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=4245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=4245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}