2014-03-06 5 views
0

를 전송하지 나는SIGTERM

#include <unistd.h> 
#include <signal.h> 
#include <sys/stat.h> 

#include <fstream> 
#include <iostream> 

#include <boost/thread.hpp> 

bool running = true; 
std::ofstream log_output; 

void close_log_output() 
{ 
    log_output.close(); 
} 

void signal_handler(int) 
{ 
    running = false; 
} 

int detach_service() 
{ 
    if(pid_t pid = fork()) exit(pid < 0); 
    umask(0); 
    close(STDIN_FILENO); 
    close(STDOUT_FILENO); 
    close(STDERR_FILENO); 
    chdir("/"); 
    log_output.open("/var/log/mydaemon.log"); 
    std::cout.rdbuf(log_output.rdbuf()); 
    std::cerr.rdbuf(log_output.rdbuf()); 
    std::clog.rdbuf(log_output.rdbuf()); 
    atexit(&close_log_output); 
    signal(SIGTERM, &signal_handler); 
    return (setsid() < 0); 
} 

int main(int argc, char **argv) 
{ 
    if(int err = detach_service()) return err; 
    while(running) boost::this_thread::sleep(boost::posix_time::milliseconds(30)); 
    std::cout << "terminated\n"; 
    return 0; 
} 

아래로 비등 간단한 데몬과 조정 $NAME, $DAEMON$DAEMON_ARGS 그냥 원래 골격 인있는 init.d 스크립트가 있습니다. PID를 통해 프로세스를 종료하면 SIGTERM을 수신하고 올바르게 종료되지만 서비스를 중지하려고 시도하면 (기본적으로 TERM을 보내도록 설정되어 있음) 명령이 중지되고 프로세스가 SIGTERM을받지 않고 종료됩니다. 프로세스가 원본에 비해 변경 (중 쉘 측 또는 C++ 쪽)

수정 해골 (단지 이름과 DAEMON_ARGS 올바르게 종료되도록 내가/변경을해야 할 무엇

우분투있는 init.d 골격) :

#! /bin/sh 
### BEGIN INIT INFO 
# Provides:   skeleton 
# Required-Start: $remote_fs $syslog 
# Required-Stop:  $remote_fs $syslog 
# Default-Start:  2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: Example initscript 
# Description:  This file should be used to construct scripts to be 
#     placed in /etc/init.d. 
### END INIT INFO 

# Author: Foo Bar <[email protected]> 
# 
# Please remove the "Author" lines above and replace them 
# with your own name if you copy and modify this script. 

# Do NOT "set -e" 

# PATH should only include /usr/* if it runs after the mountnfs.sh script 
PATH=/sbin:/usr/sbin:/bin:/usr/bin 
DESC="Description of the service" 
NAME=mydaemon 
DAEMON=/usr/sbin/$NAME 
DAEMON_ARGS="" 
PIDFILE=/var/run/$NAME.pid 
SCRIPTNAME=/etc/init.d/$NAME 

# Exit if the package is not installed 
[ -x "$DAEMON" ] || exit 0 

# Read configuration variable file if it is present 
[ -r /etc/default/$NAME ] && . /etc/default/$NAME 

# Load the VERBOSE setting and other rcS variables 
. /lib/init/vars.sh 

# Define LSB log_* functions. 
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present 
# and status_of_proc is working. 
. /lib/lsb/init-functions 

# 
# Function that starts the daemon/service 
# 
do_start() 
{ 
     # Return 
     # 0 if daemon has been started 
     # 1 if daemon was already running 
     # 2 if daemon could not be started 
     start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ 
       || return 1 
     start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ 
       $DAEMON_ARGS \ 
       || return 2 
     # Add code here, if necessary, that waits for the process to be ready 
     # to handle requests from services started subsequently which depend 
     # on this one. As a last resort, sleep for some time. 
} 

# 
# Function that stops the daemon/service 
# 
do_stop() 
{ 
     # Return 
     # 0 if daemon has been stopped 
     # 1 if daemon was already stopped 
     # 2 if daemon could not be stopped 
     # other if a failure occurred 
     start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME 
     RETVAL="$?" 
     [ "$RETVAL" = 2 ] && return 2 
     # Wait for children to finish too if this is a daemon that forks 
     # and if the daemon is only ever run from this initscript. 
     # If the above conditions are not satisfied then add some other code 
     # that waits for the process to drop all resources that could be 
     # needed by services started subsequently. A last resort is to 
     # sleep for some time. 
     start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON 
     [ "$?" = 2 ] && return 2 
     # Many daemons don't delete their pidfiles when they exit. 
     rm -f $PIDFILE 
     return "$RETVAL" 
} 

# 
# Function that sends a SIGHUP to the daemon/service 
# 
do_reload() { 
     # 
     # If the daemon can reload its configuration without 
     # restarting (for example, when it is sent a SIGHUP), 
     # then implement that here. 
     # 
     start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME 
     return 0 
} 

case "$1" in 
    start) 
     [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 
     do_start 
     case "$?" in 
       0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 
       2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 
     esac 
     ;; 
    stop) 
     [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 
     do_stop 
     case "$?" in 
       0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 
       2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 
     esac 
     ;; 
    status) 
     status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? 
     ;; 
    #reload|force-reload) 
     # 
     # If do_reload() is not implemented then leave this commented out 
     # and leave 'force-reload' as an alias for 'restart'. 
     # 
     #log_daemon_msg "Reloading $DESC" "$NAME" 
     #do_reload 
     #log_end_msg $? 
     #;; 
    restart|force-reload) 
     # 
     # If the "reload" option is implemented then remove the 
     # 'force-reload' alias 
     # 
     log_daemon_msg "Restarting $DESC" "$NAME" 
     do_stop 
     case "$?" in 
      0|1) 
       do_start 
       case "$?" in 
         0) log_end_msg 0 ;; 
         1) log_end_msg 1 ;; # Old process is still running 
         *) log_end_msg 1 ;; # Failed to start 
       esac 
       ;; 
      *) 
       # Failed to stop 
       log_end_msg 1 
       ;; 
     esac 
     ;; 
    *) 
     #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 
     echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 
     exit 3 
     ;; 
esac 

: 
+0

해골 초기화 스크립트의 관련 부분을 제공하십시오. – user2719058

+0

원래 질문에서 변경된 사항을 이미 말했지만 완료되었습니다. – Joe

+1

그래도 모든 해골이 같지는 않습니다. 귀하의 정보를 제공해 주셔서 감사합니다. – user2719058

답변

1

당신의 데몬은 pidfile을 생성하지 않으며, 어느 쪽도하지 않습니다이 start-stop-daemon 않습니다. --pidfile 프로세스 선택 기준을 만족 결코 때문에,

start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME 

이 아무것도하지 않는 첫 번째 줄을 생각하지만, --pidfile 옵션이 포함되지 여기에 있기 때문에 두 번째 줄

start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON 

SIGKILL와 데몬을 .

pidfile을 작성하려면 데몬을 수정해야합니다.

+0

좋아,하지만 pidfile을 올바르게 작성하려면 어떻게해야합니까? start-stop-daemon 옵션에'--make-pidfile'을 추가 할 수 없습니다. – Joe

+0

'--stack-daemon'을위한'--make-pidfile' 옵션은 망가진 데몬의 일시적인 해결책이며, 맨 페이지에는 데몬을 포크하는 데 도움이되지 않습니다. 데몬 자체가 생성하게하십시오. 올바른 방법입니다. – user2719058

+0

분명히. 나는 오히려 사람이 데몬에서 올바르게 어떻게 그 일을 하는가? 그냥 fopen, fprintf 및 fclose? – Joe

관련 문제