对于嵌入式设置来说,使用只读根文件系统是个好主意吗?

对于嵌入式设置来说,使用只读根文件系统是个好主意吗?

我的任务是在嵌入式设备上运行 Linux 作为操作系统。

目标具有 x86 处理器和 8 GB CompactFlash 存储设备。

我已经成功地使用 buildroot 来创建内核映像和交叉编译工具。我已将 CF 设备分区为一个小的 FAT 分区,其中包含内核映像以及syslinux引导配置和ext3文件系统,我将 buildroot 生成的根文件系统解压到其中。

syslinux通过将根目录设置为我的buildroot文件系统所在的CF ext3分区,系统可以成功启动。

我的问题集中在面对立即(和频繁)断电时的鲁棒性需求,因为断电后设备成功启动至关重要。我读到,将根文件系统安装为只读是确保数据完整性的一种方法。这对我来说是一个明智的继续方式吗?

我还了解了将根文件系统加载到 RAM 中以实现相同目的的可能性,但目前还不知道如何做到这一点。

是否有实现此目标的首选方法?如果有,我继续前进的最佳方法是什么?

答案1

新答案 (2015-03-22)

笔记:这个答案比以前更简单,但并不更安全。我的第一个答案更强,因为你可以保存文件只读经过文件系统挂载选项 权限标志。所以强迫未经许可写入文件根本不起作用。)

是的,下德班,有一个包:FS保护主页)。

它使用aufs(默认情况下,但可以使用其他unionfs工具)来允许实时会话更改但默认情况下在 RAM 中,因此重启时一切都会被忘记。

您可以通过简单地运行以下命令来安装它们:

apt-get install fsprotect

完成后,从在线文档:

在那之后:

  • 编辑/boot/grub/menu.lst/etc/default/grub2/etc/lilo.conf并将“ fsprotect=1G”添加到内核参数中。
  • 根据需要修改1G。
  • 应用更改(即运行update-grub
  • 如果/etc/default/fsprotect您想保护/.
  • 重启

您可能还想用密码保护 grub 引导加载程序或禁止对其进行任何更改。

从那里开始,如果某些文件受到保护以防止更改,例如

chmod ugo-w myfile

如果您使用示例vi myfile并尝试使用命令在其上写入:w!,这将起作用并且您的内容 myfile会发生变化。您可以重新启动以检索未修改的myfile.

我的以下第一个解决方案甚至不可能做到这一点:

旧的(第一个)答案:

是的,这是一个强大的解决方案,而且功能强大!

让 r/o 可用

您必须安装一些目录读写,喜欢/var/etc也许/home。这可以通过使用完成奥夫斯或者联盟。我喜欢这个其他方式,使用/dev/shmmount --bind

cp -a /var /dev/shm/
mount --bind /dev/shm/var /var

您之前可以将在正常操作中无需更改的所有目录移动到 a 中static-var,而不是在 /var 中创建符号链接:

mkdir /static-var
mkdir /static-var/cache
mkdir /static-var/lib
mv /var/lib/dpkg /static-var/lib/dpkg
ln -s /static-var/lib/dpkg /var/lib/dpkg
mv /var/cache/apt /static-var/cache/apt
ln -s /static-var/cache/apt /var/cache/apt
... # an so on

因此,在 ro 中重新挂载时,复制/var不会/dev/shm占用太多空间,因为大多数文件都会移动到/static-varram 中,并且只复制符号链接。

精细地做到这一点的更好方法是进行一次完整的电源循环,一天的完整工作,并精细地运行如下命令:

find / -type f -o -type f -mtime -1

因此您将看到哪些文件需要位于读写分区上。

记录

由于该主机不存在可写静态内存,为了存储历史记录和其他日志,您必须配置远程syslog服务器。

echo >/etc/syslog.conf '*.* @mySyslogServer.localdomain'

这样,如果您的系统因任何原因崩溃,之前的所有内容都会被记录下来。

升级中

当运行某些mount --bind正在使用的系统时,为了在系统正在使用时进行此类升级(无需运行init 1,以减少停机时间),更简单的方法是重新构建一个干净的系统,可以进行升级:

重新挂载'/'后读写模式:

mount -o remount,rw /

for mpnt in /{,proc,sys,dev{,/pts}};do
    mount --bind $mnpt /$mnt$mpnt;
    done

chroot /mnt

apt-get update && apt-get dist-upgrade

exit

umount /mnt/{dev{/pts,},proc,sys,}

sync
mount -o remount,ro /

现在:

shutdown -r now

答案2

我只有使用更新的 buildroot (2014-02) 的经验。在该版本中,您可以在配置文件中禁用“启动时重新挂载根文件系统读写”:

BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW 未设置

我设法创建了一个仅将其 ext4/分区用作只读的映像,因此拔掉系统电源根本不会造成任何损害。它工作得很好,所以如果你不需要写入你的文件系统,也许这是一个比上面提到的更简单的解决方案(这似乎或多或少适用于 Debian 系统,因为它指的是 apt-get)。

相关内容