read-only root over NFS v4 + overlayfs使用時の問題と対策

NFSで提供されたread-only rootにtmpfsをoverlayすることで,同一のrootfsを複数のserverで共有できる.
この環境を構築する際に生じた問題とその対策をまとめた.

環境

  • OS: CentOS Linux release 8.1.1911 (Core)
  • Kernel: 4.18.0-147.5.1.el8_1.x86_64
  • overlayfsを使用
    • lower = read-only root over NFS v4
    • upper = tmpfs

lowerdirの内容を変更するとESTALEが生じる

そもそもoverlayfsではlowerへの変更は許容されないことがKernel-docに記載されている.

https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt

Changes to the underlying filesystems while part of a mounted overlay
filesystem are not allowed.  If the underlying filesystem is changed,
the behavior of the overlay is undefined, though it will not result in
a crash or deadlock.

しかし,稼働中のrootfsへ変更を加えることができると便利なので,変更を許容してほしい.

patchworkにそのような要望を叶えるpatchが投稿されており,これを適用すればよい.

patchwork.kernel.org

(上記パッチは微妙に壊れているので,書き直した)

diff -ru linux-4.18.0-147.5.1.el8.x86_64/fs/overlayfs/super.c linux-4.18.0-147.5.1.el8.x86_64.new/fs/overlayfs/super.c
--- linux-4.18.0-147.5.1.el8.x86_64/fs/overlayfs/super.c        2020-01-14 23:54:17.000000000 +0900
+++ linux-4.18.0-147.5.1.el8.x86_64.new/fs/overlayfs/super.c    2020-03-02 04:29:36.855735623 +0900
@@ -127,16 +127,11 @@

                if (d->d_flags & DCACHE_OP_REVALIDATE) {
                        ret = d->d_op->d_revalidate(d, flags);
-                       if (ret < 0)
+                       if (ret <= 0)
                                return ret;
-                       if (!ret) {
-                               if (!(flags & LOOKUP_RCU))
-                                       d_invalidate(d);
-                               return -ESTALE;
-                       }
                }
        }
-       return 1;
+       return ret;
 }

 static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)

NFS v4を用いるとサブディレクトリ以下への書き込みでEOPNOTSUPPが生じる

NFS v4ではACLをサポートしているが,この属性情報(xattr)を含むmetadataをlowerからupperへコピーする際,ACL名前空間が異なるためコピーに失敗し,EOPNOTSUPPが生じる.

詳しい情報は以下のサイトに記載されている.

blog.fai-project.org

この問題へのいくつかの対策法を以下に示す

  • export元のfsのACLを無効にする (NFSv4のACLが無効になる)
  • NFS v3を使う
  • overlayモジュールのload時,またはマウントオプションで"metacopy=off"を指定する (未検証)
  • metadataのcopy時にEOPNOTSUPPを無視するパッチ(以下)を当てる
    • カーネルを弄らなくても解決できるので,これ以外の解決方法 (上の三つ) を取るべきだと思う
diff -ru linux-4.18.0-147.5.1.el8.x86_64/fs/overlayfs/copy_up.c linux-4.18.0-147.5.1.el8.x86_64.new/fs/overlayfs/copy_up.c
--- linux-4.18.0-147.5.1.el8.x86_64/fs/overlayfs/copy_up.c      2020-01-14 23:54:17.000000000 +0900
+++ linux-4.18.0-147.5.1.el8.x86_64.new/fs/overlayfs/copy_up.c  2020-03-02 04:21:37.701624976 +0900
@@ -110,6 +110,10 @@
                        continue; /* Discard */
                }
                error = vfs_setxattr(new, name, value, size, 0);
+               if (error == -EOPNOTSUPP) {
+                       error = 0;
+                       continue;
+               }
                if (error)
                        break;
        }