Отслеживание Upstart неправильный PID процесса - не возрождается

Первоначально я задавал этот вопрос в StackOverflow. Затем понял, что это, вероятно, лучшее место.

У меня есть настройка bluepill для мониторинга моих процессов delayed_job. (Приложение Ruby On Rails)

Использование Ubuntu 12.10.

Я запускаю и отслеживаю сам сервис bluepill, используя Ubuntu upstart. Моя конфигурация выскочки ниже (/etc/init/bluepill.conf).

description "Start up the bluepill service"

start on runlevel [2]
stop on runlevel [016]

expect daemon
exec sudo /home/deploy/.rvm/wrappers/<app_name>/bluepill load /home/deploy/websites/<app_name>/current/config/server/staging/delayed_job.bluepill

# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn

Я также пытался с expect fork вместо expect daemon. Я также попытался полностью удалить линию expect....

Когда машина загружается, bluepill запускается нормально.

$ ps aux | grep blue
root      1154  0.6  0.8 206416 17372 ?        Sl   21:19   0:00 bluepilld: <app_name>

PID процесса bluepill здесь 1154. Но upstart, похоже, отслеживает неправильный PID. Он отслеживает PID, который не существует.

$ initctl status bluepill
bluepill start/running, process 990

Я думаю, что это отслеживает PID процесса sudo, который запустил процесс bluepill.

Это предотвращает возрождение процесса bluepill, если я принудительно убью bluepill с помощью kill -9.

Более того, я думаю, что из-за неверного PID, который отслеживается, перезагрузка / завершение работы просто зависает, и мне приходится каждый раз выполнять полную перезагрузку машины.

В чем здесь может быть проблема?

ОБНОВЛЕНИЕ :

Проблема остается на сегодня (3 мая 2015 г.) в Ubuntu 14.04.2.

Проблема не в использовании sudo. Я больше не использую sudo. Моя обновленная конфигурация upstart:

description "Start up the bluepill service"

start on runlevel [2]
stop on runlevel [016]

# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn

# Give up if restart occurs 10 times in 90 seconds.
respawn limit 10 90

expect daemon

script
    shared_path=/home/deploy/websites/some_app/shared

    bluepill load $shared_path/config/delayed_job.bluepill
end script

Когда машина загружается, программа загружается нормально. Но выскочка все еще отслеживает неправильный PID, как описано выше.

Обходной путь, упомянутый в комментариях, может решить проблему зависания. Впрочем, я не пробовал.

11
задан 3 May 2015 в 13:45

3 ответа

Довольно поздно, но, надеюсь, это может помочь другим пользователям.

В upstart есть задокументированная ошибка, которая может привести к тому, что initctl отследит неправильный PID, если указать неверный раздел fork в конфигурации upstart: https://bugs.launchpad.net/upstart/+bug / 406397

Что происходит, так это то, что upstart проверяет раздел fork и определяет, сколько разветвленных процессов он должен проверить перед выбором «истинного» PID контролируемой программы. Если вы укажете expect fork или expect daemon, но ваша программа не разветвляется достаточное количество раз, start зависнет. С другой стороны, если ваш процесс разветвляется слишком много раз, initctl отследит неправильный PID. Теоретически, это должно быть задокументировано в этом разделе поваренной книги выскочки , но, как вы можете видеть в этой ситуации, есть PID, связанный с завершенным процессом, когда его не должно быть.

Последствия этого объясняются в комментариях к багтрекеру, но я здесь подведу итог: помимо initctl неспособности остановить процесс демона и зависания в недокументированном / недопустимом состоянии <service> start/killed, process <pid>, если процесс принадлежит этот PID останавливается (и обычно будет), а затем PID освобождается для повторного использования системой.

Если вы введете initctl stop <service> или service <service> stop, initctl уничтожит этот PID в следующий раз, когда он появится. Это означает, что где-то в будущем, если вы не перезагрузите компьютер после совершения этой ошибки, следующий процесс, использующий этот PID, будет немедленно уничтожен initctl, даже если это не будет демон. Это может быть что-то такое же простое, как cat или такое же сложное, как ffmpeg, и вам будет трудно понять, почему ваш программный пакет завис в середине какой-то рутинной операции.

Итак, проблема в том, что вы указали неправильную опцию expect для количества вилок, которые фактически делает ваш демон-процесс. Они говорят, что есть переписывание выскочки, которое решает эту проблему, но по состоянию на выскочке 1.8 (последняя версия Ubuntu 13.04 / январь 2014) проблема все еще присутствует.

Поскольку вы использовали expect daemon и столкнулись с этой проблемой, я рекомендую попробовать expect fork.

Редактировать: вот Ubuntu BASH-совместимый скрипт (оригинал Уэйда Фитцпатрика , модифицированный для использования Ubuntu sleep), который порождает процессы до тех пор, пока не будет исчерпано доступное адресное пространство идентификатора процесса, после чего он запускается обратно в 0 и работает до «застрял» PID. Затем процесс запускается в режиме PID initctl, а затем initctl его убивает и сбрасывает.

#!/bin/bash

# usage: sh /tmp/upstart_fix.sh <pid>

sleep 0.001 &
firstPID=$!
#first lets exhaust the space
while (( $! >= $firstPID ))
do
    sleep 0.001 &
done

# [ will use testPID itself, we want to use the next pid
declare -i testPID
testPID=$(($1 - 1))
while (( $! < $testPID ))
do
    sleep 0.001 &
done

# fork a background process then die so init reaps its pid
sleep 3 &
echo "Init will reap PID=$!"
kill -9 $
# EOF
0
ответ дан 3 May 2015 в 13:45

Для приведенного примера:

$ initctl status bluepill
bluepill start/running, process 990

быстрое решение для меня:

# If upstart gets stuck for some job in stop/killed state
export PID=990
cd /usr/local/bin
wget https://raw.github.com/ion1/workaround-upstart-snafu/master/workaround-upstart-snafu
chmod +x workaround-upstart-snafu
./workaround-upstart-snafu $PID

источник: https://bugs.debian.org/cgi- bin / bugreport.cgi? bug = 582745 # 37

Надеюсь, это будет полезно. То, что происходит, объясняется в других ответах.

0
ответ дан 3 May 2015 в 13:45

Если вы не выполняете задание Upstart на уровне пользователя или , используя раздел setuid - тогда ваша работа выполняется от имени пользователя root.

Поскольку Upstart уже запущен от имени пользователя root, зачем вам вообще использовать sudo в exec строфе?

Используя sudo или su в строфе exec вызвали те же проблемы для меня, как вы описываете здесь.

Обычно я испытываю пункт 1 ИЛИ 1 И 2:

  1. выскочка после неверного PID
  2. зависает при вылете при попытке остановить процесс

Конечно, дополнительно необходимо, чтобы раздел expect отражал правильное количество вилок.

YMMV, но для меня:

  • использование sudo или su в строфе exec с указанием правильного числа вилок обычно приводит к ситуации 1 выше.
  • Неправильное число указанных вилок (с нашим без sudo / su в exec) приводит к ситуации 1 И 2 ​​выше.
0
ответ дан 3 May 2015 в 13:45

Другие вопросы по тегам:

Похожие вопросы: