CentOS 7はSysVinitによるサービス管理をsystemdがサポートしている.
今回は1プロセスのみ起動するプログラムをデーモン化する.
デーモン化までの処理
ProgramのPIDをユーザ領域に記録するため,Shellを挟む流れとした.
SysVinit -> Shell -> Program
構成
/etc/init.d/
tick ... デーモン起動スクリプト
/home/username/daemon-sample/
exec-tick.sh ... Shell
tick ... プログラム
ick.pid ... PIDファイル
Program
10秒毎に標準出力に”Tick”と表示するだけ.
tick.c
#include <stdio.h>
int main(int argc, char* argv) {
while(1) {
printf("Tick\n");
sleep(10);
}
}
Shell
バックグラウンドでプログラムを起動させ,PIDを記録する.
exec-tick.sh
#!/bin/bash
PROG_PATH="/home/username/daemon-sample/"
PROG="tick"
PID="tick.pid"
echo -n "arg:"
echo $*
"${PROG_PATH}${PROG}" $* &
echo -n "pid: "
echo $!
echo $! > "${PROG_PATH}${PID}"
SysVinit
start()で--user
オプションを付ければ,指定ユーザで起動する.
daemon
, killproc
は. /etc/init.d/functions
で定義されたスクリプトの関数.
/etc/init.d/tick
# Source function library.
. /etc/init.d/functions
PROG_PATH="/home/username/daemon-sample/"
SCRIPT_NAME="exec-tick.sh"
SCRIPT="${PROG_PATH}${SCRIPT_NAME}"
PROG_NAME="tick"
EXEC_USER=username
start() {
echo -n "Starting tick: "
touch /var/lock/subsys/tick
daemon --user=$EXEC_USER $SCRIPT hoge fuga foo
echo -n "pid "
echo $!
return 0
}
stop() {
echo -n "Shutting down tick: "
rm -f /var/lock/subsys/tick
killproc $PROG_NAME
echo $!
return $!
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
echo -n "/var/log/subsy/tick "
cat /var/log/subsys/tick
;;
restart)
stop
start
;;
*)
echo "Usage: <servicename> {start|stop|status|reload|restart[|probe]"
exit 1
;;
esac
exit $?
お手本になる起動スクリプトは以下@ CentOS Linux release 7.1.1503 (Core)
/usr/share/doc/initscripts-9.49.24/sysvinitfiles
動作確認
root権限で起動
# /etc/init.d/tick start
Starting tick (via systemctl): [ OK ]
ユーザ権限で実行されており.制御端末とも切り離されている.(?
となっている部分)
$ps ux
username 15788 0.0 0.0 4164 352 ? S 14:57 0:00 /home/username/daemon-sample/tick hoge fuga foo
root権限で停止
# /etc/init.d/tick stop
Stopping tick (via systemctl): [ OK ]