以只读方式挂载文件系统,并将写入重定向到 RAM?

use*_*686 23 linux filesystems ubuntu readonly

是否可以将环回文件挂载为只读,并将所有写入重定向到 RAM?

Mat*_*Mat 20

可以使用像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 
...
Run Code Online (Sandbox Code Playgroud)

安装它,填充它

# mkdir /tmp/imgmnt
# mount -o loop /tmp/image /tmp/imgmnt
# echo hello > /tmp/imgmnt/hello.txt
# umount /tmp/imgmnt
Run Code Online (Sandbox Code Playgroud)

以只读方式挂载

# mount -o loop,ro /tmp/image /tmp/imgmnt
# echo blah > /tmp/imgmnt/hello.txt 
-su: /tmp/imgmnt/hello.txt: Read-only file system
Run Code Online (Sandbox Code Playgroud)

一个小的 RAM 文件系统

# mkdir /tmp/rammnt
# mount -t tmpfs -o size=1M none /tmp/rammnt
Run Code Online (Sandbox Code Playgroud)

两者结合

# mkdir /tmp/combined
# mount -t aufs -o br:/tmp/rammnt:/tmp/imgmnt=ro none /tmp/combined
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

因此,tmpfs文件系统中的写入“停止” ,它们不会尝试传播回循环安装的映像文件。

您可以使用一个普通目录(在读/写文件系统上),或者可能使用一个/dev/shm适合您的目录,而不是tmpfs为此创建一个特定的目录。


某些发行版 LiveCD 使用此技术(或其变体)。维基百科aufs条目列出了一些。


use*_*686 9

更新:

在 Ubuntu 上似乎还有另外 2 种更简单的方法(至少是更高版本):

  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
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)
  5. 运行这些行:

    sudo aa-complain dhclient3
    sudo chmod 0755 /etc/initramfs-tools/scripts/init-bottom/__rootaufs
    sudo update-initramfs -k all -u
    sudo update-grub
    
    Run Code Online (Sandbox Code Playgroud)

如果一切顺利,当您重新启动时,您将进入一个临时文件系统。RAM 部分将在/rw,磁盘映像将在/ro,但当然它是只读的。

不过,如果您已经启动到一个临时系统但需要进行永久更改,您可以/ro通过说重新挂载文件系统

sudo mount -o remount,rw /ro
Run Code Online (Sandbox Code Playgroud)

使其可写,然后您可以对该目录进行任何需要的修改。