我正在开发一个巨大的复杂应用程序。你连接一个磁盘,按下一个按钮,它就会对磁盘进行分区和格式化,安装它,并将一些文件复制到上面。
为了测试这个应用程序,我们有一个测试系统,它循环安装磁盘映像并运行相同的过程。除了我们改变了应用程序逻辑,现在测试系统无法工作。如果你给程序一个真实的磁盘,一切正常。但如果你给它一个循环设备,它就会失败。
具体来说,应用程序对磁盘进行分区、格式化,然后抱怨无法挂载该分区。确切的命令是
mount /dev/vda /mnt --rw -o offset=111149056,sizelimit=314572800
(这里/dev/vda
只是一个符号链接/dev/loop0
。如果我直接引用没有什么区别loop0
。)
如果我手动运行该命令,我会得到以下结果:
root# mount /dev/vda /mnt --rw -o offset=111149056,sizelimit=314572800
FUSE exfat 1.0.1
ERROR: exFAT file system is not found.
root# echo $?
1
我可以一遍又一遍地运行这个命令,但它不起作用。没有理由,就是没有。
这是可怕的部分:如果我跑步cfdisk /dev/vda
然后立即退出而不做任何改变,现在它安装了!
什么是地狱cfdisk
磁盘会突然开始工作吗?我怎样才能消除调用这个程序的需要?
(我徒劳地尝试调用sfdisk -R /dev/vda
;它只是抱怨“无效参数”或其他什么。)
我可以拼凑应用程序来调用cfdisk -Ps /dev/vda
或执行其他操作,但我真的非常不愿意这样做。我想知道为什么这些都是必要的。在我们更改应用程序之前,一切正常......
答案1
在黑暗中刺探,但也许cfdisk
在运行时更新内核分区表?
您的应用程序逻辑与循环设备兼容吗?
格式化磁盘映像文件,创建所需的分区
-P
使用更新内核分区表的选项设置环回设备:losetup -P /dev/loop0 <image file>
挂载分区:
mount /dev/loop0p1 /mnt
这样,就无需为偏移量而烦恼,并且您的mount
命令更接近您在真实磁盘上使用的命令。您可能可以在 2 和 3 之间添加另一个步骤来创建一个符号链接。
答案2
内核首先必须了解分区。一旦对循环设备进行分区(例如/dev/loop0
),您就无法真正安装它(分区显然不是从设备的开头开始)。对于物理驱动器,您可以指示内核重新读取分区表(至少从 (S)ATA 驱动器)hdparm -z
。
另一种选择是使用特殊的实用程序,它将扫描设备中的分区表(不一定只是 GPT 或 MBR)并为您创建分区设备文件。其中之一是partx
(util-linux 附带)。
答案3
我对测试框架做了一个小改动,问题就消失了。
具体来说,我不是kpartx -u /dev/vda
在对设备重新分区后调用,而是kpartx -d
在kpartx -a
.现在一切都很好。诡异的...