ちょっと前にリリースされたカーネルですが、4.10 で overlayfs に変更が入っていましたのでちょっと調べてみました。
Overlayfs についてはこちらをどうぞ (ちょっと古い記事なのでカーネルにマージされる前の仕様も説明しています)。
それとコンテナ勉強会のこの発表資料
- ちょっとOverlayfsの実装、読んでみました (@akachochinさん)
カーネルの変更と準備
4.10の関連するコミットは以下。
- ovl: redirect on rename-dir
- ovl: allow redirect_dir to default to “on”
- ovl: allow setting max size of redirect
- ovl: show redirect_dir mount option
lowerdir側に存在するディレクトリを移動した場合の改良ってところでしょうか。相変わらずパッチも短くて見やすくて変更が追いやすそうですね (あまりちゃんと見てませんが)。
以下は 4.13-rc5 カーネルで試しています。
カーネルの config で Overlayfs: turn on redirect dir feature by default
を “Y” にするとデフォルトで有効になるようです (CONFIG_OVERLAY_FS_REDIRECT_DIR
)。
従来の動き
まずは従来の動きにするように redirect_dir=off
というオプションを与えます。
$ mkdir lower upper work overlay # overlayfs用のディレクトリの作成 $ mkdir lower/lowerdir upper/upperdir # 下層、上層それぞれにディレクトリ作成 $ touch lower/lowerdir/lowfile upper/upperdir/upfile # ディレクトリ内にファイル作成 $ sudo mount -t overlay \ > -o lowerdir=lower,upperdir=upper,workdir=work,redirect_dir=off > overlayfs overlay/ # マウント
重ね合わされた overlay
ディレクトリの中身はこんな風になります。普通の動きですね。
$ find overlay/
overlay/
overlay/lowerdir
overlay/lowerdir/lowfile
overlay/upperdir
overlay/upperdir/upfile
lowerdir
を移動しましょう。
$ cd overlay $ mv lowerdir lowerdir2 $ ls -F lowerdir2/ upperdir/
ここで下層の lowerdir
と上層の upperdir
の中を覗いてみます。
$ find lower/
lower/
lower/lowerdir
lower/lowerdir/lowfile
Overlayfs は下層側は変化しませんので、これは当たり前。
$ ls -l upper/ 合計 8,192 c--------- 1 root root 0, 0 8月 16日 17:32 lowerdir drwxr-xr-x 2 karma users 4,096 8月 16日 17:29 lowerdir2/ drwxr-xr-x 2 karma users 4,096 8月 16日 17:29 upperdir/
Overlayfs では、削除されたファイルやディレクトリは特別なデバイスファイルになるのでした。lowerdir
は削除された状態になっており、新たに移動先の lowerdir2
が上層に作成されていますね。lowerdir2
内には、元々下層の lowerdir
内に存在していたファイルがコピーされています。
$ ls -l upper/lowerdir2/ 合計 0 -rw-r--r-- 1 karma users 0 8月 16日 17:29 lowfile
ディレクトリ内に多数のファイルやディレクトリがある場合は時間がかかりそうです。
改良後の動き
4.10 で導入された “redirect on rename-dir” という機能を使ってみましょう。
$ sudo mount -t overlay \ > -o lowerdir=lower,upperdir=upper,workdir=work,redirect_dir=on \ > overlayfs overlay
ここでは明示的に redirect_dir=on
としていますが、カーネルの config でこの機能を “Y” にしてあれば、自動的にオンになりますので、これは不要です。
$ find overlay/
overlay/
overlay/lowerdir
overlay/lowerdir/lowfile
overlay/upperdir
overlay/upperdir/upfile
先ほどと同じように下層と上層が重ね合わされた状態になっています。この状態で先ほどと同じようにディレクトリを移動してみましょう。
$ cd overlay/ $ ls lowerdir/ upperdir/ $ mv lowerdir lowerdir2 $ ls lowerdir2/ upperdir/
はい、移動されました。それでは下層と上層のディレクトリ内を覗いてみましょう。
$ ls -l upper/ 合計 12,288 c--------- 1 root root 0, 0 8月 16日 17:35 lowerdir drwxr-xr-x 2 karma users 4,096 8月 16日 17:34 lowerdir2/ drwxr-xr-x 2 karma users 4,096 8月 16日 17:34 upperdir/
これは先ほどと同じですね。移動前の lowerdir
が削除された状態になっており、新たに lowerdir2
が作成されています。この lowerdir2
内を覗いてみましょう。
$ ls -l upper/lowerdir2/ 合計 0 $ ls overlay/lowerdir2/ lowfile
おや? 先ほどは内部のファイルもコピーされていましたが、今回はファイルが存在しません。にもかかわらず、重ね合わせたディレクトリにはちゃんとファイルが存在しますね。下層側を見てみると、
$ ls -l lower/lowerdir/ 合計 0 -rw-r--r-- 1 karma users 0 8月 16日 17:34 lowfile
ファイルが存在しますが、これは従来と変わりありません。
ディレクトリを移動した場合は、中身のファイルは元の下層側のファイルを参照しているようですね。参照先はどうやって調べているのでしょう?
先に紹介したコミットにも、Documentation/filesystems/overlayfs.txt にも書かれてあります。
2. If the "redirect_dir" feature is enabled, then the directory will be copied up (but not the contents). Then the "trusted.overlay.redirect" extended attribute is set to the path of the original location from the root of the overlay. Finally the directory is moved to the new location.
調べてみましょう。
$ sudo getfattr -n trusted.overlay.redirect upper/lowerdir2 # file: upper/lowerdir2 trusted.overlay.redirect="lowerdir"
ここに参照先が保存されていますね。
階層が深くなった時は “he path of the original location from the root of the overlay” ってことだから、マウントポイントからのパスが保存されているのかと思ったら、単なるディレクトリ名でした。まあ追えるからかな。
$ sudo getfattr -n trusted.overlay.redirect upper/lowerdir2/hogehoge2 # file: upper/lowerdir2/hogehoge2 trusted.overlay.redirect="hogehoge"
ちなみに redirect_dir 機能を使って操作された overlayfs (の upperdir) を、redirect_dir 機能をサポートしていないカーネルではマウントできませんので注意しましょう (あまりないか…)。
おまけ
4.10 では、redirect 機能の他に、ディレクトリの移動時の変更がもうひとつ加えられています。xfs の時に効果を発揮するのでしょうか。