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

mat*_*975 15 embedded readonly root-filesystem ram buildroot

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

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

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

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

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

我还阅读了有关将根文件系统加载到 RAM 中以实现相同目的的可能性,但目前还不知道如何执行此操作。

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

F. *_*uri 11

新答案 (2015-03-22)

注意:这个答案比以前更简单,但不是更安全。我的第一个答案更强,因为您可以权限标志之前通过fs 挂载选项保持文件只读。因此,在没有写入权限的情况下强制写入文件是行不通的完全没有。)

是的,在Debian下,有一个包:fsprotect ( homepage )。

它使用aufs(默认情况下,但可以使用其他unionfs工具)允许实时会话更改,但默认情况下在 RAM 中,因此在重新启动时会忘记所有内容。

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

apt-get install fsprotect
Run Code Online (Sandbox Code Playgroud)

完成后,来自在线文档:

在那之后:

  • 编辑/boot/grub/menu.lst/etc/default/grub2/etc/lilo.conffsprotect=1G在内核参数中添加“ ”。
  • 根据需要修改1G。
  • 应用更改(即运行update-grub
  • 编辑/etc/default/fsprotect如果你想保护比其他的文件系统/
  • 重启

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

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

chmod ugo-w myfile
Run Code Online (Sandbox Code Playgroud)

如果您使用示例vi myfile并尝试使用命令在其上书写:w!,这将起作用并且您 myfile已更改。您可以重新启动以检索未修改的myfile.

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

旧(第一)答案:

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

使 r/o 可用

您必须在rw 中挂载一些目录,例如/var/etc也许/home. 这可以通过使用aufsunionfs来完成。我喜欢这种另一种方式,使用/dev/shmmount --bind

cp -a /var /dev/shm/
mount --bind /dev/shm/var /var
Run Code Online (Sandbox Code Playgroud)

之前,您可以将所有在正常操作中不必更改的目录移动到 中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
Run Code Online (Sandbox Code Playgroud)

因此,在RO重新安装时,复制/var/dev/shm大多数文件移动到不会占用太多空间/static-var,只有符号连接在RAM中被复制。

更好地完成此操作的更好方法是进行完整的电源循环,一天的完整工作并精细地运行如下命令:

find / -type f -o -type f -mtime -1
Run Code Online (Sandbox Code Playgroud)

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

日志记录

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

echo >/etc/syslog.conf '*.* @mySyslogServer.localdomain'
Run Code Online (Sandbox Code Playgroud)

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

升级

mount --bind在使用中运行时,为了在系统使用时进行这样的升级(不需要运行init 1,以减少停机时间),更简单的方法是重新构建一个干净的root,能够进行升级:

读写模式重新挂载“/”后:

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

现在:

shutdown -r now
Run Code Online (Sandbox Code Playgroud)