FreeBSD unionfsの改善提案および修正状況

後藤大地 (daichi@freebsd.org)
作成年月日 Mon Feb 13 12:08:39 2006
更新年月日 Tue Oct 23 13:32:15 2007

[English]

1 概要

FreeBSD 6.2-RELEASEまでに搭載されているunionfsにはいくつかの問題があった。問題は、大きく分けて2つの領域に分類することができる。unionfsにおける仕様が曖昧な部分に起因する問題と、FreeBSD unionfsのロックの実装に関する問題である。

FreeBSD unionfsの2つの問題:

この結果、CD9660ファイルシステムに対してunionfsをかぶせて使用するような場合にいくつかの問題が起こっていた。このためFreeSBIEのようなシステムではunionfsをそのまま採用できないでいた。本稿では、これら問題を説明すると同時に、これら問題を解決するためのパッチを提供する。すでに新しいunionfs実装の重要な部分の大半はシステムへマージされている。現在開発が進められている改善パッチは随時システムへのマージを実施している。

2 unionfsとは

unionfsは、2つのファイルシステムをアタッチしてひとつのファイルシステムとして扱うためのファイルシステムのことである。たとえばCD-ROMに対してメモリファイルシステムをアタッチして、CD-ROM上のファイルに対して書き込みができるかのように見せかけるといった用途に用いられる。

ベースとなるディレクトリ (下層) 以下に対して変更を加えることなく、上にかぶせたディレクトリ(上層)以下に対してのみ変更を与えることになるため、下層のディレクトリはそのままに、変更点だけ保持したいといった場合にも活用できる。

詳細な仕様はMarshall Kirk McKusick、George V. Neville-Neil著 "The Design and Implementation of the FreeBSD Operating System" の P.256 Section 6.7, The Union Filesystemからの2ページ強分などを参照のこと。

3 従来のFreeBSD unionfsが抱えていた問題

FreeBSD 6.2-RELEASEまでの古いFreeBSD unionfsが抱えいた問題は次のとおり。

  1. [実装上の問題] 従来のunionfsは、ロック機構として次のような方法を使っている。VOP_* 系の呼び出しに対し、必要に応じて上層/下層をロックしにいくというものである。この場合、unionfsのvnode を含め、1つのvnodeに対して最大で同時に3つのロックを行うことになる。つまり、カーネル側の仕組とは別のタイミングで複数のロック/アンロックを行うため、デッドロックが起りやすい状況にある。事実、従来のunionfsは不安定であり、高負荷状況になるとデッドロックが起りやすい。
  2. [実装上の問題] VOP_*系の呼び出しにおいて、一部はunionfsのvnodeを応答するのに対し、一部は上層/下層のvnodeを直接応答する。特にLOOKUPでこの現象が起きた場合、ユーザからは理解しがたい状況に陥る可能性がある。これまでに確認しているものは、pwdが上層/下層の絶対パスを応答してしまう現象である。
  3. [実装上の問題] readdirの実装が不十分で、上層の一覧のみを応答する。このため、下層にのみ存在するファイルなどをユーザが識別することが出来ない。
  4. [実装上の問題] 上層/下層に同一のファイル/ディレクトリが存在した場合、上層を削除後にホワイトアウトが作成されないため、ユーザからは削除されていないように見える。
  5. [実装上の問題] アクセス権の判定において、下層にのみファイル/ディレクトリがある場合、上層にshadow file/dirを作成後に与えられる権限を応答しない。このため、書き込めるはずのファイルに書き込めないなどの問題が発生する。
  6. [unionfsの仕様の曖昧さに起因する問題] unionfsの仕様には下層のshadow file/dirを作成する場合に、属性の引き継ぎに関する規定がない。このため、従来の実装では「0777をそのときのumaskで修正したもの」という方法のみが提供されてきたが、これが現在のFreeBSD unionfsでは好ましくない結果を生んでしまうことがある。たとえば、実行権限を与えるべきでないファイルへ実行権限が与えられてしまうなど。

これら古いFreeBSD unionfsが抱える問題によってたとえば次のような影響がでていた。

4 問題への改善提案

提案してきたパッチにおける[実装上の問題]への改善内容は次のとおり。これら成果物はすでにFreeBSDシステムへマージされており、FreeBSD 8/FreeBSD 7.0/FreeBSD 6.3ではこれら問題は発生しない。

  1. [実装上の問題への対処] unionfsのvnodeが内部に持つロックオブジェクトを上層/下層のロックオブジェクトへのポインタに差し替え、なおかつロック/アンロックをunionfsで管理することでkernelをできるだけ修正せずに正常動作するようにする。また、kernelへの影響を無くすため、上層/下層のロックは常に同じ状態を維持できるように管理する。
  2. [実装上の問題への対処] http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/84107の修正 (修正完了)
  3. [実装上の問題への対処] http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/84498の修正 (修正完了)
  4. [実装上の問題への対処] http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/89755の修正 (修正完了)
  5. [実装上の問題への対処] http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/73094の修正 (修正完了)
  6. [実装上の問題への対処] これ以外で、前述したようにわかっている問題を対処。

[unionfsの仕様の曖昧さに起因する問題]に対する改善については、本来仕様に規定されていないことであるため、規定されていない振る舞いをどうするべきか、という議論を含むことになる。

FreeBSD 6.2-RELEASEまでの古いunionfsにおける実装では、この結果、アクセス権を判定し動作を決定するアプリケーションが、ユーザの期待どおりに動作しないという状況が発生している。

この振る舞いをどうするかであるが、これは場面に応じて要求される事柄であり、また、本来仕様に定められていないことであるために、対応が難しいところだと考えられる。今回はこの振る舞いに対し、オプションによって3つの振る舞いを持たせるということで対処することを提案した。パッチはこの3つの振る舞いをオプションで切り替える機能を含んでいる。

[unionfsの仕様の曖昧さに起因する問題]に対する改善:3つの動作パターン

本来仕様が策定されていない部分の振る舞いであるから、複数の振る舞いを用意し選択できるようにすることは、意義のある対応であると考える。たとえば、3-7において説明した[unionfsの仕様の曖昧さに起因する問題]は、[transparentモード]で対処できる。

この結果、次の問題も[transparentモード]で修正された。

5 インストール方法

パッチを適用してインストールする方法の作業例をプロンプト5.1に示す。

# cd /usr/src/
# patch -p3 < /anywhere/unionfs-p19-20070504.diff
# cp /usr/src/sys/fs/unionfs/union.h /usr/include/fs/unionfs/
# cd /usr/src/sbin/mount_unionfs/
# make obj depend && make && make install
# make clean
# cd /usr/src
# make buildkernel
# make installkernel
# shutdown -r now
プロンプト5.1 インストール作業の例

6 使用方法

マニュアルページmount_unionfs(8)を参照のこと。すべてマニュアルページにまとまっている。

7 ダウンロード

FreeBSD 8-current向けパッチ。パッチセット番号が大きいほど新しいパッチセット。

FreeBSD 7-stable向けパッチ。

FreeBSD 7-current向けパッチ。

FreeBSD 6-stable向けパッチセット: