Write data() 関数のエラーログでディスク領域が使い果たされる

提供:Samba-JP
J13から転送)
ナビゲーションに移動検索に移動
KB番号 J0013
最終更新日 2001/06/15
作成者 たかはしもとのぶ
最終更新者

対象

この文書は、以下のプロダクトに付いて説明したものです。

  • Samba 2.0.9 日本語版
  • Samba 2.0.7 日本語版リリース2.2
  • Samba 2.0.7 日本語版リリース2.1
  • Samba 2.0.7 日本語版リリース2.0
  • Solaris 2.6
  • Solaris 2.5.1
  • Linux

概要

Samba 2.0.7 日本語版リリース2.0以降の source/lib/util.c にある transfer_file() 関数には write_data() 関数でエラーが発生すると while ループを抜けられなくなるという潜在的なバグがあります。Solaris 2.x や Linux の一部のバージョンではこのバグが顕在化することがあります。 このバグが顕在化した場合、ループ中で以下のようなレベル0のエラーログが無限に出力され、ディスク領域が使い果たされます。

[2001/03/02 09:08:29, 0] lib/util_sock.c:write_data(508)
  write_data: write failure. Error = Broken pipe
[2001/03/02 09:08:29, 0] lib/util_sock.c:write_data(508)
  write_data: write failure. Error = Broken pipe
[2001/03/02 09:08:29, 0] lib/util_sock.c:write_data(508)
  write_data: write failure. Error = Broken pipe
[2001/03/02 09:08:29, 0] lib/util_sock.c:write_data(508)
  write_data: write failure. Error = Broken pipe

この出力は max log size パラメータの設定で抑止することができません。

この現象は Samba 2.0.7 日本語版リリース2.0以降のバージョン固有の事象です。それ以外のバージョンはこの部分のロジックが異なるため、この現象は発生しません。

詳細

source/lib/util_sock.c 中の write_data() 関数は、通常戻り値として書き込んだデータ量(バイト)を返却しますが、何らかの原因で内部で呼び出している write() に失敗した場合、戻り値として -1 を返却します。

write_data() は、source/lib/util.c 中の transfer_file() 関数の while() ループ中で呼び出されています。このループは write_data() 関数の戻り値で返却される書き込んだデータ量が一定量(SMBヘッダのサイズ)を越えるまでループし続けますが、write_data() の戻り値で -1 が返却された場合の処理が定義されていないため、-1 が返却され続けるとループを抜けることができません。

write_data() 関数で -1 が返却される場合は、通常ソケット通信が強制的に切断されたなどの恒常的なものであるため、一度 -1 が返却されると以後 0 以上の値が返却される見込みはありません。 更に、write_data() 関数で -1 が返却された場合、レベル0で以下のようなログが出力されます。

[2001/03/02 09:08:29, 0] lib/util_sock.c:write_data(508)
  write_data: write failure. Error = Broken pipe

このログは無限に出力され続けるためログの出力先ディスクが使い果たされてしまいます。

なお、max log sizeパラメータでログの最大容量を制限していた場合でも、このループに入り込んでしまった場合、ログの容量をチェックするルーチンが実行されないため、制限を越えて無限にログが増え続けてしまいます。

対処方法

Solaris 2.6では2001年2月現在の推奨パッチを適用することで問題を引き起こす事象の発生を抑制できます。 問題が発生してしまった場合の対応に付いては、現在検討中です。

この技術情報は samba-jp:10004 などからの一連のスレッドの議論を元に作成されています。