あーかいぶすハイディフィニション

ここはもう更新しとらんのじゃ

kernel: CIFS VFS: Unexpected lookup error

CIFS マウント(WindowsLinux でのファイル共有)の仕方と暫定まとめワイ版。
※以前書いた記事を編集しました。

CIFS について

Windowsのファイル共有サービスで利用されているプロトコルの「SMB」を拡張し、Windows以外のOSやアプリケーションソフトでも利用できるよう仕様を公開したもの。

http://e-words.jp/w/CIFS.html

ということで、ザルですがに SMB≒CIFS という認識でもいいでしょう。ただし混同するからには、ちゃんと仕様を把握していないと大変な間違いの元になりますね。

CIFS のマウント方法について

基本的にマウントコマンドを実行できるのは、root ユーザのみ。

[root@localhost ~]# which mount
/bin/mount
[root@localhost ~]# mount -t cifs -o username=USERNAME,password=PASSWORD,uid=UID,gid=GID,file_mode=PERMISSION,dir_mode=PERMISSION DEVICE DIR

基本 mount コマンドが入ってればこんなんで接続できます。なお、mount コマンドがマウント可能なファイルタイプは、

現在サポートされているファイルシステムのタイプには、以下のものが含まれる。 adfs, affs, autofs, coda, coherent, cramfs, devpts, efs, ext, ext2, ext3, hfs, hpfs, iso9660, jfs, minix, msdos, ncpfs, nfs, ntfs, proc, qnx4, ramfs, reiserfs, romfs, smbfs, sysv, tmpfs, udf, ufs, umsdos, usbfs, vfat, xenix, xfs, xiafs. coherent, sysv, xenix の 3 つは等価であり、 xenix と coherent は将来削除される --- 代りに sysv を用いること。

http://linuxjm.sourceforge.jp/html/util-linux/man8/mount.8.html

ただし上記のドキュメントがいつ時点のものかは不明なので、日本語のドキュメントとしてインストールした環境の man mount と対照するにとどめましょう。手元の CentOS 6.4 では更に対応しているファイルシステムは増えていました。

The filesystem types which are currently supported include:
adfs, affs, autofs, cifs, coda, coherent, cramfs, debugfs, devpts, efs, ext, ext2, ext3, ext4, hfs, hfsplus, hpfs, iso9660, jfs, minix, msdos, ncpfs, nfs, nfs4, ntfs, proc, qnx4, ramfs, reiserfs, romfs, squashfs, smbfs, sysv, tmpfs, ubifs, udf, ufs, umsdos, usbfs, vfat, xenix, xfs, xiafs.

CIFS 増えてる(よろこび)。

mount -t TYPE した時の挙動

TYPE に指定されたファイルシステムを Kernel が知っている(対応するドライバが組み込まれている)状態なら、mount.TYPE コマンドに処理を投げるようです。つまり mount コマンドは指定されたタイプのマウントコマンドを呼ぶためのものですね(これを利用して、ファイルシステムを自動判別する auto という指定もあるようですが使ったこと無いので知らん)。
mount -t cifs した場合、内部では mount.cifs が呼ばれている、ということになります。
mount.cifs

今回の主題

Windows 2008R2 StorageServer で NAS 運用をしているのですが、ウェブサーバと化した Linux 先輩から mount で共有すると、マウントポイントにアクセスした時、ビジー状態になってタイムアウトするまでアクセスした処理が待たされる、という現象。
具体的に発生したエラーは、dmesg か messages のログで確認できるけど以下のようなもの。

kernel: CIFS VFS: Unexpected lookup error -512
kernel: CIFS VFS: Unexpected lookup error -112

他にも Trace が通知されてきてるけど、基本的にこいつらがメイン。Windows 側で共有領域作るのは、共有のなんとかってウィザードで作成したよ。

発生と対処完了まで
  1. NAS 導入したので以下のコマンドでウェブアプリケーションの静的ファイル置くディレクトリとしてマウントしたよ!」
  2. mount -t cifs -o username=ulindouzu,password=naskakkoii,uid=603,gid=603,file_mode=0755,dir_mode=0755 //114.5.1.4/893 ./kanzensyouri/
  3. 「なんかウェブアクセスすると Nginx やローカルでキャッシュした分以外でねーんすけど!」「ほげぇ」
  4. ls -ahl ./kanzensyouri/
  5. あれ?反応返って来ない……ターミナル終了して新しいセッションから less /var/log/messages
  6. kernel: CIFS VFS: Unexpected lookup error -512
  7. 「ファっ?!」
  8. dmesg
  9. kernel: CIFS VFS: Unexpected lookup error -512
  10. 「あっこれ samba のクライアントとか入ってない!ナンデ?!マウントできたしファイルも書き込めたし参照も共有してる複数サーバから出来たのにナンデ?!」
  11. yum install samba-client samba-common samba-winbind samba-winbind-clients samba-winbind-devel samba-winbind-krb5-locator
  12. 「ドーモスミマセンデシター!(ドゲザ」
  13. 翌日「書き込める時と書き込めない時がある」(^q^)
  14. 「アイエエエ?! cifs-utils が Available Package に表示されるのナンデ?!」
  15. yum install cifs-utils
  16. 「こ、今度こそ治りましたー!オタッシャデー!」「オタッシャデー!」
  17. 6時間後「おい治ってねえ(現象再発した)ぞ」(´・ω・`)はぁまじはぁ
  18. 「crontab -e して */10 * * * * touch $PATH/kanzensyouri/shigemi.touchme って書いておいたからもうこれしかねえ」
  19. とりあえず今は再発してない再発した(最下部に追記しました)
つまりどうした

samba 関連のクライアントインストールして、cifs-utils インストールして、更に NAS に対して長時間使われなかった場合タイムアウトされる可能性を考慮して、cron で10分毎に空ファイル生成させる(NAS にアクセスさせる)ようにした。
導入したパッケージのインストールコマンドは以下。

yum install samba-client samba-common samba-winbind samba-winbind-clients samba-winbind-devel samba-winbind-krb5-locator cifs-utils
分かったこと

samba のクライアント入れなくても、最近の Kernel が CIFS ファイルシステムを最初から知っているので、mount.cifs コマンド入ってればマウントできるんですね。それと、上記参照先の mount.cifs に「samba.conf は完全無視する」という記述がありましたが、いつの時点のものかわからなかったのでとりあえず入れました(最初、mount コマンドは CIFS をわからなくて、samba のクライアント入れれば解決すると思ってた)。

また、NAS にアクセスできない状態で長い間待たされるのは、過去記事にも書いたように以下のようになっている様子です。

  1. /proc/sys/kernel/hung_task_timeout_secs に記述された数値秒だけ待ってくれる、超過するとタイムアウト(デフォルト 120 秒)。
  2. マウントポイントを(再帰的に)含む位置から ls とか発行すると、hung_task_timeout_secs 秒数分待たされ地獄。
  3. dmesg にエラーが出る。

dmesg への通知で echo 0 すれば回避できる、みたいな tips は出ますが、これは非常に危ない(気が付かない)可能性が出るので、短くするにしても 15 秒とか 30 秒程度にすべきでしょう。むしろマウントコマンドの下記オプションで吸収できるようです。

  • hard
    • CIFS でマウントされたファイルシステムにアクセスしているプログラムは、サーバーがクラッシュすると、ハングアップする。
  • soft
    • (既定値)CIFS でマウントされたファイルシステムにアクセスしているプログラムは、サーバーがクラッシュしてもハングアップせず、ユーザーアプリケーションにはエラーが返却される。

試していませんが、デフォルトは hard っぽいですね、soft 指定しておけばエラーを返すので即座にアクセスを終了してくれるとおもいます。

あと結局 CIFS VFS がエラーを返す原因がわかってなくて、対処療法的に試したら治ったっぽいのでこれで落着にしておりますが、対象の NAS を四台のウェブサーバが参照しており、そのうち最初に導入した二台は cifs-utils を入れた段階で CIFS VFS がエラーを返さなくなりました。原因がわかんねぇなこれ?残りの後から追加した touch で対処療法した鯖は別ネットワークに存在しており、上位の LB にルートを通っていたので、そこからアクセスさせているのですが、それが悪いのでは…アクセスが一定時間なければ LB がアクセスタイムアウトさせてる?みたいな疑惑もあったのですが、鯖屋に問い合わせた所、「L3 だからそれはねえよ」と回答され、「ですよね……」みたいな顔してしまいましてねうへへ。

samba 界隈の話題をたどると、わりと「おいハングしてんだけど?」という話題に事欠かないようなので、アップデート出たら即座に当てて検証してみる、とかしかないでしょう。mount.cifs もバグ報告しても「最新版当てろよ」みたいな話らしいので…。最新版があたってて、mount.cifs のバージョンと接続先サーバの情報も提出してたらどうなるんでしょうね、コード読めってなんのかな?Kernel 以外なら最初から読んだほうが早そう(震え声)。

なお 10 分毎に touch するコマンドを cron に仕込んでも再発したけど治った

再発しなくなったー!と喜んでましたが翌日に再発しました、意味わからんね?とここで思考停止したんですが、鯖屋から「LB のベンダにエスカレーションしたいからどこで問題なのか切り分けしよ?」と言われ、まずどのような状況で通信が切断されるか調査しよう、ということになり該当の Web サーバから、NAS へ 15 秒毎に ping を送信し、送信失敗したらメールで通知する、というスクリプトを同僚が設置してくれました。

はい、その結果切断がなくなりました。本気でこれもう意味わかんねえな……。lsof で通信するポート見てた同僚いわく「ping スクリプト仕込んでから、通信に利用してるポートかわらなくなったなー、一度確立したコネクションが切断されないからタイムアウトなくなって改善したって事じゃね?」みたいな返答をされリアルで「oh…(^o^)」って顔になった。

という訳で、とりあえず似たような現象でお困りの諸氏は、cron にて 15秒毎位を目安に ping を一回だけ対象の NAS に向かって発射する、とか試してみると解決するかもしれません。もう小生やだー(ジタバタ)。


ちなみにロケ地は CentOS6.4 です。