Monter un système de fichiers en lecture seule et rediriger les écritures vers la RAM?

21

Est-il possible de monter un fichier de bouclage en lecture seule et de rediriger toutes les écritures vers la RAM?

Mehrdad
la source

Réponses:

18

Il est possible d'utiliser une couche de système de fichiers union comme aufs .

Démo:

Créer une image de système de fichiers

# dd if=/dev/zero of=/tmp/image bs=1024 count=1024
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 0.0028428 s, 369 MB/s
# mke2fs /tmp/image 
...

Montez-le, remplissez-le

# mkdir /tmp/imgmnt
# mount -o loop /tmp/image /tmp/imgmnt
# echo hello > /tmp/imgmnt/hello.txt
# umount /tmp/imgmnt

Montez-le en lecture seule

# mount -o loop,ro /tmp/image /tmp/imgmnt
# echo blah > /tmp/imgmnt/hello.txt 
-su: /tmp/imgmnt/hello.txt: Read-only file system

Un petit système de fichiers RAM

# mkdir /tmp/rammnt
# mount -t tmpfs -o size=1M none /tmp/rammnt

Combinez les deux

# mkdir /tmp/combined
# mount -t aufs -o br:/tmp/rammnt:/tmp/imgmnt=ro none /tmp/combined

Cette option de montage pour créer une nouvelle "branche" ( br) en empilant /tmp/rammnt(lecture-écriture) au-dessus de /tmp/imgmnt(lecture seule). Cette "branche" est rendue visible en tant que système de fichiers (lecture-écriture) /tmp/combined.

(Voir la page de manuel aufs (5) pour tous les détails.)

Maintenant, tout ce qui est fait, voici ce que vous avez:

# ls /tmp/combined
hello.txt  lost+found
# cat /tmp/combined/hello.txt 
hello
# echo bye > /tmp/combined/hello.txt 
# cat /tmp/combined/hello.txt 
bye

# cat imgmnt/hello.txt 
hello
# cat rammnt/hello.txt 
bye

Ainsi, les écritures "arrêtent" dans le tmpfssystème de fichiers, elles ne tentent pas de se propager vers le fichier image monté en boucle.

Vous auriez pu utiliser un répertoire simple (sur un système de fichiers en lecture / écriture), ou éventuellement un répertoire sous /dev/shmsi cela fonctionne pour vous, au lieu de créer un spécifique tmpfspour cela.


Cette technique (ou des variantes de celle-ci) est utilisée par certaines distributions LiveCD. L' entrée Wikipedia aufs en répertorie quelques-uns.

Tapis
la source
+1 merci! Une question: (1) est-il possible de le faire avec fstab, tel que le point de montage soit /? (c'est-à-dire que le système démarre à partir d'une image jetable, à peu près.)
Mehrdad
Je ne pense pas. Si vous voulez le faire pour /, je crois que vous êtes mieux avec un initrd (c'est comme ça que je fais pour les livecds je crois). Vous pourrez peut-être le faire à partir d'un script d'initialisation, mais cela semble délicat.
Mat
8

Mise à jour:

Il semble qu'il existe 2 autres façons plus simples de le faire sur Ubuntu (au moins les versions ultérieures):

  1. sudo apt-get install overlayrootsuivi par la mise overlayroot="tmpfs:swap=1,recurse=0"en/etc/overlayroot.local.conf .

  2. sudo apt-get install fsprotectsuivi d'un passage fsprotecten paramètre du noyau


J'ai finalement compris comment faire cela avec le système de fichiers racine (dans Ubuntu 11.04)!

Les étapes pour rendre un système amorçable sont simples. J'ai utilisé ce guide en combinaison avec ce guide et un tas de recherches sur le Web pour comprendre comment le faire fonctionner correctement, sans bugs.

Sommaire:

  1. Courir:

    sudo apt-get install fsprotect apparmor-utils
    
  2. Enregistrez ceci dans /etc/initramfs-tools/scripts/init-bottom/__rootaufs. Je ne pense pas que le nom compte vraiment, mais le début __peut être utilisé à des fins de commande, donc si vous changez le nom, vous voudrez peut-être garder les soulignements. (Ceci est une copie de ce fichier .)

    #!/bin/sh -e
    
    case $1 in
      prereqs)
        exit 0
        ;;
    esac
    
    for x in $(cat /proc/cmdline); do
      case $x in
        root=*)
          ROOTNAME=${x#root=}
          ;;
        aufs=*)
          UNION=${x#aufs=}
        case $UNION in
          LABEL=*)
            UNION="/dev/disk/by-label/${UNION#LABEL=}"
            ;;
          UUID=*)
            UNION="/dev/disk/by-uuid/${UNION#UUID=}"
            ;;
        esac    
          ;;
      esac
    done
    
    if [ -z "$UNION" ]; then
        exit 0
    fi
    
    # make the mount points on the init root file system
    mkdir /aufs /ro /rw
    
    # mount read-write file system
    if [ "$UNION" = "tmpfs" ]; then
      mount -t tmpfs rw /rw -o noatime,mode=0755
    else
      mount $UNION /rw -o noatime
    fi
    
    # move real root out of the way
    mount --move ${rootmnt} /ro
    
    mount -t aufs aufs /aufs -o noatime,dirs=/rw:/ro=ro
    
    # test for mount points on union file system
    [ -d /aufs/ro ] || mkdir /aufs/ro
    [ -d /aufs/rw ] || mkdir /aufs/rw
    
    mount --move /ro /aufs/ro
    mount --move /rw /aufs/rw
    
    # strip fstab off of root partition
    grep -v $ROOTNAME /aufs/ro/etc/fstab > /aufs/etc/fstab
    
    mount --move /aufs /root
    
    exit 0
    
  3. Dans /etc/default/grub, recherchez la ligne commençant par GRUB_CMDLINE_LINUX_DEFAULT, et à l'intérieur des guillemets qui suivent, ajoutez le paramètre aufs=tmpfs.

    Bonus: Si vous devez parfois désactiver temporairement la redirection, supprimez simplement cet argument de la liste des paramètres du noyau. Vous pouvez probablement le faire en maintenant la touche Maj enfoncée lorsque le système démarre, pour afficher le menu GRUB; puis appuyez sur e pour modifier les paramètres, et effacez simplement le aufs=...paramètre de la liste.

  4. Ajoutez ces lignes à /etc/sysctl.conf. ( Avertissement : risque de sécurité potentiel.)

    kernel.yama.protected_nonaccess_hardlinks = 0
    kernel.yama.protected_sticky_symlinks = 0
    
  5. Exécutez ces lignes:

    sudo aa-complain dhclient3
    sudo chmod 0755 /etc/initramfs-tools/scripts/init-bottom/__rootaufs
    sudo update-initramfs -k all -u
    sudo update-grub
    

Si tout s'est bien passé, au redémarrage, vous le ferez dans un système de fichiers temporaire. La partie RAM sera à /rw, et l'image disque sera à /ro, mais bien sûr, elle sera en lecture seule.

Néanmoins, si vous avez démarré dans un système temporaire mais devez apporter une modification permanente, vous pouvez remonter le /rosystème de fichiers en disant

sudo mount -o remount,rw /ro

pour le rendre accessible en écriture, puis vous pouvez apporter les modifications nécessaires à ce répertoire.

Mehrdad
la source
2

Oui, par unionfs, voir unionfs.filesystems.org . Vous avez monté le premier système de fichiers en lecture seule et comme deuxième système de fichiers RAM en lecture-écriture via unionfs.

Dans Ubuntu, vous pouvez trouver le paquet unionfs-fuse, qui est une autre implémentation des mêmes choses, mais dans l'espace utilisateur, pas en tant que module du noyau.

Jan Marek
la source
0

Vous pouvez également le faire au niveau de l'appareil, sans unionfs comme aufs. Voir mappeur de périphériques snapshot-origin.

Tor Klingberg
la source