将 USB 闪存驱动器设置为非旋转驱动器

将 USB 闪存驱动器设置为非旋转驱动器

我正在尝试优化 IO 调度程序,并为旋转和非旋转驱动器(不同)使用适当的调度程序。当我跑步时:

cat /sys/block/sd*/queue/rotational

我得到:

1    <-- for sda
1    <-- for sdb

虽然 sdb 是 USB 闪存驱动器,但它不应该是旋转的。

$ udevadm info -a -n /dev/sda | grep queue
ATTRS{queue_depth}=="31"
ATTRS{queue_ramp_up_period}=="120000"
ATTRS{queue_type}=="simple"

$ udevadm info -a -n /dev/sdb | grep queue
ATTRS{queue_depth}=="1"
ATTRS{queue_type}=="none"

所以不存在这样的属性:

ATTR{queue/rotational}=="0" or ...=="1"

答案1

是的,这是一个令人困惑的问题;这是对应的内核错误 90761(2015 年报告)和 2019 年博客文章对此进行调查。据推测,这只是一个表面问题,因为传统的 IO 调度程序已全部被MQ 截止日期.. 然而,在相当令人头疼的情况下,我想出了一个适用的规则,所以我想我不妨将其发布在这里。

/etc/udev/rules.d/usb-flash-drive-non-rotational.rules:

# Try to catch USB flash drives and set them as non-rotational. Probably no impact whatsoever : /
# c.f. https://mpdesouza.com/blog/kernel-adventures-are-usb-sticks-rotational-devices/

# Device is already marked as non-rotational, skip over it
ATTR{queue/rotational}=="0", GOTO="skip"

# Device has some sort of queue support, likely to be an HDD actually
ATTRS{queue_type}!="none", GOTO="skip"

# Flip the rotational bit on this removable device and give audible signs of having caught a match
ATTR{removable}=="1", SUBSYSTEM=="block", SUBSYSTEMS=="usb", ACTION=="add", ATTR{queue/rotational}="0"
ATTR{removable}=="1", SUBSYSTEM=="block", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/bin/beep -f 70 -r 2"

LABEL="skip"

答案2

您可以hdparm -I为每个磁盘运行:

hdparm -I /dev/sda
hdparm -I /dev/sdb

如果该行的输出hdparm -I包含如下行:

Nominal Media Rotation Rate: Solid State Device

使用来自 ATA 样式 IDENTIFY 响应的信息,表明驱动器不可旋转。

但显然还有另一种方法可以查询此信息,并且内核似乎更喜欢它。如果您sg3_utils安装了该软件包,则可以使用此命令进行与内核执行的操作相同的查询(至少在撰写本文时):

sg_inq --vpd --page=0xb1 /dev/sda

如果响应包含以下行:

Non-rotating medium (e.g. solid state)

...然后,只有这样/sys/block/sd*/queue/rotational属性才会被设置为0。

如果您的 USB 闪存驱动器是 USB2,则任何基于调度程序的优化都可能会因 USB 协议效率低下而不堪重负。仅当您有实际的 USB3 SuperSpeed 驱动器时才需要担心这一点。

相关内容