CentOS 6, service с несколькими процессами
ну или выяснить, почему процесс не убивается
Как вообще отлаживать init скрипты, этот killproc же простым смертным недоступен?
набери в терминале
. /etc/init.d/functions
[co-sslmailproxy ~]# ps xao pid,ppid,pgid,sid,comm
PID PPID PGID SID COMMAND
2118 1 2109 1996 stunnel
2119 1 2109 1996 stunnel
2120 1 2109 1996 stunnel
2121 1 2109 1996 stunnel
2122 1 2109 1996 stunnel
2123 1 2123 2123 stunnel
У всех родитель инит (удивительное рядом =) ), но последний, который отказывается убиваться, отличается иным PGID и SID. Это так и нужно?
Нашел в конфиге строчки
setuid = nobody
setgid = nobody
для пробы закомментировал - ничего не поменялось. Как узнать, что это за группы и сессии?
может эта штука просто не обрабатывает сигнал?
попробуй команду killallЯ хз, когда ее убиваешь через killall, она в логе пишет
может эта штука просто не обрабатывает сигнал?
2015.01.29 14:02:09 LOG5[2038:140694512555968]: Received signal 15; terminating
2015.01.29 14:02:09 LOG7[2038:140694512555968]: removing pid file /stunnel.pid
вроде бы 15 - это SIGTERM, и killproc вроде тоже посылает его.
заменить его на killall я тоже уже пробовал, получаю вообще китайскую грамоту:
[co-sslmailproxy ~]# vi /etc/init.d/stunnel
[co-sslmailproxy ~]# service stunnel stop
Shutting down stunnel: /sbin/service: line 66: 1568 Terminated env -i PATH="$PATH" TERM="$TERM" "${SERVICEDIR}/${SERVICE}" ${OPTIONS}
[co-sslmailproxy ~]#
И хоть процессы и убились, но инит скрипт на этом вылетел, не удалив лок файл
И хоть процессы и убились, но инит скрипт на этом вылетел, не удалив лок файлОн сам себя, случаем, не убивает?
Shutting down stunnel: /sbin/service: line 66: 1568 Terminated env -i PATH="$PATH" TERM="$TERM" "${SERVICEDIR}/${SERVICE}" ${OPTIONS}
killall `which stunnel`
Не конечно зелененького [OK] об остановленном процессе, но это уже ^_^
Спасибо!
ну теперь можно разобраться в коде функции killproc чтоб посмотреть, что она делает не так
Убивать все похожие процессы, конечно, самый лучший подход,
чисто линуксовый.
---
A25: линуха рулит, а вы все остальные - в гробу сасёте, разлагаитись,
ваняити и абастряитись.. вот!
Это означает, что процесс получил сигнал и завершился с соответствующим статусом.
Оно же намекает на то, что твой killall убил скрипт.
А разгадка проста: нефига убивать процессы методом killall,
надо развести демоны по разным pid-файлам и убивать именно те,
которые были запущены скриптами, а не все подряд.
---
Q9: А почему Линукс не ОС?
A9: ОС - это БЗДя
Это означает, что процесс получил сигнал и завершился с соответствующим статусом.Я хз, как оно на самом деле работает (в смысле, рожает много процессов). С одной стороны, родитель у всех инит. С другой - именно тот процесс, pid которого в pid файле, не завершается killproc (по service stop), но если до service stop, когда живы все шесть процессов, убить его по pid остальные тоже завершаются. Может тогда поправить скрипт так, чтобы он только его завершал, а остальные сами помрут?
Оно же намекает на то, что твой killall убил скрипт.
> С одной стороны, родитель у всех инит.
Если ты хочешь продолжать работать со связанными задачами,
тебе очень надо в этом разобраться. Иначе никак.
> С другой - именно тот процесс, pid которого в pid файле,
> не завершается killproc (по service stop),
Стоит посмотреть, что именно они туда записали.
Это линух, там может быть что угодно.
Пока что у меня складывается впечатление, что твой killproc
работает через pkill или killall, а не через pid-файл.
Возможно, что это из-за того, что он ожидает файл в /var/run,
а на самом деле он в /, как это написано в журнале.
Или ещё что-то подобное.
> но если до service stop, когда живы все шесть процессов, убить его по pid
> остальные тоже завершаются.
Если это правда, то это весьма интересное решение, я бы сказал.
> Может тогда поправить скрипт так, чтобы он только его завершал,
> а остальные сами помрут?
Ну, если это работает...
---
Q9: А почему Линукс не ОС?
A9: ОС - это БЗДя
Пока что у меня складывается впечатление, что твой killprocВ логах пишет, что как будто в / потому, что в конфиге chroot = /var/run/stunnel. На самом деле, pid файл там.
работает через pkill или killall, а не через pid-файл.
Возможно, что это из-за того, что он ожидает файл в /var/run,
а на самом деле он в /, как это написано в журнале.
Или ещё что-то подобное.
killproc стандартный центосевый (RHEL'овский?), могу привести его код, хотя он для меня тоже почти китайская грамота.
Но скорее, я попытаюсь дописать в инит скрипт что-то, что брало бы пид из пидфайла и этим же килпроцом убивало только этот сабжевый процесс.
# A function to stop a program.
killproc() {
local RC killlevel= base pid pid_file= delay try binary=
RC=0; delay=3; try=0
# Test syntax.
if [ "$#" -eq 0 ]; then
echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
return 1
fi
if [ "$1" = "-p" ]; then
pid_file=$2
shift 2
fi
if [ "$1" = "-b" ]; then
if [ -z $pid_file ]; then
echo $"-b option can be used only with -p"
echo $"Usage: killproc -p pidfile -b binary program"
return 1
fi
binary=$2
shift 2
fi
if [ "$1" = "-d" ]; then
delay=$(echo $2 | awk -v RS=' ' -v IGNORECASE=1 '{if($1!~/^[0-9.]+[smhd]?$/) exit 1;d=$1~/s$|^[0-9.]*$/?1:$1~/m$/?60:$1~/h$/?60*60:$1~/d$/?24*60*60:-1;if(d==-1) exit 1;delay+=d*$1} END {printf("%d",delay+0.5)}')
if [ "$?" -eq 1 ]; then
echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
return 1
fi
shift 2
fi
# check for second arg to be kill level
[ -n "${2:-}" ] && killlevel=$2
# Save basename.
base=${1##*/}
# Find pid.
__pids_var_run "$1" "$pid_file" "$binary"
RC=$?
if [ -z "$pid" ]; then
if [ -z "$pid_file" ]; then
pid="$(__pids_pidof "$1")"
else
[ "$RC" = "4" ] && { failure $"$base shutdown" ; return $RC ;}
fi
fi
# Kill it.
if [ -n "$pid" ] ; then
[ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
if [ -z "$killlevel" ] ; then
if checkpid $pid 2>&1; then
# TERM first, then KILL if not dead
kill -TERM $pid >/dev/null 2>&1
usleep 100000
if checkpid $pid ; then
try=0
while [ $try -lt $delay ] ; do
checkpid $pid || break
sleep 1
let try+=1
done
if checkpid $pid ; then
kill -KILL $pid >/dev/null 2>&1
usleep 100000
fi
fi
fi
checkpid $pid
RC=$?
[ "$RC" -eq 0 ] && failure $"$base shutdown" || success $"$base shutdown"
RC=$((! $RC))
# use specified level only
else
if checkpid $pid; then
kill $killlevel $pid >/dev/null 2>&1
RC=$?
[ "$RC" -eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
elif [ -n "${LSB:-}" ]; then
RC=7 # Program is not running
fi
fi
else
if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
RC=7 # Program is not running
else
failure $"$base shutdown"
RC=0
fi
fi
# Remove pid file if any.
if [ -z "$killlevel" ]; then
rm -f "${pid_file:-/var/run/$base.pid}"
fi
return $RC
}
Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]можно попробовать указать pidfile, как предлагают
Ой, а я почему-то прочитал, что он pid просит, а не pidfile. Сейчас попробую.
ОК, оставлю в таком виде.
Снова спасибо!
Школьники во всей красе.
---
Q6: Я слышал есть такой мужик, вроде Бармин зовут, и он
придумал что-то такое после чего XXX не сосет.
Или про if if if вместо case? Так может его нет в bash?
Если там нет "getopts" и "case", то он не соблюдает стандарт.
Да и в целом, идиоматический код через "getopts" и "case" лучше.
---
Q6: Я слышал есть такой мужик, вроде Бармин зовут, и он
придумал что-то такое после чего XXX не сосет.
Да, кстати, это я упустил: "=" правильно, а "==" нет. Потому что стандарт.
---
"The last good thing written in C was
Franz Schubert's Symphony Number 9."
В логах пишет, что как будто в / потому, что в конфиге chroot = /var/run/stunnel. На самом деле, pid файл там.Проверь где реально расположен pid файл после запуска сервиса.
Есть подозрение, что в /var/run/stunnel/var/run/.
Либо наоборот - кладёт при старте его в /var/run/stunnel, а ищет при стопе в /.
chroot keeps stunnel in chrooted jail. CApath, CRLpath, pid and exec are located inside the jail and the patches have to be relative to the directory specified with chroot.
Вот ещё в мане об этом говорится: при старте pid фал пишется в chroot, а при стопе ищется без chroot-а.
Где ищется (без явного указания пути, как сейчас) - не знаю, как проверить.
"set +x" и "set -x" в интересных местах.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."
Их же запускаю не я, а init (в моем случае)
Вообще-то скрипты можешь запускать и ты.
Да ладно, забейте,
Оставить комментарий
carusya
Суть такова: есть такой stunnel, софт, позволяющий заворачивать в SSL общение по некоторым протоколам. Может помочь в такой ситуации: если вы используете почтовый клиент, не умеющий SMTPS/IMAPS, а ваш почтовый сервер отказывается работать по протоколам без SSL.Так вот, на каждый потенциальный туннель он поднимает отдельный процесс. То есть, у меня настроено 6 туннелей - он поднимает шесть процессов.
Далее, решил я запускать его как service, стащил из интернета init скрипт (простой, как линейка), который почти работает. Некорректно отрабатывает вот это:
Он убивает только пять процессов из шести, и результат работы service stunnel stop вот такой:
То есть, пока руками не доубъеш оставшийся процесс, сервис обратно не запускается.
Как думаете, можно ли это пофиксить?
Так то мне некритично, но хотелось бы исправить такой глупый косяк.