Zamontować system plików tylko do odczytu i przekierować zapis do pamięci RAM?

21

Czy można zamontować plik pętli zwrotnej tylko do odczytu i przekierować wszystkie zapisy do pamięci RAM?

Mehrdad
źródło

Odpowiedzi:

18

Jest to możliwe przy użyciu unijnej warstwy systemu plików, takiej jak aufs .

Próbny:

Utwórz obraz systemu plików

# 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 
...

Zamontuj, zapełnij

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

Zamontuj go tylko do odczytu

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

Mały system plików RAM

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

Połącz oba

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

Ta opcja montowania pozwala utworzyć nową „gałąź” ( br) przez umieszczenie na stosie /tmp/rammnt(tylko do odczytu i zapisu) na górze /tmp/imgmnt(tylko do odczytu). Ta „gałąź” jest widoczna jako system plików (do odczytu i zapisu) /tmp/combined.

(Zobacz wszystkie strony man aufs (5) ).

Teraz wszystko, co zostało zrobione, oto co masz:

# 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

Tak więc zapisuje „stop” w tmpfssystemie plików, nie próbują propagować z powrotem do pliku obrazu zamontowanego w pętli.

Mógłbyś użyć zwykłego katalogu (w systemie plików do odczytu / zapisu) lub ewentualnie katalogu poniżej, /dev/shmjeśli to działa dla ciebie, zamiast tworzenia specyficznego tmpfsdla tego.


Ta technika (lub jej odmiany) jest stosowana w niektórych dystrybucjach LiveCD. Wpis w Wikipedii aufs wymienia kilka.

Mata
źródło
+1 dzięki! Pytanie: (1) czy można to zrobić tak fstab, że punktem montowania jest /? (tzn. system uruchamia się po odrzuceniu obrazu).
Mehrdad
Nie wydaje mi się Jeśli chcesz to zrobić /, uważam, że lepiej jest zacząć od initrd (tak sądzę w przypadku filmów na żywo). Być może możesz to zrobić ze skryptu inicjującego, choć brzmi to skomplikowanie.
Mat.
8

Aktualizacja:

Wygląda na to, że istnieją 2 inne prostsze sposoby, aby to zrobić na Ubuntu (przynajmniej w późniejszych wersjach):

  1. sudo apt-get install overlayroota następnie przez ustawienie overlayroot="tmpfs:swap=1,recurse=0"w/etc/overlayroot.local.conf .

  2. sudo apt-get install fsprotectnastępnie przekazany fsprotectjako parametr jądra


W końcu wymyśliłem, jak to zrobić z głównym systemem plików (w Ubuntu 11.04)!

Kroki umożliwiające uruchomienie systemu są proste. Użyłem tego przewodnika w połączeniu z tym przewodnikiem i kilkoma wyszukiwaniami w sieci, aby dowiedzieć się, jak zapewnić jego prawidłowe działanie, bez błędów.

Podsumowanie:

  1. Biegać:

    sudo apt-get install fsprotect apparmor-utils
    
  2. Zapisz to do /etc/initramfs-tools/scripts/init-bottom/__rootaufs. Nie sądzę, że nazwa ma znaczenie, ale początek __można wykorzystać do celów zamawiania, więc jeśli zmienisz nazwę, możesz zachować podkreślenia. (To jest kopia tego pliku .)

    #!/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. W /etc/default/grubznajdź wiersz, który zaczyna się od GRUB_CMDLINE_LINUX_DEFAULT, a następnie w cudzysłowach dodaj parametr aufs=tmpfs.

    Premia: Jeśli chcesz tymczasowo wyłączyć przekierowanie, po prostu usuń ten argument z listy parametrów jądra. Prawdopodobnie możesz to zrobić, przytrzymując klawisz Shift podczas uruchamiania systemu, aby wyświetlić menu GRUB; następnie naciśnij e, aby edytować parametry i po prostu usuń aufs=...parametr z listy.

  4. Dołącz te linie do /etc/sysctl.conf. ( Ostrzeżenie : potencjalne zagrożenie bezpieczeństwa.)

    kernel.yama.protected_nonaccess_hardlinks = 0
    kernel.yama.protected_sticky_symlinks = 0
    
  5. Uruchom następujące linie:

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

Jeśli wszystko poszło dobrze, po ponownym uruchomieniu uruchomisz to w tymczasowym systemie plików. Część RAM będzie w /rw, a obraz dysku będzie w /ro, ale oczywiście będzie tylko do odczytu.

Niemniej jednak, jeśli uruchomiłeś system tymczasowy, ale chcesz wprowadzić trwałą zmianę, możesz ponownie zainstalować /rosystem plików, mówiąc:

sudo mount -o remount,rw /ro

aby był zapisywalny, a następnie możesz wprowadzić wszelkie modyfikacje potrzebne w tym katalogu.

Mehrdad
źródło
2

Tak, przez unionfs , patrz unionfs.filesystems.org . Zamontowałeś pierwszy system plików tylko do odczytu, a jako drugi system plików RAM do odczytu i zapisu przez unionfs.

W Ubuntu możesz znaleźć pakiet unionfs-fuse, który jest kolejną implementacją tych samych rzeczy, ale w przestrzeni użytkownika, a nie jako moduł jądra.

Jan Marek
źródło
0

Możesz to również zrobić na poziomie urządzenia, bez unii takich jak aufs. Zobacz mapowanie urządzeń snapshot-origin.

Tor Klingberg
źródło