Pasang sistem file read-only, dan redirect menulis ke RAM?

21

Apakah mungkin untuk memasang file loopback sebagai hanya-baca, dan mengarahkan semua tulis ke RAM?

Mehrdad
sumber

Jawaban:

18

Dimungkinkan menggunakan lapisan sistem berkas gabungan seperti aufs .

Demo:

Buat gambar sistem file

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

Pasang itu, isi itu

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

Pasang hanya-baca

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

Sistem file RAM kecil

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

Gabungkan keduanya

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

Opsi pemasangan itu untuk membuat "cabang" baru ( br) dengan menumpuk /tmp/rammnt(baca-tulis) di atas /tmp/imgmnt(hanya baca). "Cabang" ini dibuat terlihat sebagai sistem file (baca-tulis) aktif /tmp/combined.

(Lihat halaman manual aufs (5) untuk semua detailnya.)

Sekarang semua sudah selesai, inilah yang Anda miliki:

# 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

Jadi tulis "berhenti" di sistem tmpfsfile, mereka tidak berusaha untuk menyebar kembali ke file gambar loop-mount.

Anda bisa menggunakan direktori biasa (pada sistem file baca / tulis), atau mungkin direktori di bawah /dev/shmjika itu berfungsi untuk Anda, alih-alih membuat spesifik tmpfsuntuk itu.


Teknik ini (atau variasi daripadanya) digunakan oleh beberapa LiveCD distribusi. Entri Wikipedia aufs mencantumkan beberapa.

Tikar
sumber
+1 terima kasih! Sebuah pertanyaan: (1) apakah mungkin untuk melakukan ini dengan fstab, sehingga titik mountnya adalah /? (Yaitu, sistem melakukan booting dari gambar yang bisa dibuang, cukup banyak.)
Mehrdad
Saya kira tidak. Jika Anda ingin melakukan itu /, saya yakin Anda lebih baik dengan initrd (begitulah yang dilakukan untuk livecds saya percaya). Anda mungkin dapat melakukannya dari skrip init meskipun itu terdengar rumit.
Mat
8

Memperbarui:

Tampaknya ada 2 cara lain yang lebih sederhana untuk melakukan ini di Ubuntu (setidaknya versi yang lebih baru):

  1. sudo apt-get install overlayrootdiikuti dengan menetapkan overlayroot="tmpfs:swap=1,recurse=0"di/etc/overlayroot.local.conf .

  2. sudo apt-get install fsprotectdiikuti dengan meneruskan fsprotectsebagai parameter kernel


Saya akhirnya menemukan cara untuk melakukan ini dengan sistem file root (di Ubuntu 11.04)!

Langkah-langkah untuk membuat sistem dapat di-boot adalah sederhana. Saya menggunakan panduan ini dalam kombinasi dengan panduan ini dan banyak pencarian web untuk mengetahui cara membuatnya berfungsi dengan baik, tanpa bug.

Ringkasan:

  1. Menjalankan:

    sudo apt-get install fsprotect apparmor-utils
    
  2. Simpan ini untuk /etc/initramfs-tools/scripts/init-bottom/__rootaufs. Saya tidak berpikir nama sebenarnya penting, tetapi awalnya __mungkin digunakan untuk tujuan pemesanan, jadi jika Anda mengubah nama, Anda mungkin ingin mempertahankan garis bawah. (Ini adalah salinan file ini .)

    #!/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. Di /etc/default/grub, cari baris yang dimulai dengan GRUB_CMDLINE_LINUX_DEFAULT, dan di dalam tanda kutip yang mengikuti, tambahkan parameter aufs=tmpfs.

    Bonus: Jika Anda perlu sesekali mematikan pengalihan sementara, cukup hapus argumen ini dari daftar parameter kernel. Anda mungkin dapat melakukan ini dengan menahan tombol Shift ketika sistem boot, untuk menampilkan menu GRUB; lalu tekan e untuk mengedit parameter, dan hapus saja aufs=...parameter dari daftar.

  4. Tambahkan baris ini ke /etc/sysctl.conf. ( Peringatan : Risiko keamanan potensial.)

    kernel.yama.protected_nonaccess_hardlinks = 0
    kernel.yama.protected_sticky_symlinks = 0
    
  5. Jalankan baris ini:

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

Jika semuanya berjalan dengan baik, ketika Anda reboot, Anda akan melakukannya ke sistem file sementara. Bagian RAM akan berada pada /rw, dan disk image akan berada di /ro, tetapi tentu saja itu akan menjadi hanya-baca.

Namun demikian, jika Anda telah mem-boot ke sistem sementara tetapi perlu melakukan perubahan permanen, Anda dapat memasang kembali /rosistem file dengan mengatakan

sudo mount -o remount,rw /ro

untuk membuatnya dapat ditulis, dan kemudian Anda dapat membuat modifikasi apa pun yang diperlukan untuk direktori itu.

Mehrdad
sumber
2

Ya, oleh unionfs, lihat unionfs.filesystems.org . Anda telah me-mount filesystem read-only pertama, dan sebagai filesystem read-write RAM kedua melalui unionfs.

Di Ubuntu Anda dapat menemukan paket unionfs-fuse, yang merupakan implementasi lain dari hal-hal yang sama, tetapi dalam ruang pengguna, bukan sebagai modul kernel.

Jan Marek
sumber
0

Anda juga dapat melakukan ini pada tingkat perangkat, tanpa serikat seperti auf. Lihat device-mapper snapshot-origin.

Tor Klingberg
sumber