SambaでTime Machineのバックアップ環境を構築する (Sierra以降)

**追記**: Samba 4.8 のパッケージが experimental に入りました。
https://packages.debian.org/search?keywords=samba

当記事の構築手順は既に古い内容であり、Time Machine に関する設定も最新の Samba では **使用できません** 。

最新の Samba における設定方法については公式の vfs_fruit のドキュメントを参照してください。

https://www.samba.org/samba/docs/current/man-html/vfs_fruit.8.html

---

# 概要

1. macOS Sierra から Time Machine のバックアップに **特定の要件を満たした** SMB 接続のネットワークボリュームがサポートされた
2. Samba の vfs_fruit に `F_FULLFSYNC` を追加するパッチが存在する
3. パッチを適用した Samba を使用すれば Time Machine のバックアップ先に利用できる

# 今までと何が異なるか

Time Machine のバックアップを SMB 接続のネットワークボリューム内に作成する方法は、macOS Sierra 以前からも存在しました。
よく紹介されるのは defaults コマンドで `TMShowUnsupportedNetworkVolumes` に `1` をセットする方法です。
これは名前からして Unsupported でしたが、macOS Sierra からはこの設定を使用しなくても SMB 接続のネットワークボリュームに Time Machine のバックアップを実行することができます。

ただし、SMB 接続での Time Machine のバックアップは、サーバー側が [Time Machine Over SMB Specification](https://developer.apple.com/library/content/releasenotes/NetworkingInternetWeb/Time_Machine_SMB_Spec/) の要件を満たす必要があります。
この記事を書いた時点では Samba はこの要件を満たさなかったため、そのままでは使用できませんでした。

この記事では、Samba で Time Machine をサポートするための以下の修正を先行して使ってみる手順を記載します。

[vfs_fruit: Add capability to advertise FULLSYNC by kevinanderson1 · Pull Request #64 · samba-team/samba · GitHub](https://github.com/samba-team/samba/pull/64)

この後に続く内容はほとんどこの Pull Request のコメントに書かれてるので、分かる人はたぶんこの先を読む必要は無いです。

# 手順

Samba を使用する時点で今更ではありますが、自己責任で試して下さい。

## Sambaをビルドする

※ Debian sid で samba-vfs-modules パッケージをビルドする手順を書きます。他のディストリビューション等ではよしなに頑張って下さい

```
$ apt source samba
$ cd samba-4.5.8+dfsg
$ curl -L https://github.com/samba-team/samba/pull/64.diff > debian/patches/bz12380-full_fsync.patch
$ echo 'bz12380-full_fsync.patch' >> debian/patches/series
$ sudo apt build-dep samba
$ debuild -us -uc -b
```

これで `../samba-vfs-modules_4.5.8+dfsg-1_amd64.deb` が出来上がったはずです。
他にも samba 本体のパッケージなどが生成されますが、必要なのは `vfs/fruit.so` だけなので samba-vfs-modules のみ使用します。

生成されたパッケージをインストールします。

```
$ sudo apt install samba samba-vfs-modules
$ sudo dpkg -i ../samba-vfs-modules_4.5.8+dfsg-1_amd64.deb
```

（samba パッケージが更新されたら同じ手順でビルドし直して samba-vfs-modules をインストールする必要があります）

## Sambaの設定を追加

`/etc/samba/smb.conf` に以下の設定を追加します。 `/srv/samba/timemachine` の部分は共有ディレクトリのパスなので適当に用意して下さい。

```ini
[global]
vfs objects = fruit streams_xattr
fruit:advertise_fullsync = true

[timemachine]
path = /srv/samba/timemachine
durable handles = yes
kernel oplocks = no
kernel share modes = no
posix locking = no
```

設定は https://github.com/samba-team/samba/pull/64#issuecomment-257267673 を参考にしました。
`fruit:advertise_fullsync` は [global] セクションに置かないと効かないみたいです。

## Avahiの設定を追加

avahi-daemon が必要なので、無ければインストールして下さい。

```
$ sudo apt install avahi-daemon
```

`/etc/avahi/services/timemachine.service` を作成して、以下の設定を記述します。

```xml
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
 <name replace-wildcards="yes">%h</name>
 <service>
   <type>_smb._tcp</type>
   <port>445</port>
 </service>
 <service>
   <type>_adisk._tcp</type>
   <txt-record>dk0=adVN=timemachine,adVF=0x82</txt-record>
 </service>
</service-group>
```

`adVN=timemachine` の部分は Samba の共有名と一致させる必要があります。
この設定は https://github.com/samba-team/samba/pull/64#issuecomment-258569618 を参考にしました。

## (任意) Time Machineで使用するストレージ容量を制限する

このままの設定だと `/srv/samba/timemachine` に割り当てられた容量の上限まで空きがあると見なされます。
Time Machine 以外にも Samba の共有フォルダがある場合だと、バックアップのために使用される容量を制限したいと考へるかもしれません。

その場合は、 https://github.com/samba-team/samba/pull/64#issuecomment-265512556 の `samba-dfree.sh` を使用することで表示上の容量を制御できます。

`samba-dfree.sh` を適当なディレクトリに配置して、`smb.conf` に設定を追加します。

```ini
[timemachine]
dfree command = /usr/bin/env TIMEMACHINE_MAX_VOL_SIZE_GB=300 /usr/local/bin/samba-dfree.sh
```

容量の上限は `TIMEMACHINE_MAX_VOL_SIZE_GB` の数値を変更することで指定できます（GiB 単位）

## Time Machineでバックアップを実行する

Time Machine の「バックアップディスクを追加/削除」で、Samba を設置したマシンの名前が表示されるはずです。
あとは普通の Time Machine でのバックアップと同じ手順で実行できます。

もし以前のバックアップを移行したい場合、既存の sparsebundle を事前に Samba の共有フォルダ内にコピーしておけば、バックアップディスクの追加時に以前のバックアップを利用するかどうか聞かれます。

# 補足

Pull Request の内容を読むと分かりますが、この修正では Samba がクライアントに `F_FULLFSYNC` 対応であることを告知するだけで実際には `F_FULLFSYNC` が送られても何もしません。
そのため、現時点ではバックアップの整合性が失はれる可能性があることを気に留めておいて下さい。