用于修剪驱动器上未分配空间的实用程序

用于修剪驱动器上未分配空间的实用程序

我有一个驱动器(SD 卡),其中有一些 ext4 分区,但也有一些未分配的空间。该fstrim实用程序只能在文件系统内工作。在我重新发明轮子并编写一个之前,是否有另一种实用程序可以修剪未分配的空间(或者可以修剪明确指定的范围)?

我可以验证设备上的大部分未分配空间不是目前已知控制器是空闲的,正如我观察到的,在这张特定的卡上,读取修剪的空间返回 0,但设备的扫描显示剩余的大量垃圾数据。

编辑:我在使用时遇到问题hdparm。下面的示例丢弃了第一个扇区,但无论我指定的范围如何,我都会看到相同的结果。fstrim设备上没有问题:

root@ubuntu:~# hdparm --please-destroy-my-drive --trim-sector-ranges 0:1 --verbose /dev/mmcblk0 

/dev/mmcblk0:
trimming 1 sectors from 1 ranges
outgoing cdb:  85 0d 06 00 01 00 01 00 00 00 00 00 00 40 06 00
outgoing_data:  
00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

ioctl(fd,SG_IO): Invalid argument
FAILED: Invalid argument

我正在进一步调查,但有人有任何见解吗?

答案1

如果您有足够新的版本,它包含能够使用和选项修剪整个设备或设备内范围的util-linux工具。blkdiscard--offset--length

请注意: blkdiscard很危险,如果你让它修剪错误的区域,你的数据就会消失!

因此,您可以找出分区表的未分区(空闲)区域,然后使用此工具修剪它们。对于msdosgpt分区,parted提供空闲区域,如下所示:

# parted -m /dev/sda unit b print free | grep ':free;'
1:17408B:1048575B:1031168B:free;
1:64022904832B:64023240191B:335360B:free;

为其添加一个循环...

while IFS=: read -ra FREE
do
    echo blkdiscard --offset ${FREE[1]%%B} --length ${FREE[3]%%B} /dev/sda
done < <(parted -m /dev/sda unit b print free | grep ':free;')

打印

blkdiscard --offset 17408 --length 1031168 /dev/sda
blkdiscard --offset 64022904832 --length 335360 /dev/sda

验证此输出对您来说是否正确,如果您愿意,可以添加其他选项(详细?),最后删除 ,echo以便实际执行,您应该已设置完毕。

该示例的第二个命令实际上失败了,因为长度太小 - 可能值得在循环内部进行检查,忽略小于 1MB 的区域,因为它们不太可能被成功修剪。


如果您使用 LVM 而不是分区,则可以为未占用的空间创建一个 LV 并修剪:

lvcreate -l100%FREE -n blkdiscard SSD-VG
blkdiscard -v /dev/SSD-VG/blkdiscard
lvremove SSD-VG/blkdiscard

如果您issue_discards = 1在 中设置lvm.conf,您可以跳过调用,因为 LVM 将自行blkdiscard发出 TRIM 。lvremove

答案2

hdparm --trim-sector-ranges可以修剪一个范围。手册页警告使用它,因此您最好确保获得正确的范围和语法。

我认为发送分区外的所有数据的修剪是危险的,因为有时会有一些隐藏数据,例如引导加载程序代码或第二个分区表。您需要准确地了解分区之外的哪些区域确实未使用。

答案3

请注意blkdiscard- 这是非常非常危险并且可能很混乱。

我在发出命令时在测试系统上发生了意外:

root@test:/home/test# fdisk -l /dev/nvme1n1
Device               Start        End    Sectors   Size Type
/dev/nvme1n1p1        2048    1101823    1099776   537M EFI System
/dev/nvme1n1p2     1134592    1658879     524288   256M Linux RAID
/dev/nvme1n1p3     1658880 1025658879 1024000000 488.3G Linux RAID    
root@test:/home/test# 
root@test:/home/test# blkdiscard /dev/nvme0n1
root@test:/home/test# fdisk -l /dev/nvme0n1
bash: /usr/sbin/fdisk: cannot execute binary file: Exec format error
root@test:/home/test# 
root@test:/home/test# fdisk -l /dev/nvme1n1
bash: /usr/sbin/fdisk: cannot execute binary file: Exec format error
root@test:/home/test# fdisk -l /dev/nvme1n1p1 
bash: /usr/sbin/fdisk: cannot execute binary file: Exec format error
root@test:/home/test# 
root@test:/home/test# fdisk 
bash: /usr/sbin/fdisk: cannot execute binary file: Exec format error

它确实修剪了另一个驱动器!操作系统安装于nvme1n1p1..3NVME0N1是试驾。

幸运的是,我的测试系统完全丢失,没什么大不了的,但我觉得有义务公开分享这一点以警告您。

我认为更好的方法是fstrim并设置issue_discards = 1lvm.conf所提到的弗罗斯特舒茨

编辑 2024:尽管有人不喜欢这个,但我有 30 年的计算机经验,从 ZX Spectrum 作为我的第一台电脑开始。我确信操作系统级别映射器可能存在问题甚至错误,特别是在锁定分区映射情况下,或者当计算机将启动优先级更改为其他 efi 分区时,当两个磁盘上都存在 efi 并且系统 fstab 包含在另一个磁盘上定义的 efi 时。那里多种场景,因此blkdiscard命令应与极度小心我的主要建议是在使用它之前重新启动系统。这个命令破坏数据

相关内容