web-dev-qa-db-ja.com

スワップを有効にしないハイバネーション

私のラップトップにはたくさんのRAMとSSDがあります。SSDを使い果たしないために、スワップを使用したくありません。プロセスがこれほど多くのRAMスワップの使用を開始する必要がある場合は、明らかに誤動作しているため、カーネルによって強制終了される必要があります。ただし、ラップトップを休止状態またはハイブリッドスリープにできるようにしたいのです。現在、取得するのは非常に難しいようです。このようなセットアップは機能します。いくつかの注意点があります。

  • swappinessを0に設定しても、アプリケーションが要求するメモリが多すぎる場合はスワップを使用できます。スワップを有効にする方法はないようですが、カーネルがスワップスペースとして使用するのを停止します(したがって、そのユーティリティを休止状態イメージ用のスペースに減らします)
  • スワップを(一時的に)無効にすると、systemctl hibernateのようなコマンドがFailed to hibernate system via logind: Sleep verb not supportedでエラーになります。
  • Upowerでシステムを休止状態/ハイブリッドスリープ状態にできるようにしたい(したがって、スワップを有効にしてからsystemctl hibernateを起動するラッパースクリプトを作成するだけでは不十分です)

私は今、これを達成するための正しい方法を探しています。これを行う1つの方法は、通常、スワップパーティションを無効にしてから、systemdを介して適切なポイントでswapon(およびシステムが起動した後はswapoff)にすることです。しかし、私はこれをどのように達成するか途方に暮れています。

別の方法は、スワップファイルを使用することですが、スワップパーティションを使用する場合に比べて、さらに複雑になるようです。特に、フルディスク暗号化を使用しており、uswsuspは、既存のスワップパーティションですでに持つことができるものの上にある単なる別のレイヤーのようです。しかし、おそらく私は何かが足りないので、スワップファイルを使用する方がこの目的のために全体的に簡単です。

8
josch
  1. システムに十分なメモリがない状態になる可能性があることがすでにわかっている場合にスワップを無効にすることは、悪い考えです。カーネルにシステムを割り当てるためのメモリがない瞬間に、おそらくvery-very応答しないか、ハングするだけなので、再起動する必要があります。ハングすると、データが失われる可能性があり、ファイルシステムが破損することもあります。ファイルシステムによっては自動的に修正できますが(ext *ファミリ、fatファミリ、btrfsなど)、すべてのFSがこの機能をサポートしているわけではありません。おそらくfsckを実行したくないでしょう。破損するたびにシングルユーザーモードで...

  2. カーネルは、必要なものをすべてSSDに書き込むだけではそれほど愚かではありません。カーネルは、HDDとは動作が異なり、TRIMなどを使用して可能な限り少ない書き込みを行おうとします。あなたが思うかもしれないほどあなたのドライブにそれほど害はありません。

  3. ハイバネーションは、低レベルで動作する組み込みカーネルサブシステムです。サイズ≥RAMサイズで、メモリの完全なスナップショットを作成できるようにするための個別のパーティションが必要です。 ここ Linuxが休止状態を管理する方法を読むことができます。メモリイメージを永続的に保存する場所がない場合、休止状態が機能する方法はありません。データを空中に保存することはできません。永続的な物理ストレージがない=休止状態がありません。これがあなたの質問に対する答えでもあります: Linuxでスワップなしで休止状態を使用することはできません。

つまり、もちろん、スワップなしで生活し、休止状態でのみ有効にすることができますが、システムがオンになっている時間の99.9%に、すべてに十分なメモリがあることが確実な場合に限ります。そうでない場合は、スワップを使用する必要があります。

今可能な解決策に:

systemctl hibernateを実行すると、systemdはsystemd-hibernate.serviceというサービスを開始します。通常はユニットファイルがあります/ usr/lib/systemd/system /ディレクトリ

Debianでは次のようになります。

#  SPDX-License-Identifier: LGPL-2.1+
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Hibernate
Documentation=man:systemd-suspend.service(8)
DefaultDependencies=no
Requires=sleep.target
After=sleep.target

[Service]
Type=oneshot
ExecStart=/lib/systemd/systemd-sleep hibernate

ご覧のとおり、必須およびのオプションがあります。スワップを有効にして、その名前をこれらのフィールドに追加する別のユニットを作成できます。これをswap-on.serviceと呼び、/ etc/systemd/system /ディレクトリに配置します。

ファイルは次のようになります。

# Unit filed is not required in our case so you can skip it
[Unit]
Description=Enable swap partition

[Service]
# This line means that service will be executed just once and immediately stop when
# swapon enables swap on /dev/sda3
Type=oneshot

# Change /dev/sda3 with device named after your swap partition 
# like /dev/sdb3 or /dev/nvme0n1p3
# Use lsblk to determine your swap partition (partition with [SWAP] as mountpoint)
# Of course you can think of a more complex solution like running external script
# that determines your swap partition automatically every time service is executed
# but for now I'll go with simple /dev/sda3
ExecStart=/sbin/swapon /dev/sda3

次に、システムを変更する必要がありますsystemd-hibernate.service

#  SPDX-License-Identifier: LGPL-2.1+
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Hibernate
Documentation=man:systemd-suspend.service(8)
DefaultDependencies=no
Requires=sleep.target swap-on.service <--
After=sleep.target swap-on.service <--

[Service]
Type=oneshot
ExecStart=/lib/systemd/systemd-sleep hibernate

複製していますswap-on.service in Afterで、systemdが休止状態を開始することを確認しますafterスワップがオンであり、その逆ではありません。systemdがswap-on.serviceが失敗した場合は休止状態にしないでください。

systemctl hibernateを実行すると、systemdは変更されたsystemd-hibernate.serviceを実行します。これはswap-on.serviceを実行してスワップを有効にします。スワップが有効で、RequiredフィールドとAfterフィールドの両方が満たされると、systemdは最終的にシステムを休止状態にすることができます。

休止状態から再開した後にsystemdでスワップを無効にするには、swap-off.serviceという別のサービスファイルを作成する必要はありません。これはswap-on.serviceと同じことを行います。 =、「on」サービスと同じディレクトリ(/ etc/systemd/system /)に配置します。唯一の違いは、このサービスが実行されることですswaponの代わりにswapoff

[Unit]
Description=Disable swap partition

[Service]
Type=oneshot

#  again, change /dev/sda3 to your swap partition /dev file
ExecStart=/sbin/swapoff /dev/sda3 <--

次のステップは、同じ/ usr/lib/systemd/systemディレクトリにあるsystemd-hibernate-resume @ .serviceというサービスファイルを変更することです。

[Unit]
Description=Resume from hibernation using device %f
Documentation=man:[email protected](8)
DefaultDependencies=no
BindsTo=%i.device
Wants=local-fs-pre.target
After=%i.device
Before=local-fs-pre.target
ConditionPathExists=/etc/initrd-release

[Service]
Type=oneshot
ExecStart=/lib/systemd/systemd-hibernate-resume %f

Beforeフィールドを変更する必要があります。 local-fs-pre.targetの横にswap-off.serviceを追加します。

...
After=%i.device
Before=local-fs-pre.target swap-off.service <--
ConditionPathExists=/etc/initrd-release
...

これで、休止状態から再開すると、スワップイメージがメモリにロードされた後にsystemdが実行されますswap-off.service(実際には少し後でありますが、それは私たちにとって重要ではありません)

これは完全に理論的な解決策であり、まだ試していませんが、systemdについて知っていることに基づいて、これは機能するはずです。 UPowerはsystemdに休止状態を要求するので、説明したようにsystemd-hibernate.serviceを実行します。これはおそらくあなたが探しているものです。

2
yakrobat

私は「誰か」に同意します。スワップパーティションを使用するだけです。 hibernateを使用しているため、スワップファイルを使用できないと思います。ファイルはアクティブなファイルシステム上にある必要があり、ディスクからの再開時に問題が発生するためです。参照:
https://www.kernel.org/doc/Documentation/power/swsusp-and-swap-files.txt

モデル840がレンダリングやDVR)のようなかなりディスクを集中的に使用するアプリケーションで、何年にもわたって単一障害点なしでSamsung SSDを叩いてきました。私は常にドライブを交換して、速度や容量を長くしていますスワップを恐れないでください。スワップを100のように設定しない限り、カーネルは、真の必要性がない限り、ページをディスクに移動しないというかなり良い仕事をするはずです。

幸運を祈ります、G ^ 2

0
texasbubb