Sambaにおける複数パーティションの容量の補正
Sambaで複数のパーティションをまたがる共有ドライブを公開すると、空き容量が正しく表示されない問題があります。
例えば、下表のように /home
の下に複数のパーティションをマウントしている場合、 /home
の共有ドライブに対する容量は10 GBと表示されてしまいます。本来は210 GBとなるはずです。また、容量が正しく表示されないだけでなく、大きなファイルをコピーできない問題も発生します。
マウントポイント | ディスク | 容量 |
---|---|---|
/home |
/dev/sda1 |
10 GB |
/home/fiz |
/dev/sdb1 |
100 GB |
/home/buz |
/dev/sdc1 |
100 GB |
dfreeによる解決策
Sambaでは dfree command
という設定が用意されており、ディスクの全容量や空き容量を外部コマンドに計算させることが可能です。具体的には、以下のように dfree command
に外部コマンドのパスを渡すと、ディスク容量の計算が必要になった時に外部コマンドが実行されます。また、 dfree cache time
で指定した秒数だけ計算結果をキャッシュさせることも可能です。
# smb.conf [home] path = /home dfree command = /etc/samba/samba-dfree dfree cache time = 60
外部コマンドの仕様は、マニュアルには以下のように記載されています。
The external program will be passed a single parameter indicating a directory in the filesystem being queried. This will typically consist of the string ./. The script should return two integers in ASCII. The first should be the total disk space in blocks, and the second should be the number of available blocks. An optional third return value can give the block size in bytes. The default blocksize is 1024 bytes. https://www.samba.org/samba/docs/man/manpages/smb.conf.5.html#idp59614672
外部コマンドの引数にはディレクトリのパスが渡されます。また、外部コマンドは全容量と空き容量の2つの値を標準出力に表示する必要があります。値は1024 byteのブロック単位です。バイト数を1024で割るとよいでしょう。
マニュアルに詳細が書かれていないので、外部コマンドがどのように実行されるか調べてみました。カレントディレクトリは共有ドライブのパス(例では /home
)になるようです。また、引数には .
しか渡されないようです。
このことから、 dfree command
で指定した外部コマンドは以下の動作をすればよいことが分かります。
- カレントディレクトリ(例:
/home
)と引数(例:.
)から計算対象のディレクトリを調べる。 - 計算対象のディレクトリに含まれるサブディレクトリを調べる。例では
/home/fiz
と/home/buz
になる。 - サブディレクトリの全容量と空き容量を合算する。例では 210 GBになる。
- 全容量と空き容量のバイト数を1024で割った値を表示する。
dfreeの実装
せっかくなのでGoで実装してみました。
ソースコードだけでなくx86_64で動作するバイナリも公開しているので、よかったら利用してください。Travis CIでビルドされたバイナリをGitHubに直接リリースしています。