在某些情况下,最好有一个只读根文件系统。这可以防止在根文件系统上发生任何可能改变系统行为的更改,并允许简单的重新启动来将系统恢复到原始状态。此类应用程序的例子包括信息亭和嵌入式设备。在Ubuntu上使用overlayroot可以使创建一个只读根文件系统变得简单快捷。
动机
假设我们有一个需要运行特定程序的嵌入式Linux设备。程序不需要存储任何数据(可能除了一些日志),我们希望保护系统不受任何更改的影响。如果程序或任何系统进程对文件系统进行了修改,我们希望将它们丢弃并返回到原始状态。我们需要一个健壮的系统来运行我们的程序,但是通过一次电源循环可以恢复到它的“工厂”状态。
背景
Overlayroot是一个为Ubuntu开发的软件包,它利用覆盖,一个联合文件系统实施。OverlayFS提供了两个不同文件系统的统一视图;呈现的文件系统是将一个文件系统覆盖到另一个文件系统上的结果。
在overlays中,有一个“上”文件系统和“下”文件系统。如果在上面的文件系统和降低文件系统中上面的文件系统,并且降低文件系统被隐藏。如果对象是目录,则上面的和降低文件系统被合并并呈现。
使用overlayroot,下层的文件系统是根文件系统的只读装载,上层的文件系统是另一个块设备的读写挂载。那个阻挡装置可以是tmpfs临时文件系统,一个标准的块设备,或者一个加密的块设备(dmcrypt).
在根文件系统顶部所做的所有更改都存储在其他地方,不会影响根文件系统。根据所选的块设备,这些更改可以在重新启动时持续存在。虽然根文件系统不会受到影响,OverlayFS提供的视图将包括存储在上面的文件系统。
机器的情况
对于我们的嵌入式Linux设备,我们不想保留对根文件系统的任何更改。我们要保存的任何数据都将存储在一个专门用于数据存储的单独文件系统中。
以下是我们的文件系统结构:
- /dev/sda1
on
/ - /dev/sda2
on
/data
我们要使用overlayroot挂载/,这样我们就有了一个读写文件系统,但是不会对/有任何的写入,我们要正常挂载/data,通常这样我们的程序可以写出并保存日志文件。
解决方案
Overlayroot从ubuntu12.10开始就可以使用了,并且已经向后移植到了12.04 LTS。快速安装:
apt-get install overlayroot
配置文件存储在:
/etc/overlayroot.conf
并包含大量的联机文档。
唯一要更改的项是覆盖
overlayroot
变量。默认为空:
overlayroot=""
从简单开始
既然我们想用tmpfs对于overlayroot,我们相应地设置变量。
overlayroot="tmpfs"
其他模式(指定设备,或crypt)记录在:
overlayroot.conf
上面有一些漂亮的图表后介绍overlayroot.
添加swap分区
默认情况下,overlayroot将禁用交换。这可以通过为配置提供另一个选项来重新启用:
overlayroot="tmpfs:swap=1"
(swap默认值是0).
不要重复
默认情况下,overlayroot将在/在指定模式下。可以通过向配置中添加另一个选项来防止这种情况:
overlayroot="tmpfs:swap=1,recurse=0"
请注意交换=1和递归=0用逗号隔开,而不是冒号。
(默认值递归是1)。
这将防止overlayroot覆盖读写操作临时文件系统在只读文件上/数据文件系统。全部/将不会受到任何修改,除了/数据,这就是我们想要的。
结果
在对overlayroot.conf做修改并且重启后,根文件系统现在应该以读写方式装载tmpfs文件系统,下层是只读的/文件系统。
使用命令:
mount
我们应该看到如下内容:
overlayroot on / type overlayfs (rw,lowerdir=/media/root-ro/,upperdir=/media/root-rw)
proc on /proc type proc (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev)
none on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/fuse/connections type fusectl (rw)
devtmpfs on /dev type devtmpfs (rw,mode=0755)
none on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
none on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/sda1 on /media/root-ro type ext4 (ro)
tmpfs-root on /media/root-rw type tmpfs (rw,relatime)
/dev/sda2 on /data type ext4 (rw)
注意根文件系统的类型覆盖使用与读写相对应的指定的上下文件系统临时文件系统以及列出的只读装载。
禁用Overlayroot
一旦启用overlayroot,就不能再对根文件系统进行更改。如果我们合法地需要进行更改(例如更新、调整等),这会带来问题。幸运的是,我们可以通过
overlayroot=disabled
引导内核。这可以根据需要一次性完成,也可以在GRUB等引导加载程序中设置为备用引导配置。
例如,在GRUB2中,可以使用类似以下内容:
menuentry 'Ubuntu, with Linux 3.5.0-54-generic (Writable)' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
gfxmode $linux_gfx_mode
insmod gzio
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set=root 28adfe9d-c122-479a-ab81-de57d16516dc
linux /vmlinuz-3.5.0-54-generic root=/dev/mapper/faramir-root ro overlayroot=disabled
initrd /initrd.img-3.5.0-54-generic
}
结论
Overlayroot使得在Ubuntu上以只读方式安装根文件系统的过程非常简单。在overlayroot出现之前,要使用自定义脚本添加到initramfs之中。这些脚本通常很脆弱,而且在Ubuntu的不同版本之间并不总是兼容的。随着OverlayFS和overlayroot的可用性,创建健壮的kiosk和具有回滚功能的嵌入式Linux设备现在非常容易。