web-dev-qa-db-ja.com

スタンバイ時のHDD電源投入:スピンアップを防止します

Linux Mint 17.1システムでは、バックアップにWestern Digital WD20EZRXHDDを使用しています。消費電力を最小限に抑え、ドライブの耐久性を向上させるために、HDDを通常はスピンダウンスタンバイ状態にし、明示的に必要な場合にのみスピンアップするようにします。

これは2つの方法で実現できます。簡単なアプローチは、hdparm -y /dev/sdbを使用してHDDを手動でスタンバイモードに設定することです。ただし、不利な点は、スクリプトによって再びスリープ状態に設定されるまで、起動中にドライブがスピンアップすることです。したがって、ドライブを スタンバイ状態でパワーアップ[〜 #〜] puis [〜#〜]、最初にスピンアップするのを防ぎます。

一部のWDドライブはPUISをサポートしていますが、PM2電源管理2モードと呼ばれています-)WesternDigitalによる。この機能は、 このWDナレッジベースの記事 で説明されているように、ジャンパーを使用して有効になっています。この構成の結果は、hdparmを使用して確認できます。

# hdparm -I /dev/sdb | grep "Power-Up In Standby"
   *    Power-Up In Standby feature set

ただし、Grubの起動画面が表示される前であっても、起動中にドライブが回転します。これは、接続されているすべてのHDDでオペレーティングシステムを探している、誤って構成されたブートローダーである可能性がありますか?

4
Finwood

私は数年前に、Linux Mintと、たまにしかデータを保存するためにしか使用されなかった古いHDを正確に検索しました。

私が見つけた解決策(リンクはもう手元にありません)は、あなたが見つけたように見えるものと同じでした:少数ハードドライブには、すべき原因となるジャンパー設定がある可能性がありますスリープ状態を維持する/起動時にスピンアップしないドライブ。 しかしそれは機能しませんでした、私の結果はあなたのものとまったく同じでした、それはまだ起動時に回転します。それに対する修正は見つかりませんでした。BIOS/ GRUB/linuxが個別に、または一緒に動作していたか、HD自体がリッスンしていなかったことがわかっています。

私はいくつかの「ホットプラグ」/「ホットスワップ」テストを行い、コンピューターの起動と実行中に電源を(SATA)ハードドライブに接続しました。いくつかのログエントリ(dmesg&/var/log/syslog)および正常に機能しました。次に、ドライブの使用が完了すると(同期、アンマウント、スリープ/ hdparm -y)電源を再度抜いてください。働いた!しかし、明らかに互換性のあるマザーボードとOSが必要なので、YMMVです。

ただし、電源プラグを抜いてドライブを使用するのはあまり便利でも簡単でもないので、双極単投スイッチを配線しました- DPST、ウィキペディアには図があります -には4つの端子があります。 2本の別々の電源線(12Vと5V?)、それらを別々に保ち、同時に両方をオン/オフにします。それをHDの電源に接続すると、必要なときにいつでもドライブの電源をオン/オフできます。

更新:

ホットスワップsed Linux Mint 14/15/16で動作しますが、何らかの理由で17以降で動作を停止し、カーネルの変更によって停止したと思います。現在、ハードドライブのホットスワップは機能しているように見えますが、ドライブはcorruptedと表示され、電源投入時の再起動のみが正常に機能します。たぶん、それを再び機能させる簡単な方法があるか、いくつかの特別なスイッチでいくつかの再コンパイルされたカーネルが必要です...?

アップデート2

ホットスワップはUbuntu16.04で再び機能しているようです(Mint 18も機能するはずです)。

2
Xen2050

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;
}

これらの行にコメントを付けてカーネルを再コンパイルすると、ドライブは起動しません。次に、それらをスピンアップするコマンドが必要になります。たとえば、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)

この時点で、カーネルをハックしても、前に説明したようにドライブはまったく起動しません。

編集2:ディスクをスピンアップするためのより良いコマンドを見つけました:

sg_sat_set_features --feature=7 /dev/sdX

これはsg3_utilsパッケージの一部であり、root権限が必要ですが、ディスクを適切に起動します。 Arch Linuxフォーラムで投稿が更新されました 、これが今のところ私の最終的な解決策です。その投稿の簡単な要約:

  • ブートローダー画面の前にPUIS対応ディスクが起動する場合は、対応するsataポートを無効にするか、PCI-exsataコントローラーカードを試してください。
  • カーネルを再コンパイルして、PUIS状態のディスクをスピンアップするコマンドを無効にします
  • sg_sat_set_featureを使用してディスクをスピンアップします
  • パーティションにアクセスするためにSATAポートを再スキャンします

編集3:archlinuxフォーラムで、ある種の魂がパッチを作成しました: https://bbs.archlinux.org/viewtopic.php ?pid = 1855326#p1855326

転写:

Libataにパッチを適用することを避けられない場合は、起動時にPUISドライブを無効にして、無限のエラーメッセージを取り除くこともできます。欠点は、sg_sat *などのユーザースペースツールが/ dev内のエントリを想定しているため、要求に応じてカーネルに再度有効にするように指示する必要があることです。

その機能の暫定パッチを見てください。誰かが時間を割いてカーネル標準に作り直し、上流に提案することを検討してくれることを願っています。クリーンな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:

これを書くためだけにArchLinuxフォーラムに登録したaz12shareartの功績だと思います。

3
Veon