NixOSにハイバネーションを設定する

ハイバネーションとは?

ハイバネーションとは、サスペンド(スリープ)とシャットダウンとの間のような状態です。

サスペンドでは、基本的には現在のメモリの状態を保持するための電力の供給だけを行い、それ以外の部分は電源をオフにします。 そのため、少量とはいえ電力を消費します。

一方ハイバネーションは、現在のメモリの状態をディスク上のスワップ領域に退避させるので、完全に電源をオフにすることができます。 そのため、ラップトップのようなモバイルマシンではバッテリーを節約できる点で有利です。

NixOSで設定するには?

ハイバネーションを設定するには退避するためのスワップ領域を作成する必要があります。 待避するためのスワップ領域は、ディスク上のスワップパーティション(直接でもLVM上でも)、スワップファイルのどちらでも可能です。

筆者は、スワップファイルによる方法で以下のように設定しました。

1
2
3
4
5
6
7
# Swap file
swapDevices = [
  {
    device = "/var/lib/swapfile";
    size = 32 * 1024; # 32 GB
  }
];

スワップファイルのオフセットを調べる

スワップ領域がパーティションな場合では、待避先を指定するboot.resumeDeviceにそのパーティションを/dev/disk/by-uuid/<UUID>で指定します。 一方、スワップファイルを選択した場合では、boot.resumeDeviceにはあくまでもスワップファイルの存在するディスクパーティションを指定し、 そのスワップファイルが物理的なディスク中のどのブロックを指しているのかをオフセットで指定する必要があります。

今回のケースでは、スワップファイルを使用するので、オフセットを以下のコマンドで調べました。

1
2
3
4
5
6
7
8
sudo filefrag -v /var/lib/swapfile
Filesystem type is: ef53
File size of /var/lib/swapfile is 34359738368 (8388608 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..   45055:     409600..    454655:  45056:
   1:    45056..  110591:     458752..    524287:  65536:     454656:
   2:   110592..  335871:     593920..    819199: 225280:     524288:
...

必要な値は、物理的なディスク上でスワップファイルに対応するブロックの初まりの値なので、この結果からはext:が0でphysical_offsetの頭の値である409600をオフセットとしてメモしておきます。

設定する

元の設定aki-ph-chem/nix(まだ、ハイバネートの設定がされていない状態のコミット)に以下のように設定を追加しました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
diff --git a/hosts/nixosSwayLaptop/hardware-configuration.nix b/hosts/nixosSwayLaptop/hardware-configuration.nix
index b1fbfff..7ceb0e6 100644
--- a/hosts/nixosSwayLaptop/hardware-configuration.nix
+++ b/hosts/nixosSwayLaptop/hardware-configuration.nix
@@ -25,6 +25,11 @@
   boot.kernelModules = [ "kvm-intel" ];
   boot.extraModulePackages = [ ];
 
+  # for Hibernation
+  boot.kernelParams = [ "resume_offset=409600" ]; # スワップファイルの'/'中でのオフセット
+  boot.resumeDevice = "/dev/disk/by-uuid/66a368d1-3b3d-49fe-b6eb-f3c73f35ce22"; # パーティション '/'をUUIDで指定
+  powerManagement.enable = true;
+
   fileSystems."/" = {
     device = "/dev/disk/by-uuid/66a368d1-3b3d-49fe-b6eb-f3c73f35ce22";
     fsType = "ext4";

この設定では、boot.resumeDeviceで待避先のパーティションとして/を指定して、boot.kernelParamsでスワップファイルのオフセットを設定しています。

最後に設定を適用して再起動します。

1
2
sudo nixos-rebuild switch --flake .#nixosSwayLaptop --impure
reboot

suspendを実行して成功すればokです。

1
systemctl hibernate 

使用してみて

基本的にはハイバーネーションには成功して、復帰も正常に行われます。 しかし、まあまあな頻度で復帰時にカーネルパニックが起ってフリーズしてしまう問題を解決できていないので、使用は控えています。

CC BY
Hugo で構築されています。
テーマ StackJimmy によって設計されています。