Ubuntu 19.
なぜZFSをデスクトップに?
Ubuntu Weekly Topicsの2019年8月9日号でも紹介しているように、
ZFSそのものはUbuntu 15.
- GRUBからZFSなルートファイルシステムを簡単に選択できるようにする
[2] - LinuxカーネルのパッケージにZFSのカーネルモジュールを同梱する
[3] - インストーラー
(Ubiquity) でZFSなルートファイルシステムを作成できるようにする
これらの対応により、
UbuntuとZFSの関係やライセンスに関する話は、
ZFSは非常にメモリを使うファイルシステムです。ZFS on LinuxのFAQにも
最近ではPC用途でも8GB以上のメモリは一般的になったものの、
よってデスクトップやノートPCで
とにもかくにも食わず嫌いは良くありません。今回は実際にZFSを使っていろいろ試してみることにします。あらかじめ仮想マシンか何かに、

インストール直後の状態確認
まずはインストール直後の状態を確認してみましょう。最初にパーティションレイアウトを見てみます。
$ sudo parted /dev/vda unit MiB print モデル: Virtio Block Device (virtblk) ディスク /dev/vda: 20480MiB セクタサイズ (論理/物理): 512B/512B パーティションテーブル: gpt ディスクフラグ: 番号 開始 終了 サイズ ファイルシステム 名前 フラグ 1 1.00MiB 513MiB 512MiB fat32 EFI System Partition boot, esp 2 513MiB 563MiB 50.0MiB ext4 3 563MiB 1486MiB 923MiB linux-swap(v1) 4 1486MiB 3534MiB 2048MiB zfs 5 3534MiB 20480MiB 16946MiB zfs
最初のパーティションはEFI System Partition
第2パーティションはGRUBの設定ファイルやモジュール類をインストールする領域です。GRUB自体はinsmod zfs
」
ただしこれはESPと分離する意味があまりないため、
第3パーティションは見てのとおりスワップパーティションです。Ubuntuは17.
第4パーティションと第5パーティションがZFS用のパーティションです。前者が起動カーネルなどを保存する
ちなみにリリースノートで指摘されていたインストーラーがストレージをフォーマットする際にZFSがなくext4だけ表示される問題は、

ZFSパーティションのレイアウトを計算するのは、
Ubuntu 20.
次に/etc/
」
$ cat /etc/fstab # /etc/fstab: static file system information. # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # # <file system> <mount point> <type> <options> <dump> <pass> # /boot/efi was on /dev/vda1 during installation UUID=8977-6786 /boot/efi vfat umask=0077 0 1 UUID=0a9b50b8-7a66-4ae1-8a7d-35796345aca0 /boot/grub ext4 errors=remount-ro 0 1 UUID=892fa4dc-22ef-49fa-9340-2676ce19cbd7 none swap discard 0 0
あれ、
ストレージプールのレイアウト
それでは今度は実際にZFSの情報を表示してみましょう。最初にZFSには
ストレージプールはいわゆるボリューム管理のような機能です。複数のストレージデバイス・
ストレージプールの操作はzpoolコマンドで行います。
$ zpool list NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT bpool 1.88G 159M 1.72G - - - 8% 1.00x ONLINE - rpool 16.5G 3.98G 12.5G - - 5% 24% 1.00x ONLINE -
先ほども説明したように、zpool status
コマンドで確認できます。
$ zpool status pool: bpool state: ONLINE status: The pool is formatted using a legacy on-disk format. The pool can still be used, but some features are unavailable. action: Upgrade the pool using 'zpool upgrade'. Once this is done, the pool will no longer be accessible on software that does not support feature flags. scan: none requested config: NAME STATE READ WRITE CKSUM bpool ONLINE 0 0 0 vda4 ONLINE 0 0 0 errors: No known data errors pool: rpool state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM rpool ONLINE 0 0 0 vda5 ONLINE 0 0 0 errors: No known data errors
『Software Design 2019年12月号』
そこでbpoolについてはより保守的な使い方であることを明示するために、zpool get all
」
$ zpool get all | grep version bpool version 28 local rpool version - default
よってbpoolについては、
ちなみにUbuntu 20.
データセットのレイアウト
ストレージプールは論理ボリュームのようなものです。ここから実際に読み書きできる領域として切り出したものが
ファイルシステムはその名の通りファイルシステムです。実際にファイルシステムのどこかにマウントされ、
ファイルシステムやボリュームは、
Ubuntuインストール直後に使われているデータセットはファイルシステムだけです。データセットのリストはzfs list
コマンドで確認できます。
$ zfs list NAME USED AVAIL REFER MOUNTPOINT bpool 159M 1.59G 176K /boot bpool/BOOT 158M 1.59G 176K none bpool/BOOT/ubuntu_08z65m 158M 1.59G 158M /boot rpool 3.98G 12.0G 96K / rpool/ROOT 3.98G 12.0G 96K none rpool/ROOT/ubuntu_08z65m 3.98G 12.0G 3.49G / rpool/ROOT/ubuntu_08z65m/srv 96K 12.0G 96K /srv rpool/ROOT/ubuntu_08z65m/usr 200K 12.0G 96K /usr rpool/ROOT/ubuntu_08z65m/usr/local 104K 12.0G 104K /usr/local rpool/ROOT/ubuntu_08z65m/var 495M 12.0G 96K /var rpool/ROOT/ubuntu_08z65m/var/games 96K 12.0G 96K /var/games rpool/ROOT/ubuntu_08z65m/var/lib 492M 12.0G 379M /var/lib rpool/ROOT/ubuntu_08z65m/var/lib/AccountServices 96K 12.0G 96K /var/lib/AccountServices rpool/ROOT/ubuntu_08z65m/var/lib/NetworkManager 128K 12.0G 128K /var/lib/NetworkManager rpool/ROOT/ubuntu_08z65m/var/lib/apt 77.5M 12.0G 77.5M /var/lib/apt rpool/ROOT/ubuntu_08z65m/var/lib/dpkg 35.6M 12.0G 35.6M /var/lib/dpkg rpool/ROOT/ubuntu_08z65m/var/log 1.96M 12.0G 1.96M /var/log rpool/ROOT/ubuntu_08z65m/var/mail 96K 12.0G 96K /var/mail rpool/ROOT/ubuntu_08z65m/var/snap 112K 12.0G 112K /var/snap rpool/ROOT/ubuntu_08z65m/var/spool 112K 12.0G 112K /var/spool rpool/ROOT/ubuntu_08z65m/var/www 96K 12.0G 96K /var/www rpool/USERDATA 3.44M 12.0G 96K / rpool/USERDATA/root_e8xd45 112K 12.0G 112K /root rpool/USERDATA/shibata_e8xd45 3.24M 12.0G 3.24M /home/shibata
多いですね。Ubuntuでは大雑把な重要度と用途に合わせてデータセットを分けているようです。データセットの名前はubuntu_
」root_
」shibata_
」
注目すべきは
つまりZFSは/etc/
にルートファイルシステムを明示的に書かなくても、
ちなみにGRUBは、
$ cat /proc/cmdline BOOT_IMAGE=/BOOT/ubuntu_08z65m@/vmlinuz-5.3.0-23-generic root=ZFS=rpool/ROOT/ubuntu_08z65m ro quiet splash vt.handoff=1
上記のroot=
」
GRUBのデータセットの指定方法は、update-grub
実行時にzfsコマンドを駆使して行います。詳細は/etc/
」
スナップショットとロールバック
ZFSの便利な機能のひとつが
たとえばUbuntuのインストール直後はアップグレードが必要なパッケージがたくさん溜まっていますよね。アップグレード前にスナップショットを取って、
$ apt list --upgradable (中略) uno-libs3/eoan-updates 6.3.3-0ubuntu0.19.10.1 amd64 [6.3.2-0ubuntu2 からアップグレード可] ure/eoan-updates 6.3.3-0ubuntu0.19.10.1 amd64 [6.3.2-0ubuntu2 からアップグレード可] whoopsie/eoan-updates,eoan-security 0.2.66ubuntu0.3 amd64 [0.2.66 からアップグレード可] zfs-zed/eoan-updates 0.8.1-1ubuntu14.1 amd64 [0.8.1-1ubuntu14 からアップグレード可]
スナップショットはzfs snapshot データセット名@スナップショット名
」
$ sudo zfs snapshot -r rpool@`date +%Y%m%d%H%M%S`
上記のように-r
」
作成されたスナップショットはzfs list
コマンドに-t snapshot
」
$ zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT rpool@20191130232337 0B - 96K - rpool/ROOT@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m@20191130232337 0B - 3.49G - rpool/ROOT/ubuntu_08z65m/srv@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/usr@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/usr/local@20191130232337 0B - 104K - rpool/ROOT/ubuntu_08z65m/var@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/games@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/lib@20191130232337 0B - 379M - rpool/ROOT/ubuntu_08z65m/var/lib/AccountServices@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/lib/NetworkManager@20191130232337 0B - 136K - rpool/ROOT/ubuntu_08z65m/var/lib/apt@20191130232337 0B - 77.5M - rpool/ROOT/ubuntu_08z65m/var/lib/dpkg@20191130232337 0B - 35.6M - rpool/ROOT/ubuntu_08z65m/var/log@20191130232337 692K - 2.07M - rpool/ROOT/ubuntu_08z65m/var/mail@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/snap@20191130232337 0B - 112K - rpool/ROOT/ubuntu_08z65m/var/spool@20191130232337 0B - 112K - rpool/ROOT/ubuntu_08z65m/var/www@20191130232337 0B - 96K - rpool/USERDATA@20191130232337 0B - 96K - rpool/USERDATA/root_e8xd45@20191130232337 0B - 112K - rpool/USERDATA/shibata_e8xd45@20191130232337 0B - 3.50M -
USEDがほぼ0Bになっていますね。ZFSはデータセット単位のCopy-on-Writeに対応しているので
アップグレード前のスナップショットを取得したので、
$ sudo apt full-upgrade -y $ apt list --upgradable 一覧表示... 完了
無事にアップグレードが完了しましたね。この状態でスナップショットを表示してみましょう。
$ zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT rpool@20191130232337 0B - 96K - rpool/ROOT@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m@20191130232337 753M - 3.49G - rpool/ROOT/ubuntu_08z65m/srv@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/usr@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/usr/local@20191130232337 56K - 104K - rpool/ROOT/ubuntu_08z65m/var@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/games@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/lib@20191130232337 21.2M - 379M - rpool/ROOT/ubuntu_08z65m/var/lib/AccountServices@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/lib/NetworkManager@20191130232337 100K - 136K - rpool/ROOT/ubuntu_08z65m/var/lib/apt@20191130232337 516K - 77.5M - rpool/ROOT/ubuntu_08z65m/var/lib/dpkg@20191130232337 8.36M - 35.6M - rpool/ROOT/ubuntu_08z65m/var/log@20191130232337 1.01M - 2.07M - rpool/ROOT/ubuntu_08z65m/var/mail@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/snap@20191130232337 72K - 112K - rpool/ROOT/ubuntu_08z65m/var/spool@20191130232337 64K - 112K - rpool/ROOT/ubuntu_08z65m/var/www@20191130232337 0B - 96K - rpool/USERDATA@20191130232337 0B - 96K - rpool/USERDATA/root_e8xd45@20191130232337 0B - 112K - rpool/USERDATA/shibata_e8xd45@20191130232337 988K - 3.50M -
主にルートディレクトリのデータセット
スナップショット同士、
$ sudo zfs diff rpool/ROOT/ubuntu_08z65m@20191130232337 rpool/ROOT/ubuntu_08z65m M /etc M /etc/apparmor.d M /etc/apport M /etc/bash_completion.d M /etc/cron.daily M /etc/default M /tmp M /var/cache/apt M /var/cache/apt/archives/partial M /etc/firefox (後略)
今回は多くのパッケージがアップグレードされてしまったため、
次にアップグレード前、
$ for i in `zfs list -t snapshot | grep 20191130232337 | awk '{print $1}'`; do sudo zfs rollback -r -R -f $i; done
zfs rollback
に付加しているオプションはそれぞれ次のような意味になります。
- 「
-r
」:指定したスナップショットより新しいスナップショットとブックマークを削除する - 「
-R
」:指定したスナップショットより新しいスナップショットとブックマークとそれらのクローンを削除する - 「
-f
」:クローンされたデータセットがマウントされていたら、削除する前にアンマウントする
zfs rollback
は-r
」
zfs clone
コマンドを使うと、-R
」
ロールバックが成功したら、
$ zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT rpool@20191130232337 0B - 96K - rpool/ROOT@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m@20191130232337 8K - 3.49G - rpool/ROOT/ubuntu_08z65m/srv@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/usr@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/usr/local@20191130232337 0B - 104K - rpool/ROOT/ubuntu_08z65m/var@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/games@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/lib@20191130232337 8K - 379M - rpool/ROOT/ubuntu_08z65m/var/lib/AccountServices@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/lib/NetworkManager@20191130232337 8K - 136K - rpool/ROOT/ubuntu_08z65m/var/lib/apt@20191130232337 0B - 77.5M - rpool/ROOT/ubuntu_08z65m/var/lib/dpkg@20191130232337 8K - 35.6M - rpool/ROOT/ubuntu_08z65m/var/log@20191130232337 80K - 2.07M - rpool/ROOT/ubuntu_08z65m/var/mail@20191130232337 0B - 96K - rpool/ROOT/ubuntu_08z65m/var/snap@20191130232337 0B - 112K - rpool/ROOT/ubuntu_08z65m/var/spool@20191130232337 0B - 112K - rpool/ROOT/ubuntu_08z65m/var/www@20191130232337 0B - 96K - rpool/USERDATA@20191130232337 0B - 96K - rpool/USERDATA/root_e8xd45@20191130232337 0B - 112K - rpool/USERDATA/shibata_e8xd45@20191130232337 8K - 3.50M -
USEDがスナップショット前と同じくらいに減っている、
さらにapt list
コマンドを実行すると、
$ apt list --upgradable (中略) uno-libs3/eoan-updates 6.3.3-0ubuntu0.19.10.1 amd64 [6.3.2-0ubuntu2 からアップグレード可] ure/eoan-updates 6.3.3-0ubuntu0.19.10.1 amd64 [6.3.2-0ubuntu2 からアップグレード可] whoopsie/eoan-updates,eoan-security 0.2.66ubuntu0.3 amd64 [0.2.66 からアップグレード可] zfs-zed/eoan-updates 0.8.1-1ubuntu14.1 amd64 [0.8.1-1ubuntu14 からアップグレード可]
今回はシステム全体をロールバックしましたが、
zsnapdパッケージとして提供されている
バックアップとリストア
一般ユーザーにおけるZFSのもうひとつの利点が、zfs send
コマンドでホームディレクトリのデータセットのバックアップを取ってみましょう。なお、zfs send
の対象はスナップショットかマウントされていないデータセットとなりますので、
$ echo "backuped data" > ~/backup.dat $ zfs snapshot rpool/USERDATA/shibata_e8xd45@backup1 $ sudo zfs send rpool/USERDATA/shibata_e8xd45@backup1 > /var/tmp/home_backup.bin $ ls -lh /var/tmp/home_backup.bin -rw-rw-r-- 1 shibata shibata 13M 12月 1 23:21 /var/tmp/home_backup.bin
zfs send
はバイナリストリームを出力しますので、| gzip -c > backup.
」
バックアップデータができたので、zfs recv
コマンドでリストアしましょう。今回は単純に
$ sudo zfs recv rpool/USERDATA/shibata_backup1 < /var/tmp/home_backup.bin $ zfs list rpool/USERDATA/shibata_backup1 NAME USED AVAIL REFER MOUNTPOINT rpool/USERDATA/shibata_backup1 3.59M 11.1G 3.52M /shibata_backup1 $ cat /shibata_backup1/backup.dat backuped data $ sudo zfs destroy -r rpool/USERDATA/shibata_backup1
リストアしたデータセットは自動的にセットされたマウントポイントにマウントされます。ここから先は個々のバックアップポリシーに依存しますが、zfs destroy
で削除できます。ただし、-r
」
zfs recv
は標準入力からバイナリストリームを受け取ってそれをリストアしています
よくあるのは、
$ sudo zfs send rpool/USERDATA/shibata_e8xd45@backup1 | \ ssh foo.local sudo zfs recv rpool/USERDATA/shibata_backup
自動化するならスナップショット・
たとえばあらかじめ次のようなコマンドで、
$ sudo zfs set quota=20G prpool/USERDATA/shibata_e8xd45
前項でも取り上げたzsnapdパッケージとして提供されている
ZFSのメモリの使用量
ZFSを使う上で気になるのがメモリの使用量です。ZFSはprocfsやsysfs経由で数多くの情報を提供し、
そこでざっくりと情報を把握するのに便利なのがarc_
コマンドです。早速使ってみましょう。zfsutils-linuxパッケージに含まれているので、
$ arc_summary -g ARC: 922.5 MiB (46.9 %) MFU: 415.3 MiB MRU: 453.8 MiB META: 133.6 MiB (1.4 GiB) DNODE 20.0 MiB (147.5 MiB) +----------------------------------------------------------+ |FFFFFFFFFFFFRRRRRRRRRRRRRO | +----------------------------------------------------------+
ARC
ARCの最大サイズは環境にも依存しますが、
$ arc_summary | grep L2ARC L2ARC not detected, skipping section
なんらかの理由でARCの最大サイズを変更したい場合は、
$ echo 'options zfs zfs_arc_max=1073741824' | sudo tee /etc/modprobe.d/zfs.conf $ sudo update-initramfs -u -k all
この方法は他のモジュールパラメーターにも有効です。