ZFS/FreeBSD上でTimeMachineを動かそうとして七転八倒した過程
でわかったことを、メモとしてまとめておく。
設定等は以下のページにまとめた。
なおこの知見は公開情報とMacのログからの推測である。当然一切の保証等は存在しない。参考にされる場合は、Your own riskでお願いする。
調査環境
- Server:
- OS: FreeBSD 12.2-RELEASE-p11
- samba: 4.13.14 (ports)
- Client 1: MacBook (Intel Core m7 Early 2016)
- OS:
- (内蔵SSD)Mojave(10.14.6)
- (予定:外部SSD)Catalina(10.l5)
- OS:
- Client 2: MacBook Pro(M1Max 14inch 2021)
- OS: Monterey (12.1)
- Client 3: MacBook Air (M1 2020)
- OS: Big Sur (11.6.2)
TimeMachineの動作
samba側
-
1. sambaは起動時に
smb4.conf
を調べ、fruit:time machine = yes
のボリュームがあればそれをmDNS(avahi, mDNSResponder)に登録する。 - 2. TimeMachine用ボリュームを公開する。動作は普通のSMBボリュームと同一であり、特別扱いはしない。
Mac側
- 1. MacはmDNS情報より、sambaが公開しているTimeMachineボリュームを知る。
- 2. Macはsambaが公開しているTimeMachineボリュームをマウントする。このボリュームを本稿ではrawボリュームと呼ぶ。rawボリュームのpathはMac 側のOSにより異なる。
OS | path |
---|---|
Mojave | /Volumes/com.apple.TimeMachine.<vol名>-<UUID> |
Catalina, Big Sur, Monterey |
/Volumes/.timemachine/<サーバ名>._smb._tcp.local./<UUID>/<Vol名> 1
|
-
3. Macはrawボリューム直下にある
<mac名>.sparsebundle
サブディレクトリをsparsebundleと解釈してマウント2する。このボリュームを本稿ではTMボリュームと呼ぶ。TMボリュームのpathもOSにより異なる。
OS | path |
---|---|
Mojave, Catalina | /Volumes/Time Machineバックアップ |
Big Sur, Monterey | /Volumes/<mac名>のバックアップ |
-
4. Mojave, Catalinaでは、TMボリュームに対して
fsck_hfs -q
を実行する。エラー(filesystemがdirtyである)が返ってくると新規バックアップを作成する必要がありますと表示され、バックアップは中断する。
Big Sur, Montereyではこのチェックは行われない3。
-
5. TMボリュームに対してバックアップデータを書き込む。それと同時にTMボリュームに対してSpotlight index作成を行う。
-
6. バックアップの書き込みが終了すると、TimeMachine環境設定はバックアップが終了したように表示する。しかし大抵の場合、index作成はその時点では終了していない。
- MontereyではSpotlight index作成が終了するのを待ってからTMボリューム、rawボリュームをumountする。Big Surも同様と思われる4。
-
Mojaveでは、Spotlight index作成中にも関わらずumountしようとするので、umountを失敗する事がある。
これが原因でTMボリュームが正常にcloseされずdirtyとなってしまう事があり、上記 4. の通りバックアップは終了してしまう。
Monterey, Big SurでもWiFi切断等の原因でSpotlight index作成が終了する前にTMボリューム、rawボリュームが強制的にumountされてしまう事があり得る。
Mac上のTimeMachine関連ログを見ると、Big Sur, MontereyではTMボリュームが正常にマウントしているか何度も確認している。よって何らかの対処を行なっていると思われるが、現状では判明していない。
USBで繋いだ外部SSDにTimeMachineバックアップを行った場合、MontereyではSpotlight index作成が終わってからTimeMachine環境設定の表示も終わっているようである。この為外部ディスクへのバックアップは事故が少ないのだろう。
raw ボリュームの構造
TimeMachineバックアップを行なったrawボリュームは、以下のような構成となる。
<timemachine path>/<mac名1>.sparsebundle/bands/...
(/mapped/... Catalina以降)
/com.apple.TimeMachine.MachineID.bckup
/com.apple.TimeMachine.MachineID.plist
/com.apple.TimeMachine.Results.plist
/com.apple.TimeMachine.SnapshotHistory.plist
/Info.bckup
/Info.plist
/token
:
:
/<mac名2>.sparsebundle/...
:
:
TimeMachineのpath直下には、<mac名>.sparsebundle
と言うサブディレクトリが(TimeMachine バックアップを行なったMacの数だけ)ある。
このサブディレクトリはsparsebundleの構造5となっている。
bands
の中にはファイル名が16進数で構成されるファイルが多数存在する。各ファイルの大きさはほぼ同一(少数の例外あり)であるが、Wikipediaの記述6のように8Mbyteとは限らない。確認できた範囲では、Mojaveでは8Mbyte, Catalinaでは64Mbyte, Big Sur, Montereyでは256Mbyteであった。なおOSバージョンアップ時にどうなるかは未確認である。
なおCatalina以降ではmapped
と言うディレクトリがあり、bands
の内容と同じ名前のファイルが同数存在する。ファイルサイズは皆8Kbyteであった。
このように一つのボリューム内に複数のmacのバックアップイメージが作られるので、複数人で一つのTimeMachineボリュームを使う場合は工夫が必要である。
筆者は以下の方法で対処した。
[TimeMachine]
path = <somewhere>
read only = no
browseable = no
writable = yes
fruit:time machine max size = <volume size>
fruit:time machine = yes
valid users = <user 1>, <user 2>, ...
force user = tmbackup
force group = tmbackup
valid users
で使用するユーザを指定する。
サーバ側OSで擬似ユーザ(ここではtmbackup
)を作成し、rawボリュームの所有者をその擬似ユーザとする。
ユーザ間でTMボリュームが見えてしまう問題は、TMボリュームの暗号化で対処する。
その他
Macを特定するID
Catalinaで動作するMacが用意できないので、外部ディスクにCatalinaをインストールして試験をしようとした。ところがMojaveと同じボリュームしか選択できず、上書きしようとしてしまう。Macを異なるホスト名にしたり、ネットワークI/Fを別の物に変えようとも挙動は変わらない。
どうやらrawボリュームのcom.apple.TimeMachine.MachineID.plist
内にあるcom.apple.backupd.HostUUID
で識別しているようである。
この為Catalinaでの挙動を調べる為に別のサーバボリュームを用意する必要が生じてしまった。
samba1つで複数のTimeMachineボリュームを作れるか?
FreeBSDのports/pkgのsamba4.13のデフォルト設定では、TimeMachineボリュームを2つ以上作成しても1つしかMacから見れない。
これはmDNSによって広告されるTimeMachineボリュームの情報(_adisk._tcp
)に、ボリューム一つ分しか登録できない為である。この情報はsambaからavahiに自動的に設定されるので、普通の方法では変更できない。
可能性としてはsambaからavahiサポートを外した上で、avahiを適切に設定する方法があり得るが、未検証である。
成功したので、以下のページにまとめた。
調査時に使ったscript
TimeMachineの動作を調べるために大量のlogを読む必要があったが、/usr/bin/log
コマンドが出力するログは一行が非常に長く読みづらい。このためこちらのページを参考に、以下のようなscriptを作成した。
なおzsh, bashのいずれでも動作する。.zshrc
や.bashrc
など、シェルが起動時に読み込むファイルに挿入する。
# logコマンドの出力を整形
function tm_f(){
/usr/bin/awk '{$4=""; $5=""; print; fflush()}'
}
# logコマンドの引数
TMARGS=( --style compact --predicate 'senderImagePath contains[cd] "TimeMachine"' )
# tmlog: 記録されているログを出力する
tmlog(){
sudo /usr/bin/log show "${TMARGS[@]}" "$@" | tm_f
}
# tmview: 実行中に出力されるログを出力する
# ^Cで終了する
tmview(){
sudo /usr/bin/log stream "${TMARGS[@]}" "$@" | tm_f
}
# 現在発生しているエラーのみ表示
$ tmview
# エラーだけでなく、INFOレベルも表示
$ tmview --info
# 5分前から現在までのエラーログを表示
$ tmlog --last 5m
# 2022年1月9日の13:00:30から14:15:45までのエラー、INFOログを表示
$ tmlog --start '2022-01-09 13:00:30' --end '2022-01-09 14:15:45' --info
参考URL
-
** Macから新しいバックアップを作成する必要がある場合 - Apple サポート **
TimeMachineのイメージが壊れた時の対処法 -
Samba4を「ふつうに」使おう!(2015/08/08 OSC 2015 Kansai@Kyoto)
Samba設定の常識・定石が解説されており、大変参考になった。 -
FreeBSD ZFS で Samba | Netsphere Laboratories
ZFSのACL関係で大変参考になった。 - Sambaのマニュアル
man smb.conf
— Samba の設定ファイル
man vfs_fruit
— OS X と Netatalk との相互運用性を強化する
man vfs_streams_xattr
— 代替データストリームを POSIX の拡張属性に格納する
man vfs_zfsacl
— ZFS ACL samba モジュール
-
マウントポイントは
/Volumes/.timemachine/<サーバ名>._smb._tcp.local./<UUID>/
だが、umountするとディレクトリは消えて、/Volumes/.timemachine/<サーバ名>._smb._tcp.local./
のみが残る。
またマウント中は/Volumes/.timemachine/<サーバ名>._smb._tcp.local./<UUID>/
と言うディレクトリが2つ できる。一方はrawボリュームが入っているが、もう一方は空のようである。 ↩ -
この為samba側からTMボリュームの内容を操作する事はできない。LinuxでTimeMachineボリュームをsparsebundleとして解釈し、read onlyでマウントする方法は存在する(FUSE filesystem for reading macOS sparse-bundle disk images と Apple's Time Machine fuse read only file system を使う)。よってFreeBSDでも同様に行う事は可能と思われる。 ↩
-
ログに
Skipping periodic backup verification: not needed for an APFS sparsebundle
と明示される。 ↩ -
Montereyではログから確認できたが、Big Surでは確認できなかった。 ↩
-
sparsebundleの仕様を見つける事はできなかった。公開情報としては存在しないのか? ↩
-
Wikipedia:Appleディスクイメージの記述より(1/8/2022閲覧) ↩