저는 애플리케이션이 정상적인 동작의 일부로 여러 하위 프로세스를 생성하는 Debian Wheezy를 실행하는 시스템을 개발 중입니다. 대부분의 경우 상위 애플리케이션이 종료되면 모든 하위 애플리케이션이 지워진 다음 종료됩니다. 그러나 컴퓨터를 종료/다시 시작하면 종료되기 전에 몇 분 동안 멈추는 경우가 많습니다. 머신은 원격/헤드리스이므로 내 쪽에서 보는 것은 시스템이 종료되고 SSH 세션이 종료되고 로그인을 시도할 때 연결 거부 오류가 발생한다는 메시지뿐입니다. /var/log/syslog를 찾아보니 다음과 같은 항목이 표시됩니다.
[ 3840.402493] INFO: task child_process:4455 blocked for more than 120 seconds. [ 3840.402579] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 3840.402684] child_process D c109bbf8 0 4455 3702 0x00000000 [ 3840.402691] f79c7b00 00000046 00000001 c109bbf8 f0bed5b0 333f9aaa 00000351 c1483b00 [ 3840.402703] c1483b00 00000292 c109bcf9 00000292 00000000 f2c005a0 00000000 edd1fd34 [ 3840.402714] 00000292 c109bebf c10abe25 00000001 f2bd4740 00000000 00000001 c109bc0a [ 3840.402726] Call Trace: [ 3840.402733] [] ? free_pages_prepare+0xc0/0xf1 [ 3840.402741] [] ? free_hot_cold_page+0x3d/0xf7 [ 3840.402749] [] ? __pagevec_free+0x3e/0x55 [ 3840.402756] [] ? page_address+0x1b/0x85 [ 3840.402763] [] ? free_pages_prepare+0xd2/0xf1 [ 3840.402771] [] ? __mutex_lock_common.isra.6+0x11d/0x132 [ 3840.402778] [] ? mutex_lock+0x15/0x21 [ 3840.402785] [] ? tty_release+0x3d/0x400 [ 3840.402794] [] ? ip_mc_del_src+0xf1/0x12e [ 3840.402801] [] ? ip_mc_leave_src+0x22/0x68 [ 3840.402809] [] ? kmem_cache_free+0x23/0x55 [ 3840.402816] [] ? fput+0xd7/0x161 [ 3840.402822] [] ? filp_close+0x54/0x5a [ 3840.402828] [] ? put_files_struct+0x4b/0x88 [ 3840.402834] [] ? do_exit+0x237/0x60d [ 3840.402842] [] ? recalc_sigpending+0xf/0x2f [ 3840.402849] [] ? dequeue_signal+0xb4/0x126 [ 3840.402855] [] ? do_group_exit+0x56/0x83 [ 3840.402863] [] ? get_signal_to_deliver+0x43b/0x465 [ 3840.402871] [] ? do_signal+0x32/0x52c [ 3840.402879] [] ? update_rmtp+0x45/0x45 [ 3840.402886] [] ? do_futex+0x99/0x6c6 [ 3840.402893] [] ? read_tsc+0xa/0x28 [ 3840.402901] [] ? timekeeping_get_ns+0x10/0x47 [ 3840.402907] [] ? sys_futex+0xbb/0x10f [ 3840.402915] [] ? do_notify_resume+0x1e/0x5c [ 3840.402922] [] ? work_notifysig+0x13/0x1b [ 3840.402929] [] ? start_cpu_timer+0x39/0x62 [ 3840.402935] [] ? vmstat_cpuup_callback+0x18/0x5a
재부팅 요청이 이루어진 후 시스템이 실제로 종료되기 전의 여러 하위 프로세스에 대한 항목입니다.
관련될 수 있는 점은 때때로 부모 응용 프로그램이 종료된 후 자식 응용 프로그램을 실행 상태로 두는 경우가 있다는 것입니다. 이러한 프로세스를 수동으로 종료하기 위해 기본적으로 다음으로 구성된 스크립트가 있습니다.
#!/bin/bash
killall -q parent_process
killall -q child_1
killall -q child_2
#etc...
수동으로 실행하면 이 스크립트는 모든 프로세스를 안정적으로 종료하고 중단되지 않습니다. 또한 하위 프로세스를 수동으로 시작하면 이 동작이 중단되거나 나타나지 않습니다.
내 직감에 따르면 상위 응용 프로그램이 하위 프로세스를 제대로 정리하지 않는 것이 문제이지만 불행히도 상위 프로세스는 독점 내부 응용 프로그램이므로 구현을 변경할 수 없으므로 해결 방법을 찾으려고 노력했습니다. . 종료/다시 시작하기 전에 killall 스크립트를 수동으로 실행하면 종료가 지연되지 않으므로 종료/다시 시작 시 스크립트를 실행하는 방법을 찾으려고 노력했습니다.
나의 첫 번째 시도는 Killall 스크립트를 /etc/init.d에 복사한 다음 K01killstuff로 rc0.d 및 rc6.d에 연결하는 것이었지만 작동하지 않았기 때문에 적절한 init 스크립트를 작성하기로 결정했습니다. 나는 /etc/init.d의 프레임워크로 시작했고 다음을 얻었습니다:
#! /bin/sh
### BEGIN INIT INFO
# Provides: killstuff
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Stop: 0 1 6
# Short-Description: Stop applications
# Description: This file should be used to construct scripts to be
# placed in /etc/init.d.
### END INIT INFO
# Author:
#
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Description of the service"
NAME=daemonexecutablename
DAEMON=/usr/sbin/$NAME
DAEMON_ARGS="--options args"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$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 stops the daemon/service
#
do_stop()
{
killall -q parent_process
killall -q child_1
killall -q child_2
}
case "$1" in
start)
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping Applications"
do_stop
;;
status)
;;
restart|force-reload)
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:
스크립트를 테스트하여 /etc/init.d/killstuff stop
예상한 모든 프로세스가 종료되었음을 확인한 후 실행하여 update-rc.d killstuff defaults
링크가 rc0.d 및 rc6.d에 생성되었지만 재부팅 시 시스템이 여전히 중단되는 것을 확인했습니다. 이로 인해 이러한 프로세스는 종료 순서 초기에 종료되어야 한다고 믿게 되었습니다.
그러면 어디에서 킬 스크립트를 호출할 수 있나요? 아니면 시스템을 보다 원활하게 종료하기 위해 시스템이 종료되기 전에 모든 응용 프로그램을 종료하는 것 외에 시도할 수 있는 다른 방법이 있습니까?