[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FDclone-users:00493] Re: .fd_history was lost
- Subject: [FDclone-users:00493] Re: .fd_history was lost
- From: Takashi SHIRAI <shirai@unixusers.net>
- Date: Mon, 10 Apr 2006 23:13:29 +0900
しらいです。
In Message-Id <86wtdyeiml.knu@iDaemons.org>
"Akinori MUSHA" <knu@iDaemons.org>さんwrites:
> ホームディレクトリを NFS マウントして運用しているのですが、
> この環境ではファイルのロックがサポートされていないために、
> shell.c:savehistory() の Xfopen(file, "w") → lockfile() の
> ところで失敗し、そのまま Xfclose() されて ~/.fd_history が
> 空っぽになってしまいます。
ふむ。確かに NFS では lock が効かないので link(2) 辺りを使
って疑似 lock をかけるのが定石ですね。
最近の NFS は普通に lock がかかってしまうものが多いので忘
れていました。これは相手先の条件もあるので、やってみないこと
には lock 不能な file system かどうかは判断不能ですね。
> 1. 別にロックファイルを作る
> 2. open(2) の O_EXLOCK でアトミックにロックする
> 3. 追記モード(a, a+, r+)でオープンして truncate させない
O_EXLOCK は BSD 固有の option なので余り適切ではなさそうで
す。
また、2. と 3. とは lock 不能だった場合にコマンド履歴が保
存されないので、使い勝手としては truncate されてしまうのと大
差ないと思います。
ちゃんとやるなら、fcntl lock に失敗した時点で link lock を
試すといった手法になるでしょうかね。
> csh, tcsh, ash, bash (libreadline) などはファイルロック自体
> していないようでした。同じユーザで対話シェルを同時に起動または
> 終了するというケースはまれと見たからかもしれません。
実際に .fd_history が壊れたという事例があったんで lock を
実装したんですが、余り気にしないでもいいということでしょうか
ね。
そういうことであれば、fcntl lock で実装しておいて返り値は
無視するという実装でどうでしょうかね。
blocking lock にしてるので、返り値を無視したところで lock
が有効な環境では普通に lock がかかる筈です。lock が無効な環
境でのみ、file の同時書込みに対応出来ないということで。
link lock の実装は、作成した lock file の後始末が面倒なん
ですよね。割込まれた時とか異常終了した時とか考えると、そこま
で苦労して実装することもないかと。
# MHpopd の実装を見たら、わざわざ getmntinfo(3) 辺りを使っ
#て NFS かどうか調べてから lock かけてるらしい。何故そこま
#でする必要が...:-)
---- Cut Here ----
diff -u ../old/FD-2.08b/shell.c ./shell.c
--- ../old/FD-2.08b/shell.c Thu Mar 30 00:00:00 2006
+++ ./shell.c Mon Apr 10 22:45:35 2006
@@ -1630,12 +1630,7 @@
int i, j, size;
if (!file || !(fp = Xfopen(file, "r"))) return(-1);
-#ifndef NOFLOCK
- if (lockfile(Xfileno(fp), LCK_READ) < 0) {
- Xfclose(fp);
- return(-1);
- }
-#endif
+ VOID_C lockfile(Xfileno(fp), LCK_READ);
size = (int)histsize[n];
history[n] = (char **)malloc2(sizeof(char *) * (size + 1));
@@ -1650,7 +1645,7 @@
for (j = i; j > 0; j--) history[n][j] = history[n][j - 1];
history[n][0] = line;
}
- lockfile(Xfileno(fp), LCK_UNLOCK);
+ VOID_C lockfile(Xfileno(fp), LCK_UNLOCK);
Xfclose(fp);
for (i++; i <= size; i++) history[n][i] = NULL;
@@ -1684,16 +1679,11 @@
if (!history[n] || !history[n][0]) return(-1);
if (!file || !(fp = Xfopen(file, "w"))) return(-1);
-#ifndef NOFLOCK
- if (lockfile(Xfileno(fp), LCK_WRITE) < 0) {
- Xfclose(fp);
- return(-1);
- }
-#endif
+ VOID_C lockfile(Xfileno(fp), LCK_WRITE);
size = (savehist > (int)histsize[n]) ? (int)histsize[n] : savehist;
for (i = size - 1; i >= 0; i--) convhistory(history[n][i], fp);
- lockfile(Xfileno(fp), LCK_UNLOCK);
+ VOID_C lockfile(Xfileno(fp), LCK_UNLOCK);
Xfclose(fp);
return(0);
---- Cut Here ----
しらい たかし