新贵跟踪错误的进程PID-不重新生成


11

我最初在StackOverflow上问过这个问题。然后意识到这可能是一个更好的地方。

我有bluepill设置来监视我的delay_job进程。(Ruby On Rails应用程序)

使用Ubuntu 12.10。

我正在使用Ubuntu的启动和监视bluepill服务本身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>

此处,bluepill进程的PID为1154。但是upstart似乎正在跟踪错误的PID。它正在跟踪不存在的PID。

$ initctl status bluepill
bluepill start/running, process 990

我认为它正在跟踪sudo启动bluepill进程的进程的PID 。

如果我使用强制杀死bluepill,这可以防止重新生成bluepill进程kill -9

而且,我认为由于跟踪了错误的PID,重新启动/关机只是挂起,因此每次都必须硬重置计算机。

这可能是什么问题?

更新

直到今天(2015年5月3日),问题仍然存在于Ubuntu 14.04.2上。

问题不在于使用sudo。我不再使用sudo了。我更新的新贵配置是这样的:

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,如上所述。

评论中提到的解决方法可能会解决挂起的问题。我还没有尝试过。


您是否尝试过查看990的流程?ps aux | grep 990应该这样做,但pstree 990可能会提供更多信息。
奥利

PID值为990的进程不存在。
2013年

2
至于需要重新启动以使新贵恢复到良好状态的必要条件,请参见-github.com/ion1/workaround-upstart-snafu
andersonbd1

您可以使用以下命令来加快该工具的速度:$ echo 3000 | sudo tee / proc / sys / kernel / pid_max
andersonbd1

Answers:


8

很晚了,但希望对其他用户有所帮助。

如果fork在新贵配置中指定了不正确的节,则新贵中有一个已记录的错误,该错误可能导致initctl跟踪错误的PID :https : //bugs.launchpad.net/upstart/+bug/406397

发生的情况是,新贵会检查fork节并确定在选择要控制的程序的“真” PID之前应检查的分叉过程数。如果您指定expect forkexpect daemon但您的程序没有进行足够的次数,start则会挂起。另一方面,如果您的进程派生了太多次,initctl将跟踪错误的PID。从理论上讲,它应该记录在新贵食谱的这一部分中,但是正如您所看到的,在这种情况下,有一个PID与被杀死的进程相关联,而在不应该存在的情况下。

在bugtracker注释中对此进行了解释,但在此我将进行总结:除了initctl无法停止守护进程并停留在未记录/非法状态之外<service> start/killed, process <pid>,如果属于该PID的进程停止了(通常它将),然后释放PID以供系统重新使用。

如果发出initctl stop <service>service <service> stopinitctl将在下一次出现该PID时终止该PID。这意味着,如果您在犯此错误后没有重新启动,则在某个地方,initctl即使该进程不是守护程序,使用该PID的下一个进程也将被立即杀死。它可能与一样简单,也可能非常cat复杂ffmpeg,您很难弄清为什么软件包在某些常规操作过程中崩溃了。

因此,问题在于您expect为守护进程实际产生的派生数目指定了错误的选项。他们说有一个新贵改写来解决这个问题,但是从新贵1.8开始(最新的Ubuntu 13.04 / 2014年1月),这个问题仍然存在。

由于您使用expect daemon并最终遇到此问题,因此建议您尝试使用expect fork

编辑:这是一个与Ubuntu BASH兼容的脚本(由Wade Fitzpatrick最初修改为使用Ubuntu sleep),该脚本生成进程,直到可用进程ID地址空间用尽为止,这时它从0开始并一直向上直到“卡住” PID。然后在initctl挂起PID时产生一个进程,并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

这个答案有一些有用和有趣的信息,但是我不清楚这个答案如何回答最初的问题,因为@Anjan提到“我也尝试过使用
user12345 2014年

5

对于提供的示例:

$ 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

我希望这会有所帮助。其他答案中说明了发生了什么。


不错的脚本。这可能需要一两分钟。reboot有时A 可能更可取,并且可以解决此问题。
Peter Ilfrich '16

0

除非您正在运行Upstart用户级作业使用setuid节 -否则您的作业将以root身份运行。

由于Upstart已经作为root用户运行,因此为什么您需要在exec节中完全使用sudo ?

如本文所述,在节中使用sudo或对我造成了同样的问题。suexec

通常,我将经历项目1或1和2:

  1. 暴发户跟随错误的PID
  2. 当我尝试停止进程时,upstart挂起

当然,此外,您还必须expect使节反映正确的叉子数量。

YMMV,但对我来说:

  • exec节中使用sudo或su并指定了正确的叉子数量通常会导致上述情况1。
  • 指定的分叉数量不正确(在没有sudo / su的exec情况下使用)会导致上述情况1和2。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.