Samba一つで複数のTimeMachineを作る方法

Samba一つで複数のTimeMachineを作る事ができたので、メモを書いておく。

**更新履歴**
- 9/13/2022
ログファイルに出てしまうエラーメッセージを追加。
- 3/21/2022
avahiの `smb.service` の誤りを修正。通常の共有ボリュームが見えなくなる問題があった。

# 背景

https://qiita.com/ftns/items/47a60e918a1cdd49fa9d#samba1つで複数のtimemachineボリュームを作れるか

上記ページの時点では、一つのsambaでサポートできるTimeMachineは一つのみであった。
理由は、
> これはmDNSによって広告されるTimeMachineボリュームの情報(`_adisk._tcp`)に、ボリューム一つ分しか登録できない為である。この情報は**sambaからavahiに自動的に設定される**ので、普通の方法では変更できない。

であると思われた。そこで

> 可能性としてはsambaからavahiサポートを外した上で、avahiを適切に設定する方法があり得るが、未検証である。

と考えたので、実際にやってみた。

:::note info
なお本問題は所詮mDNSへの登録の問題に過ぎないので、sambaの将来のバージョンでは解消される可能性がある。
:::

# 調査環境
* Server:
  - OS: FreeBSD 12.2-RELEASE-p13
  - samba: 4.13.14(ports)
* Client 1: MacBook (Retina 12inch Early 2016) Catalina(10.l5.7)
* Client 2: MacBook Pro（M1Max 14inch 2021) Monterey (12.3)

# 準備

## samba

### 本体の設定
FreeBSDのports/pkgで提供されているsambaは、デフォルトでavahiサポートが有効となっている。そこで [ports](https://docs.freebsd.org/ja/books/handbook/ports/#ports-using "FreeBSDハンドブック 4.5. Ports Collection の利用") 版samba413(`/usr/ports/net/samba413`)で**avahiサポートを外そうとした**所...

```shell:
# 念の為 ports をアップデート
$ sudo portsnap fetch
$ sudo portsnap update

# sambaの設定を変更
$ cd /usr/ports/net/samba413
$ sudo make config
　　（“( ) ZEROCONF_NONE  Zeroconf support is absent” を選択）
====> Two or more enabled options conflict with each other
=====> Option FRUIT conflicts with ZEROCONF_NONE (select only one)
======> MacOSX support requires Zeroconf(AVAHI or MDNSRESPONDER)
Config is invalid. Re-edit? [Y/n] 
```

...と、エラーになってしまう。
早くも詰んだか？と思ったが、このサーバではavahiを使っておりmDNSResponderは使っていない。そこでダメ元で***mDNSResponder対応にしてみる***事にした。

```shell:
$ cd /usr/ports/net/samba413
$ sudo make config
　　（“( ) MDNSRESPONDER  Zeroconf support via mDNSResponder” を選択）
$ sudo make clean all deinstall reinstall
```

これでコンパイルは成功する。結果を先に述べると、**この方法で上手く動作した**[^1]。

[^1]: なおOSでmDNSResponderを使っている場合に、sambaをavahiサポートにして動作するかは不明である。

### smb4.conf

smb4.confでは、単純にTimeMachine volumeを列挙すれば良い。
一例を以下の折り畳み内で示す。
<details><summary>smb4.conf</summary>

```conf:smb4.conf
[global]
    workgroup = WORKGROUP
    security = USER
    server min protocol = SMB2
    server string = <your server>
    server role = standalone server
    dos filemode = yes
    store dos attributes = yes
    map archive = no
    unix extensions = no
    
    # veto files
    delete veto files = yes
    veto files = /._*/.DS_Store/

    # ACL
    force unknown acl user = yes
    inherit acls = yes
    map acl inherit = yes

    # vfs
    vfs objects = zfsacl catia fruit streams_xattr full_audit

    # vfs_zfsacl
    nfs4:chown = yes

    # vfs_fruit
    fruit:zero_file_id = yes
    fruit:metadata = stream
    fruit:veto_appledouble = no
    fruit:resource = xattr
    fruit:model = PowerMac

    # vfs_streams_xattr
    streams_xattr:store_stream_type = no
    streams_xattr:prefix = user.

[TimeMachine0]
    comment = TimeMachine 0
    path = <somewhere on ZFS>
    read only = no
    valid users = <user1>, <user2>, ...
    fruit:time machine max size = <volume size>
    fruit:time machine = yes
    browseable = no
    writable = yes

[TimeMachine1]
    comment = TimeMachine 1
    path = <somewhere on ZFS>
    read only = no
    valid users = <user3>, <user4>, ...
    fruit:time machine max size = <volume size>
    fruit:time machine = yes
    browseable = no
    writable = yes
```
</details>

### 再起動

```shell:
$ sudo service samba_server restart
```

## avahi
### 設定
通常の方法なら、TimeMachine関連の設定はsambaからavahiに自動的に設定される。
ここでは自動設定を使わないので、avahiに予め設定を用意する必要がある。

散々試行錯誤した結果、以下の設定で動作した。
```config:/usr/local/etc/avahi/service/smb.service
<?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=TimeMachine0,adVF=0x82</txt-record>
    <txt-record>dk1=adVN=TimeMachine1,adVF=0x82</txt-record>
    <txt-record>sys=adVF=0x100</txt-record>
  </service>
  <service>
    <type>_device-info._tcp</type>
    <txt-record>model=PowerMac</txt-record>
  </service>
</service-group>
```

ここで追加した設定は、以下の通り：

```config: TimeMachine volumeの設定
  <service>
    <type>_adisk._tcp</type>
    <txt-record>dk0=adVN=TimeMachine0,adVF=0x82</txt-record>
    <txt-record>dk1=adVN=TimeMachine1,adVF=0x82</txt-record>
    <txt-record>sys=adVF=0x100</txt-record>
  </service>
```
ここでは`TimeMachine0`, `TimeMachine1`の2つのTimeMachineボリュームを設定している。各`<txt-record>`の最初を`dk0=`, `dk1=`とする事で、複数のボリュームを認識するようである。`adVN=`の次がTimeMachineボリューム名である。
なお`sys=adVF=0x100`は、TimeMachineではない通常の共有ボリュームを示しているようである[^2]。

[^2]: この行が無いとFinderに共有ボリュームが一切表示されず、隠した筈の`TimeMachine0`, `TimeMachine1`のみが表示される。

```config:アイコンの設定
  <service>
    <type>_device-info._tcp</type>
    <txt-record>model=PowerMac</txt-record>
  </service>
```
avahiサポートを外すと、`smb4.conf`の`fruit:model`でアイコンを設定しても反映されない。その為ここで設定する。`model=`の後に書く名称は、`fruit:model`で設定する物と同じである。

### 再起動
```shell:
$ sudo service avahi-daemon restart
```

# 結果

![Two-TM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428443/d2107852-86f0-6a09-f542-964ed477d17f.png)

一つのsambaで、2つのTimeMachineボリュームが使えるようになった。動作も問題ないようである。

### 問題点

logに以下のようなエラーメッセージが大量に出てしまうが、この方法ではやむを得ない。

```
Sep 13 14:35:19.674 <サーバ名> smbd[<PID>]: dnssd_clientstub ConnectToServer: connect
() failed path:/var/run/mdnsd Socket:55 Err:-1 Errno:2 No such file or directory
```