WSL2でzramを使う

目次

現在のWSL2のカーネル(ChatGPTによれば6.6系からと思われる)では、zramが使えるようになっている。WSL2ではsudo apt install systemd-zram-generatorだけでは動かないため、zramを有効にする方法をメモする。

環境

  • WSL2
    • カーネル 6.18.33.2-microsoft-standard-WSL2
    • Ubuntu 26.04 LTS

zramとは

RAM上に圧縮機能付きブロックデバイスを作成するカーネルモジュール。圧縮解凍のオーバーヘッドはあるものの、基本的にSSD・HDDより高速となる。圧縮RAMディスクとしても使えるが、ここではスワップとして使う。

WSL2でzramを有効にする手順

WSL2等のコンテナ環境でなければ、zram有効化の手順は一般的に以下のとおりである。

  1. sudo apt install systemd-zram-generatorを実行し、systemd-zram-generatorをインストールする
  2. /etc/systemd/zram-generator.confを編集し、zramデバイスのサイズ等を調整する
    • 存在しない場合は/usr/share/doc/systemd-zram-generator/zram-generator.conf.exampleからコピーして編集すればよい
  3. sudo systemctl daemon-reloadsudo systemctl start systemd-zram-setup@zram0を実行して有効化する
  4. zramctlを実行して、/dev/zram0が作成されていることを確認する
  5. swapon --showを実行して、/dev/zram0がスワップに設定されていることを確認する
  6. 再起動して、再度/dev/zram0がスワップに設定されていることを確認する

しかし、WSL2ではこれだけでは再起動(wsl.exe --shutdown後にUbuntuを起動)後に/dev/zram0が設定されず、スワップにも設定されない。これには以下の2つの原因がある。

  1. systemd-detect-virtでWSL2がコンテナ判定になるため、zram-generatorがsystemdユニットファイルを自動生成しない

    The generator does nothing if run inside a container (as determined by systemd-detect-virt(8) --container).

  2. zram-generatordev-zram0.swapを生成したとしても、コンテナ内では起動しない

    systemd now has an explicit notion of supported and unsupported unit types. Jobs enqueued for unsupported unit types will now fail with an "unsupported" error code. More specifically .swap, .automount and .device units are not supported in containers, .busname units are not supported on non-kdbus systems. .swap and .automount are also not supported if their respective kernel compile time options are disabled.

  3. [email protected]After=dev-%i.deviceによりdev-zram0.deviceの後に起動するが、/sys/block/zram0/comp_algorithmが存在しないため失敗する
    • dev-zram0.deviceがactiveになるタイミングと/sys/block/zram0/*が使えるようになるタイミングに若干ずれがある?

そのため、追加で以下の手順を行う。

  1. dev-zram0.serviceを手動で作成する。.swapではないので普通のサービスとして起動する。

     1$ sudo vi /etc/systemd/system/dev-zram0.service
     2$ sudo cat /etc/systemd/system/dev-zram0.service
     3[Unit]
     4Description=Compressed Swap on /dev/zram0
     5
     6Requires=[email protected]
     7After=[email protected]
     8Before=swap.target
     9
    10[Service]
    11Type=oneshot
    12RemainAfterExit=yes
    13ExecStart=/sbin/swapon --priority 100 /dev/zram0
    14ExecStop=/sbin/swapoff /dev/zram0
    15
    16[Install]
    17WantedBy=multi-user.target
    18$ sudo systemctl daemon-reload
    19$ sudo systemctl enable dev-zram0.service
    
  2. [email protected]を適当に修正する

     1$ sudo systemctl edit [email protected]
     2$ systemctl cat [email protected]
     3# /usr/lib/systemd/system/[email protected]
     4# SPDX-License-Identifier: MIT
     5# This file is part of the zram-generator project
     6# https://github.com/systemd/zram-generator
     7
     8[Unit]
     9Description=Create swap on /dev/%i
    10Documentation=man:zram-generator(8) man:zram-generator.conf(5)
    11After=dev-%i.device
    12DefaultDependencies=false
    13
    14[Service]
    15Type=oneshot
    16RemainAfterExit=yes
    17ExecStart=/usr/lib/systemd/system-generators/zram-generator --setup-device '%i'
    18ExecStop=/usr/lib/systemd/system-generators/zram-generator --reset-device '%i'
    19
    20# /etc/systemd/system/[email protected]/override.conf
    21[Service]
    22ExecStartPre=/bin/sh -c 'while ! [ -e /sys/block/%i/comp_algorithm ];do sleep 0.1;done'
    
  3. WSL2を再起動する

  4. スワップを確認する

    1$ zramctl;swapon --show
    2NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
    3/dev/zram0 lzo-rle       3.9G   4K   80B   12K         [SWAP]
    4NAME       TYPE      SIZE USED PRIO
    5/dev/sdc   partition   2G   0B   -2
    6/dev/zram0 partition 3.9G   0B  100
    

以上でWSL2でzramを有効化する手順は完了となる。

BuildKit上でsbuildを使いDebianパッケージをビルドする