我的系统在 eMMC 设备上有两个 LVM 卷,我试图通过用零填充其中一个卷来“擦除”它。这是我第一次使用 LVM,所以我将展示我尝试过但没有成功的内容。
首先,我常常pvdisplay -m
查看我的卷是如何设置的:
# pvdisplay -m
--- Physical volume ---
PV Name /dev/mmcblk0p2
VG Name vg0
PV Size 3.42 GiB / not usable 3.00 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 876
Free PE 776
Allocated PE 100
PV UUID i2Abz2-4o2h-9hq4-Gk3h-b5SD-0r9M-7oDfh3
--- Physical Segments ---
Physical extent 0 to 49:
Logical volume /dev/vg0/volume_a
Logical extents 0 to 49
Physical extent 50 to 99:
Logical volume /dev/vg0/volume_b
Logical extents 0 to 49
Physical extent 100 to 875:
FREE
这看起来很简单
- 有一个VG,
vg0
vg0
由一个PV组成,/dev/mmcblk0p2
- PV 为 3.42GiB,分成 876 个 4MiB PE
- PE [0, 49] 存储第一个 LV,
volume_a
- PE [50, 99] 正在存储第二个 LV,
volume_b
考虑到这一点,我继续尝试将其volume_b
归零dd
:
# dd if=/dev/zero of=/dev/vg0/volume_b bs=1M count=200
201+0 records in
200+0 records out
209715200 bytes (210 MB, 200 MiB) copied, 17.2374 s, 12.2 MB/s
根据 的输出pvdisplay -m
,我假设 的 PE [50, 99] (200M-400M)/dev/mmcblk0p2
应该用零填充。但这是我所看到的:
# hexdump /dev/mmcblk0p2 -s 200m
c800000 0000 0000 0000 0000 0000 0000 0000 0000
*
c900400 c800 0000 2000 0003 2800 0000 f0ad 0002
c900410 c7f5 0000 0001 0000 0000 0000 0000 0000
有一些零,但仅适用于 1MiB。然后我尝试用随机数填充它并重新检查。
# dd if=/dev/urandom of=/dev/vg0/volume_b bs=1M count=200
200+0 records in
200+0 records out
209715200 bytes (210 MB, 200 MiB) copied, 99.9135 s, 2.1 MB/s
# hexdump /dev/mmcblk0p2 -s 200m
c800000 0000 0000 0000 0000 0000 0000 0000 0000
*
c900400 c800 0000 2000 0003 2800 0000 f0ad 0002
c900410 c7f5 0000 0001 0000 0000 0000 0000 0000
这与以前相同,所以看来我的dd
通话没有按照我认为的方式进行。我的假设是,LV/dev/vg0/volume_b
是一种“虚拟”块设备,当我dd
写入它时,LVM 将其映射到相应 PE 的实际块写入。不幸的是,这与我所看到的不符。
[edit1] 我曾经hexdump
检查过的内容/dev/vg0/volume_b
,毫不奇怪,它充满了随机垃圾。我刚刚意识到hexdump
整个过程/dev/mmcblk0p2
并使用它grep
来查找数据的存储位置。目前正在顺利进行,如果有效的话我会更新。
[edit2] 搜索没有结果
答案1
经过更多测试,看来 LVM 及其与 Linux 内核的关系存在问题。我猜测它涉及磁盘缓存,但我不能 100% 确定。这是我发现的:
首先,我将一些垃圾数据写入我的 LVM 卷:
# dd if=/dev/urandom of=/dev/vg0/volume_b bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.600447 s, 1.7 MB/s
然后,我读回 LVM 卷。这是所写的垃圾片段:
# hexdump /dev/vg0/volume_b -n 0x20
0000000 2358 898b a13b 8d94 39a1 bff6 8b38 79ec
0000010 9155 1202 ce46 938f 49dc 7687 f804 bf13
0000020
但检查块设备本身,没有任何排列。
# hexdump /dev/mmcblk0p2 -s 200M
c800000 0000 0000 0000 0000 0000 0000 0000 0000
*
c900000 2dee 8ea4 2116 1981 252f d113 afc1 3182
c900010 e6fc 7d1b d173 3cab 4399 8715 bcdf 2272
有 1MiB 的零,后面跟着一些垃圾,这些垃圾与刚刚写入 LVM 卷的内容不符。但为了好玩,我尝试重新启动系统并再次检查。
# hexdump /dev/mmcblk0p2 -s 200M
c800000 0000 0000 0000 0000 0000 0000 0000 0000
*
c900000 2358 898b a13b 8d94 39a1 bff6 8b38 79ec
c900010 9155 1202 ce46 938f 49dc 7687 f804 bf13
有数据了!仍然有 1MiB 的零部分(大概是标头?),但写入的数据/dev/vg0/volume_b
位于/dev/mmcblk0p2
.
我实在无法解释这一点。我的猜测是 LVM 和内核驱动程序之间的链接可能存在问题,或者更具体地说,内核如何处理磁盘缓存。如果我通过 LV 将物理磁盘写入当前已缓存的区域,是否有可能缓存不会被更新或标记为脏?
这是一个嵌入式系统,因此我尝试通过断开电源并重新通电来重新启动系统。行为完全相同。在断电之前,hexdump
物理设备上会显示陈旧的数据,重新启动后会更新为新写入的数据。这表明写入完成后会刷新到磁盘,并且这不是 Linux 断电过程的一部分。
我将暂时保留这个问题,因为我仍然不确定其根本原因是什么,但至少我知道这个问题并不是真正的问题。
[编辑] 看来缓存确实是罪魁祸首。echo 3 > /proc/sys/vm/drop_caches
写入后运行会导致读回立即更新。韦尔普。