4月から個人 PC を MacBook Air から Linux マシンに変えました。[2021-05-06-1]
スライド P41 に書いたとおり、たまにスリープから復帰しなくてつらいです。仕方がないので「スリープしない設定にする。常にAC電源ON🤗」という運用でカバー()をしていました。😭
いつまでも続けるわけにもいかないので、今回重い腰を上げてハイバネート出来るようにしました。
Linux (Xfce4) のスリープ方式
私が使っているウィンドウマネージャーは Xfce4 です。電源管理の設定等で出てくるスリープ関連の用語と、自分なりの理解は以下のとおりです。情報源は Wikipedia です。😆
- サスペンド
- メモリ以外の給電停止した状態。ACPI では S3 に相当する
- ハイバネート
- メモリの内容をストレージに移し電源断。ACPI では S4 に相当する
- ハイブリッドスリープ
- サスペンドとハイバネートの中間だと思われるが、試したらすぐハイバネートしただけだった…
macOS (Big Sur) のスリープ方式
macOS ではサスペンドやハイバネートの使い分けは不要で、意識するのは「スリープ」のみです。以下のような「セーフスリープ 」という機構を備えているそうです。
- スリープ状態になると、メモリの内容を保持したままストレージにも保存する
- スリープ中にバッテリーが切れていなければ、復帰時にメモリの内容を使う
- スリープ中にバッテリーが切れていたら、復帰時にストレージの内容を使う
奨励はされていませんが、pmset コマンドでスリープ方式を「セーフスリープ」から「スリープ」または「ディープスリープ」に変更は出来るようです。
「スリープ」は ACPI の S3 に相当し、「ディープスリープ」は S4 に相当するようなので、Xfce4 の「ハイブリッドスリープ」は「セーフスリープ」が本来の振る舞いなのかも。
※ 状態としての「スリープ」と、その種類としての「スリープ」(と「セーフスリープ」「ディープスリープ」)があるので、文章がややこしいです。
Linux と macOS の振る舞いの違い
macOS の素晴らしい点に、ユーザーにスリープをほぼ意識させない設計があると思います。
サスペンドやハイバネートのような用語が現れないこともさることながら、MacBook なら蓋を開けばログイン画面が表示されるだけです。多少復帰がもたつくことはあるのはご愛嬌。
Linux はサスペンドは同じとしても、ハイバネートは OS の起動から始まるので、「あれ?バッテリー切れてた?」と一瞬不安になります。Windows も同じという理解です。
どの OS もバックグラウンドの処理は同じだと思います。macOS はユーザーへの見せ方がきれいですね。
Manjaro でのハイバネート設定方法
「サスペンドとハイバネート - ArchWiki 」に従いました。以下の流れです。
- スワップファイルを作る
- 関連するカーネルパラメータを GRUB(ブートローダー)に追加する
- 関連するフックを initramfs に追加する
1. スワップファイルを作る
今回は /swapfile という 18GB のスワップファイルを作りました。
$ sudo fallocate -l 18G /swapfile
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
この VivoBook のメモリは 16GB です。RedHat の記事 に従い、スワップファイルのサイズは 18GB にしました。
無事作られました。
$ swapon -show
Filename Type Size Used Priority
/swapfile file 18874364 0 -2
永続化するために /etc/fstab に以下を追記しました。
/swapfile none swap defaults 0 0
ちなみに、今回のような任意サイズのファイルは dd でも作れます。ただ、dd は実際にファイル書き込みが発生するため、可能なら fallocate を使うほうが無駄がなくて良いと思います。
参考記事: Linuxでサイズ指定してダミーファイルを作成する方法 - conf t
2. 関連するカーネルパラメータを GRUB(ブートローダー)に追加する
/etc/default/grub を以下のように変更しました。/swapfile が、どのデバイスの、どの位置(オフセット)に存在するかを教えています。
--- /tmp/grub.orig 2021-08-25 01:12:57.415049508 +0900
+++ /etc/default/grub 2021-08-23 23:42:08.875333968 +0900
@@ -2,7 +2,7 @@
GRUB_TIMEOUT=5
GRUB_TIMEOUT_STYLE=hidden
GRUB_DISTRIBUTOR="Manjaro"
-GRUB_CMDLINE_LINUX_DEFAULT="quiet apparmor=1 security=apparmor udev.log_priority=3"
+GRUB_CMDLINE_LINUX_DEFAULT="quiet apparmor=1 security=apparmor udev.log_priority=3 resume=UUID=52d772c6-e49d-4be0-9963-c9aae2a9e4f9 resume_offset=52037632"
GRUB_CMDLINE_LINUX=""
# If you want to enable the save default function, uncomment the following
GRUB_CMDLINE_LINUX がユーザー用の変数かと思い、初めはこれを使ってしまいましたが、リカバリモード用でした(GNU GRUB Manual 2.06: Simple configuration )。
“resume=UUID=52d772c6-e49d-4be0-9963-c9aae2a9e4f9” で、/swapfile が置いてあるデバイスを教えています。
雑に調べると /dev/nvme0n1p5 です。/swapfile なので当たり前ですが、"/" がマウントポイントです。
$ df /swapfile
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/nvme0n1p5 527306168 62862840 437583404 13% /
“resume=/dev/nvme0n1p5” でも問題はないとは思いますが、外付けストレージの追加等で名前が変わるリスクはゼロではないため、UUID による永続的な命名方法を使いました。
各デバイスの UUID 確認方法は簡単です(永続的なブロックデバイスの命名 - ArchWiki )。
$ ls -alF /dev/disk/by-uuid
total 0
drwxr-xr-x 2 root root 100 8月 24 00:14 ./
drwxr-xr-x 8 root root 160 8月 24 00:14 ../
lrwxrwxrwx 1 root root 15 8月 24 00:14 2E80-83B2 -> ../../nvme0n1p1
lrwxrwxrwx 1 root root 15 8月 24 00:14 52d772c6-e49d-4be0-9963-c9aae2a9e4f9 -> ../../nvme0n1p5
lrwxrwxrwx 1 root root 15 8月 24 00:14 DA82730D8272ECFF -> ../../nvme0n1p4
“resume_offset=52037632” で、/swapfile が /dev/nvme0n1p5 の先頭からどの位置(オフセット)に存在するかを教えています。
filefrag というコマンドで分かるようです。
$ sudo filefrag -v /swapfile | head -n 5
Filesystem type is: ef53
File size of /swapfile is 19327352832 (4718592 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 52037632.. 52037632: 1:
1: 1.. 2047: 52037633.. 52039679: 2047: unwritten
ext4 はフラグメンテーションが起きづらいそうだけど、e4defrag で手動デフラグしたらオフセットは変わり得るのでは?と思いました。ちょっと怖いな。どうなんでしょう?
/etc/default/grub を変更したら /boot/grub/grub.cfg を再作成します。
$ sudo grub-mkconfig -o /boot/grub/grub.cfg
3. 関連するフックを initramfs に追加する
/etc/mkinitcpio.conf を以下のように変更しました。カーネル起動時に resume というモジュールがロードされるのかな。filesystems の前に追加するのがとても重要だそうです。
--- /tmp/mkinitcpio.conf.orig 2021-08-25 01:40:50.793227026 +0900
+++ /etc/mkinitcpio.conf 2021-08-23 23:07:04.396638336 +0900
@@ -49,7 +49,7 @@
#
## NOTE: If you have /usr on a separate partition, you MUST include the
# usr, fsck and shutdown hooks.
-HOOKS="base udev autodetect modconf block keyboard keymap filesystems fsck"
+HOOKS="base udev autodetect modconf block keyboard keymap resume filesystems fsck"
# COMPRESSION
# Use this to compress the initramfs image. By default, gzip compression
/etc/mkinitcpio.conf を変更したら /boot/initramfs-*.img を再作成します。
$ sudo mkinitcpio -p linux510
linux510 は /etc/mkinitcpio.d/ 以下のファイルと対応していました。今回は /etc/mkinitcpio.d/linux510.preset しかなかったので、linux510 になりました。
ちなみに mkinitcpio を引数なしで実行すると、dry run モードによる確認が出来ます。
$ sudo mkinitcpio
==> Starting dry run: 5.10.59-1-MANJARO
-> Running build hook: [base]
-> Running build hook: [udev]
-> Running build hook: [autodetect]
-> Running build hook: [modconf]
-> Running build hook: [block]
-> Running build hook: [keyboard]
-> Running build hook: [keymap]
-> Running build hook: [resume]
-> Running build hook: [filesystems]
-> Running build hook: [fsck]
==> Generating module dependencies
==> Dry run complete, use -g IMAGE to generate a real image
注意点
GRUB や Linux カーネルが更新されたら、2 や 3 の再設定が必要みたいです。面倒なので私は mitamae でゆるふわ構成管理しています。
まとめ
ハイバネート出来た時は、思わずおぉー!と声が出ました。他の OS では当たり前すぎるハイバネートですが、自分で設定すると感慨深いものがあります。
これで VivoBook から気軽に AC 電源コードを抜けるようになりました。なんと当たり前な…。今までは気がつくと電源が落ちていたので、AC 電源コードも気も抜けませんでした。😭
サスペンドは復帰時に画面が表示されず、電源ボタンを長押しするしかなくなることがあるので、まだ使えていません。
前述の「サスペンドとハイバネート - ArchWiki 」によると、この現象は多数報告されているそうです。そして、そのデバッグのベストプラクティスがこの記事 とのこと。
長いので気が向いたら調べます。たぶん、Linux カーネルと ATI のドライバの相性()が悪いのだと思います。
他の参考記事
🔗 Arch Linux 快適デスクトップ環境の構築 2019 - Qiita
🔗 Linux におけるラップトップマシン向け電力管理スイートの紹介(Pm-utils, Laptop-mode-tools, Powertop, TLP) – 怠惰の形而上学
初めからインストールされていた TLP があればサスペンド(スリープ)は問題なく管理されているそう。Laptop-mode-tools はもう古いそう。なのにサスペンドだけだと数時間しかバッテリーがもたないのは、推して知るべし…。