编辑
2025-03-03
工作知识
0
请注意,本文编写于 95 天前,最后修改于 95 天前,其中某些信息可能已经过时。

目录

一:功能开启
1.1 内核功能
1.2 开机参数
1.3 ramdisk脚本
二:启动效果
2.1 挂载情况
三:追加功能
3.1 自动清理
3.2 提交改动
3.3 系统还原
3.4 U盘更新
3.5 备份系统
四:使用
4.1 脚本

有些项目需要做根文件系统只读,也需要保证系统本身是可写的。这里通过使用联合文件系统overlayfs来处理这种需求。

同样的,客户还需要做U盘更新,备份,还原等操作。为了方便处理,这些操作均通过ramdisk里的overlayfs脚本来实现。这里简单讲一下实现步骤

一:功能开启

1.1 内核功能

功能主要为两个地方,一个是支持ramdisk/initrd,一个是支持overlayfs

其次需要开启的为各类挂载系统的功能支持,如ext4,ntfs,exfat,squashfs,以及U盘的识别

如下所示:

CONFIG_BLK_DEV_INITRD CONFIG_OVERLAY_FS CONFIG_EXT4_FS CONFIG_NTFS_FS CONFIG_FAT_FS CONFIG_VFAT_FS CONFIG_SQUASHFS CONFIG_USB_STORAGE CONFIG_SCSI CONFIG_BLK_DEV_SD

1.2 开机参数

我们知道,系统开机由内核的cmdline来体现,为了使能overlayfs,可以显示的将overlayfs的配置体现在cmdline。如下

root=PARTLABEL=rootfs rootfstype=squashfs rw overlayroot=device:dev=PARTLABEL=userdata,fstype=ext4,mkfs=1

可以知道如下信息:

a.root分区默认挂载在PARTLABEL=rootfs,类型为squashfs b.overlayroot分区默认一个设备,为PARTLABEL=userdata,类型为ext4

1.3 ramdisk脚本

ramdisk脚本可以通过如下获取

https://gitlab2.kylin.com/shanghai-team/ramdisk/-/blob/ramdisk-reduce/ramdisk/scripts/init-bottom/kylinoverlay

脚本在init-bottom下运行,需要在ORDER下追加

/scripts/init-bottom/kylinoverlay "$@"

这样在系统加载ramdisk/initrd时,kylinoverlay运行会通过mount命令,将原始的root挂载修改为overlay挂载

如直接克隆ramdisk参考,上述步骤无需关心

二:启动效果

2.1 挂载情况

root@kylin:~# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT mmcblk0 179:0 0 29.1G 0 disk ├─mmcblk0p3 179:3 0 10.5G 0 part /media/root-ro └─mmcblk0p6 179:6 0 13G 0 part /media/root-rw

其中 /media/root-ro 和 /media/root-rw 是对应的root和userdata分区

root@kylin:~# blkid /dev/mmcblk0p3: TYPE="squashfs" PARTLABEL="rootfs" PARTUUID="614e0000-0000-4b53-8000-1d28000054a9" /dev/mmcblk0p6: PARTLABEL="userdata" UUID="62af73c5-bd8c-4cc0-af0a-10abc9574f21" TYPE="ext4" PARTLABEL="userdata" PARTUUID="2d1d0000-0000-4e74-8000-770200003b4e" overlay的挂载情况 root@kylin:~# mount /dev/mmcblk0p3 on /media/root-ro type squashfs (ro,relatime) /dev/mmcblk0p6 on /media/root-rw type ext4 (rw,relatime) overlayroot on / type overlay (rw,relatime,lowerdir=/media/root-rw/commit:/media/root-ro,upperdir=/media/root-rw/rootfs_overlay,workdir=/media/root-rw/rootfs_overlay-workdir/_)

这里把commit和root-ro作为lower,root-ro是最底层,rootfs_overlay作为upper,rootfs_overlay-workdir作为work

这里需要说明的是:

overlayfs是将多个分区/目录进行联合挂载,对挂载点进行分层,作为lower层的只读,upper层的可写,从而合并成overlayroot目录作为根文件系统,在根文件系统上的读写实际上是通过读写upper层的内容。

三:追加功能

3.1 自动清理

rm -rf "${root_rw}/${dir_prefix}/*"

开机自动清理即直接删除upper层的所有文件内容

3.2 提交改动

cp -rpf ${root_rw}/${dir_prefix}/* ${root_rw}/commit/ rm -rf ${root_rw}/${dir_prefix}/*

提交改动即将overlay_root目录的内容,原封不动拷贝到commit下。

值得注意的是,overlay会标记已删除的文件和目录为字符文件,需要针对其做如下处理

先遍历dir_prefix的字符文件,然后跑到commit下删掉 再遍历commit的字符文件,然后跑到dir_prefix下删掉

3.3 系统还原

func_restore(){ rm -rf ${root_rw}/* mkdir -p ${root_rw}/${dir_prefix} mkdir -p $workdir mkdir -p ${root_rw}/commit }

系统还原即删除所有root-rw目录的内容,并重新创建upper层,work层,和lower层的commit 目录

3.4 U盘更新

umount ${root_ro} umount ${root_rw} rootfs=`blkid -s PARTLABEL | grep PARTLABEL=\"rootfs\" | awk -F: '{print $1}'` userdata=`blkid -s PARTLABEL | grep PARTLABEL=\"userdata\" | awk -F: '{print $1}'` dd if=/update/filesystem.squashfs of=${rootfs} dd if=/update/ghost.squashfs of=${rootfs} dd if=/update/overlay.ext4 of=${userdata} mount ${rootfs} ${root_ro} mount ${userdata} ${root_rw}

U盘更新即找到U盘后,卸载root-rw和root-ro,将分区进行dd到系统上,然后再重新mount起来

因为直接使用的dd,所以dd时不能断电和拔出U盘,否则系统会变砖,后续可以考虑,系统变砖后,自动恢复rootfs的功能

3.5 备份系统

mksquashfs ${root_ro}/ /ghost/ghost.squashfs commit_size=`/usr/bin/du --block-size=1M -s ${root_rw}/commit/ | awk '{print $1}'` commit_size=$(($commit_size+100)) dd if=/dev/zero of=/ghost/overlay.ext4 bs=512 count=2048 mkfs.ext4 -F /ghost/overlay.ext4 resize2fs /ghost/overlay.ext4 ${commit_size}M inode=`expr ${commit_size} \* 1024 / 16` mkfs.ext4 -F -L userdata -N ${inode} /ghost/overlay.ext4 cp -rpf ${root_rw}/commit/ /tmp umount /tmp sync -f /ghost/overlay.ext4 e2fsck -f /ghost/overlay.ext4 resize2fs /ghost/overlay.ext4 -M

备份系统即打包root分区和打包overlay分区下的commit目录。生成ghost.squashfs和overlay.ext4

四:使用

4.1 脚本

使用通过overlaymanager.sh脚本,通过内置到操作系统下即可使用,具体操作情况如下

usage(){ info "Usage: " info " $0 -commit/-c #提交" info " $0 -ghost/-g #一键ghost" info " $0 -restore/-r #系统还原" info " $0 -update/-u #更新系统" info " $0 -y #打开自动清理" info " $0 -n #关闭自动清理" info " $0 -boot/-b #升级内核" }