使用只读根文件系统是嵌入式安装的一个好主意吗?


15

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

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

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

该系统已成功地引导使用syslinux由根目录设置为CF ext3分区在我的buildroot的文件系统所在。

我的问题集中在面对即时(且频繁)断电的鲁棒性需求上,因为断电后设备能否成功启动至关重要。我已经读过,将根文件系统安装为只读是确保数据完整性的一种方法。这是我进行下去的明智方式吗?

我还阅读了将根文件系统加载到RAM中以实现相同功能的可能性,但目前尚不知道如何实现。

有没有实现该目标的首选方法,如果是,那么我进行下去的最佳方法是什么?

Answers:


11

新答案(2015-03-22)

注意:这个答案比以前的答案更简单,但并不安全。我的第一个答案更强,因为您可以权限标志之前通过fs挂载选项将文件保持只读状态。因此,强制进行未经许可的文件写入将不起作用完全没有。)

是的,在Debian下,有一个软件包:fsprotecthomepage)。

它使用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并尝试使用command编写示例,那么:w!它将起作用,并且您 myfile已更改。您可以重新启动以检索未修改的myfile

我的以下第一个解决方案甚至是不可能的:

旧的(第一)答案:

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

使R / O可用

你必须安装一些目录中RW一样/var/etc也许/home。这可以通过使用aufsunionfs来完成。我喜欢另一种方式,使用/dev/shmmount --bind

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

您可以将所有在正常操作中无需更改的目录移动到中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-var,只有符号连接在RAM中被复制。

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

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

感谢您的回答。由于我的Linux技能目前还不是很好,所以我不完全了解它。不过,它仍然非常有帮助,并为我提供了更多的研究领域。
mathematician

答案已编辑!新的解决方案和差异说明!
F. Hauri

这不能回答问题,对于基于debian的系统来说是一个很好的答案,但是Buildroot不是基于debian的。
LovesTha

@LovesTha看一下 Old(第一)答案!这是基于Debian的, 并且U可以理解原理并为任何发行/安装方式实现相同的机制。(即使“ 升级”部分显示Debian命令,U也可以执行手动升级或任何其他基于distrib的升级。)
F. Hauri 2016年

您的旧答案将是对有关设置只读Linux系统的一般问题的一个很好的答案。一旦我完成了将buildroot设为只读的探索,我希望回来并在此处针对特定问题给出详细的详细答案。Buildroot已经将/ var的临时位符号链接到/ tmp,这是一个tempfs。/ etc不应被用作程序的暂存空间,因此不需要对其进行特殊处理。
LovesTha

3

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

未设置BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW

我设法创建了一个仅使用其ext4 /分区为只读的映像,因此拔出系统电源完全不会造成损害。它很好用,所以如果您不需要写文件系统,也许这是一个比上述解决方案简单得多的解决方案(由于它指向apt-get,它似乎或多或少适用于Debian系统)。


感谢您的回答-但是最终,我选择了一个initramfs设置,该安装仅在CF驱动器上安装了几个带有sync选项的目录,以实现数据持久性。暂时这对我很好。
mathematician1975

补充说明:使用较旧的buildroot版本,检查/etc/inittab是否在/那里重新安装了。如果是这样,请根据您的需要进行更改。
evnu

这个答案是“构建根方式”的重要组成部分。要使更复杂的系统工作,将需要接受的答案中的许多建议。尽管可能需要做的只是将一些额外的符号链接设置为/ tmp(tempfs),并且一切正常。
LovesTha
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.