Subject: Re: qmail start up on OSF/1
From: [email-masked] (HASHIMOTO, Tsuyoshi)
Date: 15 Jul 1997 11:23:12 +0900
Newsgroups: fj.sys.alpha,fj.unix,fj.mail

橋本（つ）＠富士通です．

In article <[email-masked]>
[email-masked] (Kawaguti Ginga) writes:

>   /sbin/rc3.d/S41qmail という script をつくってその中で
>   /usr/bin/env - PATH="/var/qmail/bin:$PATH" /bin/csh -cf 'qmail-start ./Mailbox splogger qmail &'
             ^^^^^^^
推測（後述するような方法で当たっているか確認は可能）ですが，SysV 系の 
OS において，自分自身で daemon になるための処理を持っていない program 
を boot の時の起動 script 内 で & つきで単純に起動すると，親の script 
の終了時に（後述する理由で） SIGHUP を受けて消滅する事が，問題の原因に
なっている思います．

プロセスが（どの）シグナルを受けたために消滅したかは，process accouning 
機能を有効にしておけば，acctcom -f で表示される status で分かります．
（ここでいう 'status' は header が STAT の欄です．signal を受けて消滅
した場合はシグナル番号が８進数で，そうでない (exit() システムコールを
呼んだ場合) は 0 が表示されます．）

システム管理まわりは platform 依存性が大きいので，process accounting 
の詳細は，システム管理者用のマニュアルを見て下さい．man コマンドでの 
acctcom(1), acct(1M) などにも説明があると思いますが ...

もっとも，次のように書いて回避できれば，acctcom -f での確認はなくとも，
SIGHUP で消滅していたという事になりそうです．

#!/bin/sh
# 次の行を入れて SIGHUP を無視 (signal 無視の指定は fork/exec 後も有効)
trap '' 1
/usr/bin/env - PATH="/var/qmail/bin:$PATH" /bin/csh -cf 'qmail-start ./Mailbox splogger qmail &'

あるいは，(shell script にしてしまう以上，) 次のように書く方が， env 
コマンドを使うより，むしろ普通かも知れません．とりあえず，こうして回避
できるか試す意味があります．

#!/bin/sh
trap '' 1
PATH="/var/qmail/bin:$PATH"
export PATH
exec /bin/csh -cf 'qmail-start ./Mailbox splogger qmail &'

SIGHUP を無視するには，nohup(1) を使う事もできるでしょう．

さて，SIGHUP を受けていると考えられる理由は，後述する 'session' につい
ての SysV の仕様です．

OSF/1 D3.2 がどういう形で SysV (多分 SVR4) 系の仕様を取り込んでいるか
知らないので，とりあえず SVR4(System V Release 4) の用語によって説明
します．

/sbin/rc? （を実行する shell ）のように，ある端末（ boot の時なら 
console ）を他の process が open していない状態で open() する process 
は，その子孫の processes から構成され，その端末を「制御端末」とする 
'session' の 'session leader' になります．session leader が消滅した時
に，session 全体に SIGHUP を送る」という動作は，SVR4 系の UNIX の仕様
です．(SysV 系の仕様として SVR2 の頃からあり，当時は上の説明での
session の事を process group と呼んでいました．（ SVR4 以前の SysV は 
BSD job control のサポートがなかったので，session と process group を
区別していませんでした．）

「自分自身で daemon になるための処理を持っていない」program は，「端末
から自分を切り離す処理を持っていない」し「 SIGHUP を無視する処理も持っ
ていない」のが普通なので，上記仕様により SIGHUP を受ければ，消滅します．
＃ daemon になるための処理を持っている program でも，書き方がまずいと，
＃端末からの切り離しや SIGHUP handler 登録処理がまにあわずに，消滅します．
＃「 daemon の起動の後に sleep 3 と書くと動いた」などのパターンがこれです．

なお，端末から切り離す (setsid(2) や setpgrp(2) を参照) 事による回避も，
単に setsid(2) (or setpgrp(2))を実行した後に，指定した program を 
exec(2) するだけの機能を持つコマンドを用意すれば可能です．この方法の方
が，ある意味では本筋と言えるかも知れません．

＃ SVR4 系のマシンでは（マニュアルには必ずしも出ていないが /usr/bin に）
＃setpgrp というコマンドが多分あると思います．（なくても同等機能の自作
＃は容易でしょう．）

>   これは、なにか私が"常識"を欠いている所為なのでしょうか?

上の仕様は，マニュアルなどに分かりやすい形で文書化されている事が少ない
せいか，時にトラブルの原因になるようです．intro(2) や termio(7) などの
説明や setsid(2) ないし setpgrp(2) の説明から分かる場合もあるのですが，
OS （のマニュアル）によっては，説明がなかったり，「これで分かれという
方が無理」な説明の場合が多くあります．マニュアルに分かりやすく出ている
なら，そのマニュアルは，「きちんとしている」と評価して良いと思います．

市販の書籍での説明では，Prentice Hall から出ている Goodheart & Cox の 
"The Magic Garden Explained" （「 UNIX カーネルの魔法」という題で和訳
も出ていたと思います．）での疑似コードくらいでしか，上の仕様の記述を見
た記憶がありません．もっとも，記述が丁寧な SysV 系のシステム管理の本に
なら，出ていてもおかしくはないとは思います．
-- 
[name] 橋本　剛 [office] 富士通 HPC 本部)二開統)