🗄

ZFS(on Mac)にTimeMachineバックアップを取れるようにしてみた

2022/01/25に公開
3

ZFSの勉強がてら色々いじっているのですが、MacでZFSを組んで、ZFS上にTimeMachineバックアップが取れるようになったので共有しておこうと思います。

概要

前提

  • Macにディスクが直で接続されていること
  • Macにhomebrewがインストール済み

実施環境

  • Macbook Air 2019
    • Corei5 デュアルコア/ RAM: 8GB
    • OS: Catalina
  • HDD 4枚
    • TOSHIBA MQ01ABD100: 2.5インチ 1TBx4

今回の構成について

4枚のディスクでRAID10(RAID 1 + 0)を構築します。一度に2枚のディスクへの書き込みを行うため高速かつ、ミラーリングも行っているため安全性が高く、ディスク4枚の小規模環境では持ちられやすい構成です。

RAID-Zをもちいれば更に容量効率は良くなりますが、今回は触れないことにします。

設定方法

アプリケーションの用意

gdiskをインストールしておきます。

brew install gptfdisk

openzfsは公式がMac向けにパッケージを出してくれているので、対応するOSのpkgをダウンロードしましょう。
https://openzfsonosx.org/wiki/Downloads
今回はOpenZFSonOsX-2.1.0-Catalina-10.15.pkgをインストールしました。
インストール後はOSを再起動してください。

ディスクの作成

ディスクユーティリティを開き、どのボリュームに何が刺さっているかなどを確認します。


ディスクが確認できたらパーティションをクリアしていきます。gdiskコマンドを用いて以下のようになるように切ってください。

~ % sudo gdisk /dev/disk2 ## <------- 上記で確認した 装置 に該当
GPT fdisk (gdisk) version 1.0.8

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): p
Disk /dev/disk2: 1953525168 sectors, 931.5 GiB
Sector size (logical): 512 bytes
Disk identifier (GUID): 6A4194BA-B14D-4C89-87CE-D0A33DEA11C2
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 1953525134
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048      1953525134   931.5 GiB   8300  Linux filesystem

注意点としては、MacのデフォルトではCurrent type is AF00 (Apple HFS/HFS+)となっていて、OpenZFSではHFS上でzfs poolを作れないので、Linux filesystemにするのを忘れずに。

パーティションを切っている最中、セットしたディスクは、このコンピュータで読み取れないディスクでしたと表示されますが、無視をクリックして閉じてください。

利用するディスクのパーティションをすべて作成したら、領域名をメモしておきましょう。領域名はディスクユーティリティにかかれている他、以下のコマンドでもある程度絞り込めます。

ls -1 /dev/ | grep ^disk

筆者の環境ではdisk2s1disk3s1disk5s1disk6s1が該当するので、この体で勧めていきます。

zpoolの作成

zfsらしくプールを作成します。私の環境ではHDDとリーダが4096セクタに対応しているためashiftを変更しています。古い機器の場合は-o ashift=12は取り除いてください。

sudo zpool create -o ashift=12 maczfs mirror /dev/disk2s1 /dev/disk3s1

上記を実行すると以下のようにRAIDが構成されます。

~ % zpool status
  pool: maczfs
 state: ONLINE
config:

	NAME         STATE     READ WRITE CKSUM
	maczfs       ONLINE       0     0     0
	  mirror-0   ONLINE       0     0     0
	    disk2s1  ONLINE       0     0     0
	    disk3s1  ONLINE       0     0     0

errors: No known data errors

もちろんきちんとディスクユーティリティにも反映されます。ただし仮想的なボリュームのため、このディスクをフォーマットしたりはできません。

mirrorの追加

zpoolにさらにミラーディスクを追加していきます。

sudo zpool add maczfs mirror /dev/disk5s1 /dev/disk6s1

かなりにぎやかになりました。zpool listを入力すると、現在のプールの容量などがわかります。

~ % zpool status
  pool: maczfs
 state: ONLINE
config:

	NAME         STATE     READ WRITE CKSUM
	maczfs       ONLINE       0     0     0
	  mirror-0   ONLINE       0     0     0
	    disk2s1  ONLINE       0     0     0
	    disk3s1  ONLINE       0     0     0
	  mirror-1   ONLINE       0     0     0
	    disk5s1  ONLINE       0     0     0
	    disk6s1  ONLINE       0     0     0

errors: No known data errors
~ % zpool list
NAME     SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
maczfs  1.81T  3.21M  1.81T        -         -     0%     0%  1.00x    ONLINE  -

TimeMachine用のパーティションの切り出し

必要であればTimeMachineのバックアップを配置するためのパーティションをpool内に切り出します。
Sparsebundleにより容量は切り出しが行われますが、ZFS上で管理したい場合は実施します。

sudo zfs create -o compression=lz4 -o atime=off -o acltype=posixacl maczfs/tmdisk
sudo zfs set quota=1T maczfs/tmdisk

zfs listですべてのpoolのパーティションを確認できます。AVAIL列を見るとmaczfs/tmdiskは1TBが上限として設定されたことが確認できます。

~ % zfs list
NAME            USED  AVAIL     REFER  MOUNTPOINT
maczfs         5.05M  1.76T     2.68M  /Volumes/maczfs
maczfs/tmdisk  1.86M  1024G     1.86M  /Volumes/maczfs/tmdisk

Sparsebundleの作成

TimeMachineのバックアップを保存する仮想ディスクとなる.sparsebundleファイルを作成します。
/Volumes/maczfs/....の部分にSparsebundleファイルが保存されます。$(scutil --get LocalHostName)はPC名が設定されますが、特に指定は無いです。

-volnameで指定した名前がTimeMachineのGUIに表示されます。また、ここで-sizeを設定するとTimeMachineバックアップに上限を設けることができます。

sudo hdiutil create -size 1024g -library SPUD -fs JHFSX -type SPARSEBUNDLE -volname "TMzfs" /Volumes/maczfs/tmdisk/$(scutil --get LocalHostName).sparsebundle
sudo chmod -R 777 /Volumes/maczfs/tmdisk/$(scutil --get LocalHostName).sparsebundle

sparsebundleの拡張子のファイルが作成されており、全ユーザが読み書きできる状態になっていればOKです。

~ % ls -la /Volumes/maczfs/tmdisk
total 3446
drwxr-xr-x@ 5 root  wheel        6  1 25 00:46 ./
drwxr-xr-x@ 6 root  wheel        7  1 25 00:35 ../
drwx------  3 root  wheel        4  1 25 00:35 .Spotlight-V100/
-rw-r--r--  1 root  wheel  1753264  1 25 00:35 .VolumeIcon.icns
drwx------  2 root  wheel        3  1 25 00:35 .fseventsd/
drwxrwxrwx@ 3 root  wheel        6  1 25 00:46 Nekobook.sparsebundle/

TimeMachineにディスクを設定

作成したSparsebundleをシステムにマウントし、TimeMachineに設定します。

hdiutil attach /Volumes/maczfs/tmdisk/Nekobook.sparsebundle
sudo tmutil setdestination -p /Volumes/TMzfs
~ % hdiutil attach /Volumes/maczfs/tmdisk/Nekobook.sparsebundle
/dev/disk8          	GUID_partition_scheme
/dev/disk8s1        	EFI
/dev/disk8s2        	Apple_HFS                      	/Volumes/TMzfs

tmutilがエラーなく実行できると、TimeMachineバックアップが作成可能になります。

自動マウントを設定

Sparsebundleを常にマウントしておくために、定期的にマウントの操作を行う必要があります。
Linuxではcronを用いますが、MacではLaunchedを用いるのが一般的なようです。

Launchedの設定ファイルを以下のサイトを用いて作成しました。
https://zerolaunched.herokuapp.com/

launched.tmzfs_automount.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>launched.tmzfs_automount</string>
	<key>ProgramArguments</key>
	<array>
		<string>sh</string>
		<string>-c</string>
		<string>if [[ ! -d /Volumes/TMzfs ]];then hdiutil attach /Volumes/maczfs/tmdisk/Nekobook.sparsebundle;fi</string>
	</array>
	<key>StartCalendarInterval</key>
	<array>
		<dict>
			<key>Minute</key>
			<integer>0</integer>
		</dict>
		<dict>
			<key>Minute</key>
			<integer>20</integer>
		</dict>
		<dict>
			<key>Minute</key>
			<integer>40</integer>
		</dict>
	</array>
	<key>UserName</key>
	<string>root</string>
</dict>
</plist>

上記をrootユーザが実行するLaunched格納ディレクトリに保存すれば完了です。

cd /Library/LaunchDaemons
sudo cp ~/launched.tmzfs_automount.plist ./
sudo launchctl load -w ./launched.tmzfs_automount.plist

Launchctlでもきちんと読み込めていることが確認できます。

LaunchDaemons % sudo launchctl list | grep launched.tmzfs_automount
-	0	launched.tmzfs_automount

システム起動時の設定

Linux同様にMacにも、OS起動の再に接続されているZFSを、自動的にマウントする機能がありますが、Macのセキュリティに引っかかって動作しないため、一部のセキュリティを解除します。

フルディスクアクセスzpoolを追加し、チェックを付けます。リストにない場合はリストの下の「+」ボタンから/usr/local/zfs/bin/にいるzpoolを追加します。

これで再起動しても自動的にZFSがマウントされます。

設定手順の問題点

読み込めないディスクだというエラーは毎回起動のたびに出てきてしまうのでうざいです。

Linux filesystemではない切り方であれば回避できるでしょうか。起動のときだけではあるものの、気になります。

終わりに

もともとThunderbay4はRaspberryPiのZFSストレージとして利用しようと思っていたのですが、Thunderbolt3では無いためか、認識すらせず、Macに直接つなごうという発想になりました。
ソフトウェアRAIDなのでちょっとAirのスペックでは心配ですが、このような方法でもTimeMachineバックアップを取ることができるよという内容でした。

ちなみに復旧のときは、MacにZFSが入っていれば良いのですが、入っていない場合そのままでは復旧できないので(他PCでzpool importしたり、sparsebundlesmbなどで共有してあげる必要がありそうです。

storageノード用のWindowsサーバも買ったほうがいいかな...

参考

https://github.com/jollyjinx/ZFS-TimeMachine
https://openzfsonosx.org/wiki/FAQ#Q.29_Auto-import_fails_after_Catalina.3F
まだCatalinaだけど、Big surにアップデートしたらお世話になるかも
https://blog.goo.ne.jp/tsunanoa/e/34d5b36ead20f3c7468f9e97d88ca5f1

GitHubで編集を提案

Discussion

坦々狸坦々狸

storageノード用のWindowsサーバはOS代が結構な出費になりますね

最近は安価なコンパクトPCでも結構なスペック載ってるのでそういうのにTrueNAS等NAS用のディストリ入れて
Thunderbay4をZFSで管理するのはそいつに任せるのが安く済みそう🙄

タイムマシンしたい機器が1台なんだったらそいつをiSCSSiでマウントするようにすればsambaより早いと思いますし

ねこのねこの

うぉぉコメントありがとうございます!
そうなんですよね...なのでちょっと探しているのですが、Thuderbolt 3ポートが付いていて安価なミニPCが見つからない...みんなただのType C...難儀...

坦々狸坦々狸

あー確かにThunderbolt搭載で絞ると5〜7万位のボリュームゾーンになるんですね
この価格だと逆にQNAPあたりのNAS買ってディスク載せ替えたほうがスペース的にも使い勝手的にも良さそう😅