我正在用Rust编写工具,需要根据当前文件系统是SSD还是传统硬盘来改变其功能。
运行时的区别在于,如果文件存在于SSD上,则与HDD相比,将使用更多线程来访问文件,这只会破坏磁盘并降低性能。
我主要对Linux感兴趣,因为这是我的用例,但是欢迎其他任何添加。如果可能,我还需要以非root用户身份执行此操作。是否有系统调用或文件系统设备会告诉我我正在使用哪种设备?
最佳答案
信誉归功于@Hackerman:
$ cat /sys/block/sda/queue/rotational
0
如果返回1,则给定的文件系统位于旋转媒体上。
我已经将这个概念充实到一个shell脚本中,该脚本可以可靠地确定文件是否在旋转媒体上:
#!/bin/bash
set -e
# emits the device path to the filesystem where the first argument lives
fs_mount="$(df -h $1 | tail -n 1 | awk '{print $1;}')"
# if it's a symlink, resolve it
if [ -L "$fs_mount" ]; then
fs_mount="$(readlink -f $fs_mount)"
fi
# if it's a device-mapper like LVM or dm-crypt, then we need to be special
if echo $fs_mount | grep -oP '/dev/dm-\d+' >/dev/null ; then
# get the first device slave
first_slave_dev="$(find /sys/block/$(basename $fs_mount)/slaves -mindepth 1 -maxdepth 1 -exec readlink -f {} \; | head -1)"
# actual device
dev="$(cd $first_slave_dev/../ && basename $(pwd))"
else
dev="$(basename $fs_mount | grep -ioP '[a-z]+(?=\d+\b)')"
fi
# now that we have the actual device, we simply ask whether it's rotational or not
if [[ $(cat /sys/block/$dev/queue/rotational) -eq 0 ]]; then
echo "The filesystem hosting $1 is not on an rotational media."
else
echo "The filesystem hosting $1 is on rotational media."
fi
上面的内容对我来说既适用于普通分区(即
/dev/sda1
安装在给定的路径上),也适用于dm-crypt
分区(即/dev/mapper/crypt
安装在给定的路径上)。我没有用LVM进行测试,因为附近没有一个。对于Bash无法移植的歉意。