Fin*_*ood 5 linux boot hard-drive grub hdparm
在我的 Linux Mint 17.1 系统上,我使用 Western Digital WD20EZRX HDD 进行备份。为了最大限度地降低功耗并延长驱动器的耐用性,我希望 HDD 通常处于停转待机状态,并且仅在明确需要时才启动。
这可以通过两种方式实现: 简单的方法是使用 手动将 HDD 设置为待机模式hdparm -y /dev/sdb。但是,缺点是驱动器在启动期间旋转,直到被脚本再次设置为休眠。因此,我想让驱动器在 Standby,
PUIS 中通电,以防止它在第一次启动。
一些 WD 驱动器支持 PUIS,尽管它被Western Digital称为PM2,即电源管理 2 模式。使用跳线启用此功能,
如此 WD 知识库文章 中所述。可以使用hdparm以下方法验证此配置的结果:
# hdparm -I /dev/sdb | grep "Power-Up In Standby"
* Power-Up In Standby feature set
Run Code Online (Sandbox Code Playgroud)
但是,即使在 Grub 启动屏幕显示之前,驱动器在启动过程中仍会旋转。这可能是一个错误配置的引导加载程序,它在所有连接的 HDD 上寻找操作系统?
Linux 内核启动驱动器。看一下 drivers/ata/libata-core.c (内核源代码)中的这些行:
if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) {
tried_spinup = 1;
/*
* Drive powered-up in standby mode, and requires a specific
* SET_FEATURES spin-up subcommand before it will accept
* anything other than the original IDENTIFY command.
*/
err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
if (err_mask && id[2] != 0x738c) {
rc = -EIO;
reason = "SPINUP failed";
goto err_out;
}
/*
* If the drive initially returned incomplete IDENTIFY info,
* we now must reissue the IDENTIFY command.
*/
if (id[2] == 0x37c8)
goto retry;
}
Run Code Online (Sandbox Code Playgroud)
如果您注释这些行并重新编译内核,驱动器将不会旋转。然后,您需要一个命令来启动它们,例如,当 hdparm 禁用 PUIS 时,它会启动驱动器。看看这个链接。
这就是我对 PUIS 的全部了解。
编辑: 我刚刚注意到您的驱动器在 grub 屏幕之前旋转:这意味着主板正在旋转驱动器。您可以尝试在 BIOS/UEFI 配置中禁用相应的 SATA 端口(如果允许),然后重试。如果它工作正常,驱动器将保持静止,直到内核旋转它,在 grub 屏幕之后和用户登录提示之前,您可以在 dmesg 中找到
ataX.00: failed to IDENTIFY (SPINUP failed, err_mask=0x4)
ataX.00: revalidation failed (errno=-5)
ataX: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
Run Code Online (Sandbox Code Playgroud)
此时,如果您破解内核,驱动器将根本不会像我之前描述的那样旋转。
编辑2: 我找到了一个更好的命令来旋转磁盘:
sg_sat_set_features --feature=7 /dev/sdX
Run Code Online (Sandbox Code Playgroud)
它是 sg3_utils 包的一部分,需要 root 权限,但可以很好地旋转磁盘。 在 arch linux 论坛上更新的帖子,这是我目前的最终解决方案。该帖子的一个小摘要:
编辑3: 某个好心人在archlinux论坛上写了一个补丁:https://bbs.archlinux.org/viewtopic.php ?pid=1855326#p1855326
转录:
如果我们无法避免修补 libata,不妨在启动时禁用 PUIS 驱动器,以摆脱无尽的错误消息。缺点是我们必须告诉内核根据请求重新启用它们,因为像 sg_sat* 这样的用户空间工具需要 /dev 中的一个条目。
看看我针对该功能的暂定补丁。我希望有人会考虑抽出时间将其重新设计为内核标准并向上游提出。我针对 clean v4.19.56 编写了补丁。
重新编译模块并重建 initramfs 映像后,请记住在引导加载程序中设置“libata.spinup_control=0”内核参数!
那么你应该
echo 1 > /sys/module/libata/parameters/spinup_control
并对您想要启动的驱动器发出重新扫描。
echo '- - -' > devices/pci0000:00/0000:00:1f.2/ata4/host3/scsi_host/host3/scan
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -171,6 +171,10 @@ static int atapi_an;
module_param(atapi_an, int, 0444);
MODULE_PARM_DESC(atapi_an, "Enable ATAPI AN media presence notification (0=0ff [default], 1=on)");
+static int spinup_control = 1;
+module_param(spinup_control, int, 0644);
+MODULE_PARM_DESC(spinup_control, "Spin up standby drives (0=PUIS drives disabled, 1=standby drives can spin up [default])");
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Library module for ATA devices");
MODULE_LICENSE("GPL");
@@ -1978,28 +1982,40 @@ retry:
goto err_out;
}
- if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) {
+ /*
+ * My drives indicate with 0x738c that media is ready when PUIS
+ * is enabled, in conflict with the relevant standards.
+ * The compliant behavior therefore prevents spun-up and ready
+ * drives from being recognized on reboot.
+ * I had no choice but to remove "|| id[2] == 0x738c))".
+ */
+ if (!tried_spinup && (id[2] == 0x37c8)) {
tried_spinup = 1;
/*
* Drive powered-up in standby mode, and requires a specific
* SET_FEATURES spin-up subcommand before it will accept
* anything other than the original IDENTIFY command.
*/
- err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
- if (err_mask && id[2] != 0x738c) {
- rc = -EIO;
- reason = "SPINUP failed";
- goto err_out;
- }
- /*
- * If the drive initially returned incomplete IDENTIFY info,
- * we now must reissue the IDENTIFY command.
- */
- if (id[2] == 0x37c8)
+ if (spinup_control) {
+ err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
+ if (err_mask) {
+ rc = -EIO;
+ reason = "SPINUP failed";
+ goto err_out;
+ }
+ /*
+ * If the drive initially returned incomplete IDENTIFY info,
+ * we now must reissue the IDENTIFY command.
+ */
goto retry;
+ } else {
+ dev->horkage |= ATA_HORKAGE_DISABLE;
+ ata_dev_notice(dev, "horkage modified (drive powered-up in standby)\n");
+ }
}
- if ((flags & ATA_READID_POSTRESET) &&
+ if (spinup_control && (flags & ATA_READID_POSTRESET) &&
(class == ATA_DEV_ATA || class == ATA_DEV_ZAC)) {
/*
* The exact sequence expected by certain pre-ATA4 drives is:
Run Code Online (Sandbox Code Playgroud)
感谢 az12shareart,我认为他注册到 arch linux 论坛只是为了写这篇文章。
几年前,我搜索了确切的东西,寻找 Linux Mint 和一个也仅用于偶尔数据存储的旧 HD。
我找到的解决方案(不再有方便的链接)与您发现的相同:一些硬盘驱动器可能有一个跳线设置,该设置应该导致驱动器保持睡眠状态/在启动时不旋转。但它不起作用,我的结果和你的完全一样,它仍然在启动时旋转。我没有找到任何解决方案,据我所知,这是 BIOS/GRUB/linux,单独或一起工作,或者只是 HD 本身没有监听。
我做了一些“热插拔”/“热插拔”测试,在计算机启动和运行时将电源连接到(SATA)硬盘驱动器。它生成了一些日志条目(dmesg & /var/log/syslog)并成功运行。然后,当完成驱动器(同步、卸载、睡眠/ hdparm -y)后,再次拔掉电源。成功了!但它显然需要兼容的主板和操作系统,所以 YMMV。
然而,拔掉电源插头来使用驱动器并不是很方便或容易,所以我连接了一个双刀单掷开关 - DPST,维基百科有一个图表- 有 4 个端子,用于 2 条独立的电源线(12V & 5V?),将它们分开并同时打开/关闭它们。将其连接到硬盘的电源后,我可以在需要时打开和关闭硬盘。
热交换曾经在 Linux Mint 14/15/16 上工作,但由于某种原因它在 17 及更高版本上停止工作,我猜一些内核更改阻止了它。现在,热插拔硬盘似乎可以工作,但驱动器读取为已损坏,只有开机重新启动才能使其成功工作。也许有一种简单的方法可以让它再次工作,或者需要一些重新编译的内核和一些特殊的开关......?
热插拔显然在 Ubuntu 16.04 上再次起作用(Mint 18 也应该起作用)。
| 归档时间: |
|
| 查看次数: |
7448 次 |
| 最近记录: |