技術の家庭菜園

https://tpcbtw.com/

再帰により制限時間を超えたスクリプトを実行する

問題点とその背景

HPCマシン、より一般的な言い方をすればスパコンクラスタと呼ばれるマシンであるが、これらはその殆どが高速なネットワークによってクラスタリングされた単体動作可能なLinuxマシンである。
さて、特に大規模なHPCマシンは1つの部署や1つの研究室が所有しているということは珍しい。多くはそのマシンを管理する専門の部署や、もしくは大学直下の研究センター、もしくは独立行政法人等が管理し、多数の利用者がそれを使うということになる。

利用者が増えれば、それだけマシンの負荷は増える。
特に広く用いられているTORQUEシステムやPBSシステムにおいては、計算ノードの資源を指定した分を排他的に使える代わりにジョブ待ちが多く発生し、また皆が作業するログインノードでは慢性的に資源不足に陥る。
これを解決するためにその管理団体は様々な対策を講じる。ログインノード自体の強化をしてくれる団体は素晴らしいが、概ねその対策というのはユーザーに対する制限である。
例えばとあるスパコンにおいては、計算ジョブの長さは例外はあるものの最大24時間とされ、ログインノードでの最大作業時間は10分未満となっている。
ジョブの長さが24時間なのはせめて許そう。そのような長い計算を投げるならば定期的にデータを書き出しリスタートが可能な状態にできるプログラムが多い。
24時間後にジョブを再投入すれば良いのだから、その問題は解決できる。

しかし、ログインノードで10分しか作業ができないのは頂けない。
ジョブの逐次実行用のスクリプトを投げても10分後には自動的にkillされてしまう。
これでは作業もままならない。困ったものである。

対策

しかしこの自動的にkillする仕組みはどうやらプロセスIDでプロセスを判別し、10分以上のプログラムを検出するとそれに対しシグナルを送ることで実装されているようだ。まぁほとんどの監視スクリプトがこのような実装ではないだろうか。
そうであるならば、対策は簡単である。我々のスクリプトのループを再帰呼び出しに置き換え、PIDを変え続ければいいのだ。
例えば以下のようなスクリプトを考える。

#!/bin/sh
while [ ! -f ./DONE ];
do
	./a.out
done

これはカレントディレクトリにDONEというファイルが生成されるまでa.outを回すという簡単なスクリプトである。
これを以下のように書き換える。

#!/bin/sh
if [ -f ./DONE ]; then
	exit 0
fi
./a.out
$0 &

最初のスクリプトにあったwhileループがなくなり、判定条件のみif文で残してある。
最後の"$0 &"が重要である。$0には自身のスクリプト名が入る。
つまり最後に自身を再帰呼び出しして、冒頭から実行し直しているのだ。
効果としてはwhileループと大きな差はない。しかし新しくスクリプトを実行していることになるのでPIDは変わるのだ。
これによりくだらない10分制限などは回避することができる。

ループがあるスクリプトなど使用用途は若干限定されるかもしれないが、これが私の環境では現状かなり有効となっている。
これもいつまで有効かはわからないが、もしかしたら貴方の環境では役に立つかもしれない。
もちろん見つかったら管理者に怒られるだろうので、自己責任でお願いしたいが。