Смонтировать файловую систему только для чтения и перенаправить запись в ОЗУ?

Ответы:

18

Это возможно, используя объединенный слой файловой системы, такой как aufs .

Демо-версия:

Создать образ файловой системы

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

Смонтируйте его, заполните его

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

Смонтировать его только для чтения

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

Небольшая файловая система RAM

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

Объединить оба

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

Эта опция монтирования для создания новой «ветки» ( br) путем наложения /tmp/rammnt(чтение-запись) поверх /tmp/imgmnt(только для чтения). Эта «ветвь» сделана видимой как (чтение-запись) файловой системы на /tmp/combined.

(Подробности смотрите на странице руководства aufs (5) .)

Теперь все, что сделано, вот что у вас есть:

# 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

Таким образом, записи «останавливаются» в tmpfsфайловой системе, они не пытаются распространяться обратно в файл образа, смонтированный в цикле.

Вы могли бы использовать простой каталог (в файловой системе для чтения / записи) или, возможно, каталог в том /dev/shmслучае, если это работает для вас, вместо того, чтобы создавать специальный каталог tmpfsдля этого.


Этот прием (или его разновидности) используется некоторым дистрибутивом LiveCD. В википедии есть несколько записей .

Мат
источник
+1 спасибо! Вопрос: (1) можно ли это сделать fstab, чтобы точка монтирования была /? (то есть система загружается из сбрасываемого образа, в значительной степени.)
Mehrdad
Я так не думаю. Если вы хотите сделать это для /, я полагаю, вам лучше с initrd (это то, как это делается для livecds, я считаю). Вы можете сделать это из сценария инициализации, хотя это звучит сложно.
Мат
8

Обновить:

Кажется, есть 2 других более простых способа сделать это в Ubuntu (по крайней мере, в более поздних версиях):

  1. sudo apt-get install overlayrootа затем, установив overlayroot="tmpfs:swap=1,recurse=0"в/etc/overlayroot.local.conf .

  2. sudo apt-get install fsprotectс последующей передачей fsprotectв качестве параметра ядра


Я наконец понял, как это сделать с корневой файловой системой (в Ubuntu 11.04)!

Шаги по загрузке системы просты. Я использовал это руководство в сочетании с этим руководством и кучей поисковых запросов в Интернете, чтобы выяснить, как заставить его работать правильно, без ошибок.

Резюме:

  1. Бег:

    sudo apt-get install fsprotect apparmor-utils
    
  2. Сохраните это /etc/initramfs-tools/scripts/init-bottom/__rootaufs. Я не думаю, что имя на самом деле имеет значение, но начало __может быть использовано для упорядочивания, поэтому, если вы измените имя, вы можете захотеть сохранить подчеркивание. (Это копия этого файла .)

    #!/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. В /etc/default/grub, найдите строку, которая начинается с GRUB_CMDLINE_LINUX_DEFAULT, и в следующих кавычках добавьте параметр aufs=tmpfs.

    Бонус: если вам нужно временно отключить перенаправление, просто удалите этот аргумент из списка параметров ядра. Вероятно, вы можете сделать это, удерживая клавишу Shift во время загрузки системы, чтобы показать меню GRUB; затем нажмите e, чтобы изменить параметры, и просто удалите aufs=...параметр из списка.

  4. Добавьте эти строки в /etc/sysctl.conf. ( Предупреждение : потенциальная угроза безопасности.)

    kernel.yama.protected_nonaccess_hardlinks = 0
    kernel.yama.protected_sticky_symlinks = 0
    
  5. Запустите эти строки:

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

Если все прошло хорошо, при перезагрузке вы будете делать это во временную файловую систему. Часть ОЗУ будет в /rw, и образ диска будет в /ro, но, конечно, это будет только для чтения.

Тем не менее, если вы загрузились во временную систему, но хотите внести постоянные изменения, вы можете заново смонтировать /roфайловую систему, сказав

sudo mount -o remount,rw /ro

чтобы сделать его доступным для записи, а затем вы можете внести любые изменения, необходимые для этого каталога.

Mehrdad
источник
2

Да, от unionfs, см. Unionfs.filesystems.org . Вы монтируете первую файловую систему только для чтения и в качестве второй файловой системы ОЗУ для чтения и записи через unionfs.

В Ubuntu вы можете найти пакет unionfs-fuse, который является другой реализацией тех же вещей, но в пространстве пользователя, а не в качестве модуля ядра.

Ян Марек
источник
0

Вы также можете сделать это на уровне устройства, без unionfs, как aufs. Смотрите устройство-картограф snapshot-origin.

Тор Клингберг
источник