在双启动场景中自动创建、移动和调整持久数据分区的大小

在双启动场景中自动创建、移动和调整持久数据分区的大小

设备:Raspberry Pi 4B 上的 Ubuntu 20.04.5

我愿意在 Azure 设备更新方案中自动执行持久数据分区的过程。为此(双启动),我需要一个持久数据分区(因此我的分区表是 <boot/rootfs1/rootfs2/data>)。该映像是在 Azure Pipeline 过程中创建的,因此该映像仅包含几 GB 的分区表。当 Raspberry Pi 4B 上的 SD 卡刷机时,脚本会在首次启动时运行以调整分区大小,如下所示:

检索可用空间(在基础映像上,所有四个分区都约为 10Gb,但 SD 卡最小为 32Gb) 计算所有扇区以调整分区大小 将它们移动到最终偏移量 调整分区大小 调整文件系统大小 它们都是 ext4 文件系统,在映像创建过程中一切顺利,在持久数据创建中创建了文件夹,所有文件夹都指示 ext4,每个人都很开心。但在调整大小过程中,以及使用 sfdisk 移动分区时,分区会丢失其 ext4 fstype,就像它们已损坏一样。这是我的命令:

echo "+$data_sectors_to_move," | sfdisk /dev/mmcblk0 -N 4 -f --no-reread

我曾经添加过 --move-data 参数,但过去几天它一直给我错误

sfdisk: /dev/mmcblk0p4: failed to move data: Not a directory

现在,我不移动数据,它只是丢失了 ext4 格式。

我尝试执行 mkfs.ext4,但是在自动过程执行和设备重启后,执行 parted /dev/mmcblk0 --script print 时仍然没有 ext4 指示。

日志中没有显示任何错误。请注意,我无法发布我的代码,但我很乐意回答您的问题。

期望分区被移动和调整大小,并保留其中的数据和 fs 类型,但是什么也没有发生。

答案1

我曾经添加--move-data参数...

sfdisk这似乎可能是您的问题。分区工具仅对分区表进行操作。它们通常不会触及磁盘上的底层数据,但使用标志时除外--move-data

除非您传递--move-data,否则旧数据不会跟随新分区表。这实际上会导致分区表不正确,因为数据仍在旧位置。在数据恢复场景中,您需要再次重写分区表以匹配每个数据分区的旧起始和结束位置。(除非其他内容已经覆盖了它们,否则您通常可以通过这种方式从磁盘恢复数据。)

除非在空闲的未使用磁盘空间中创建新分区,否则使用诸如、、、甚至更旧的工具(如、、、等)时总是有sfdisk丢失数据的可能性的sgdiskgdiskfdiskpartedgparted

请注意,在这种情况下,“数据丢失”一词并不意味着您已经破坏了底层数据,而是由于分区表条目现在指向不同的位置,您无法轻松访问这些数据。当系统尝试在这些新的扇区偏移位置读取文件系统数据时,它看起来是损坏的,因为它不是从该点开始的。一个比喻可能是,您丢失了一本书的章节和起始页的目录,然后尝试创建一个新的目录,以便您可以插入自己的章节,但忘记了实际移动其他章节和页码。然后,如果您根据新错误的目录开始阅读,您很可能最终从章节的中间开始,这本书的时间顺序就不合理了。

我建议追查一下最初发生错误的原因:

sfdisk:/dev/mmcblk0p4:无法移动数据:不是目录

原始错误消息很可能是出于其他原因而发生的,如果不查看脚本代码或深入了解运行命令的系统中发生的情况,很难说出原因。我的第一个猜测是,如果这种情况发生在启动时,这可能是由于/dev/mmcblk0p4设备文件实际上尚未存在,这是 SystemD 和系统启动中常见的竞争条件造成的。如果是这种情况,请确保您的脚本正在运行设备/dev/mmcblk0p4已创建并准备就绪。如果您使用的是 SystemD,则只需等待单元dev-mmcblk0p4.device准备就绪即可。只需dev-mmcblk0p4.device为您的启动脚本添加依赖项即可。如果您将其他.service文件链接在一起作为彼此的依赖项,请确保您使用systemd-notify作为后命令(或编译sd_notify()程序)来发出每个服务步骤完成时的信号。简单的Wants=或单元依赖项仍然可能受到竞争条件的影响,因为 SystemD 会尝试尽可能快地并行启动所有内容,而不考虑其他单元是否实际完成了所有工作。Before=After=

相关内容