Linuxサーバ関連情報 > PerlでNFS上のファイルロックの仕方
Perlでよく使われるflockはNFS上のファイルをロックする保障がされていません。
そこでfcntlを使ってファイルロックすることにします。
NFS上のファイルをflockでファイルロックできるのか?検証
Debian Etchを使ってNFS上のファイルをflockでロックするとどうなるか?
ロックはできましたが、ロックが開放されません。プロセスが終了すればロックが解除されますが、同じプログラム内で2回以上ロックするような処理では
画面が固まってしまう現象がありました。
他にもロックすらできない現象もありますが、kernelのバージョンとNFSのバージョンによって挙動はさまざまです。
比較的に新しいkernelとNFSのバージョンでおかしな挙動をするようです。
fcntlを使ってみよう
perlでファイルロックの仕方はflock以外にもlockfやfcntlがありますが、今回はfcntlを使ったファイルロックの仕方を説明します。
#!/usr/bin/perl
use Fcntl; my $filepath = '/home/hoge/test.txt'; my $sdata = 'test'; # ロックのオプションを設定 my ($locked) = pack("ssL", Fcntl::F_WRLCK, 'SEEK_SET', 0); ① # ロック解除のオプションを設定 my ($unlocked) = pack("ssL", Fcntl::F_UNLCK, 'SEEK_SET', 0); ② # ファイルオープン open(F, "+< $filepath") or &error($filepath); # ロック fcntl(F, F_SETLK, $locked) or &error('ロックできませんでした。'." $$ @_: $!"); ③ # ファイル書き込み truncate(F, 0); seek(F, 0, 0); print(F $sdata); # 解除 fcntl(F, F_SETLK, $unlocked) or &error('ロック解除できませんでした。'); ④ close(F); print "Content-type: text/html; charset=EUC-JP\n\n"; print "OK!"; exit; sub error { my $data = shift; print "Content-type: text/html; charset=EUC-JP\n\n"; print $data; exit; } |
① ②
fcntlの第3の引数に渡す構造体を作成します。perlの場合、packする必要があります。
③
fcntl関数でロックします。
第1引数:ファイルハンドラ
第2引数:オプションです。今回ロックするために必要なオプションを紹介します。
【F_SETLK】ファイルのロックする場合、既にロックされている場合エラーを返します。
【F_SETLKW】ファイルのロックをする場合、既にロックされている場合は解除されるまで待ちます。
第3引数:① ②でpackしたスカラー変数
④
ロックしたファイルを解除します。この一行を書かなくても、ファイルをcloseすればロックは解除されます。
NFS上でファイルをロックするためのサーバ設定
NFS上のファイルをロックするためにはNFSサーバ側とマウントする側のどちらにもstatdとlockdが必要になります。
DEBIANの場合apt-get install nfs-commonしてnfs-commonを起動するとstatdとlockdが立ち上がります。
これをしないとNFS上のファイルをロックできません。