简体   繁体   English

Upstart:在启动序列期间在启动后脚本节中使用命令替换时出错

[英]Upstart: Error when using command substitution in post-start script stanza during startup sequence

I'm seeing an issue in upstart where using command substitution inside a post-start script stanza causes an error (syslog reports "terminated with status 1"), but only during the initial system startup. 我在upstart中看到一个问题,其中在启动后脚本节中使用命令替换会导致错误(系统日志报告“以状态1终止”),但仅在初始系统启动期间发生。

I've tried using just about every startup event hook under the sun. 我试过几乎在阳光下使用每个启动事件挂钩。 local-filesystems and net-device-up worked without error about 1/100 tries, so it looks like a race condition. 本地文件系统和net-device-up正常运行约1/100次,没有错误,因此看起来像是竞争条件。 It works just fine on manual start/stop. 在手动启动/停止时效果很好。 The command substitutions I've seen trigger the error are a simple cat or date, and I've tried using both the $() way and the backtick way. 我看到的命令替换触发错误是一个简单的日期或猫,我尝试使用$()和反引号两种方式。 I've also tried using sleep in pre-start to beat the race condition but that did nothing. 我还尝试在开始前使用睡眠来克服比赛状况,但这没有任何作用。

I'm running Ubuntu 11.10 on VMWare with a Win7 host. 我在具有Win7主机的VMWare上运行Ubuntu 11.10。 Spent too many hours troubleshooting this already... Anyone got any ideas? 已经花了太多时间进行故障排除...任何人有任何想法吗?

Here is my .conf file for reference: 这是我的.conf文件供参考:

start on runlevel [2345]
stop on runlevel [016]

env NODE_ENV=production
env MYAPP_PIDFILE=/var/run/myapp.pid

respawn

exec start-stop-daemon --start --make-pidfile --pidfile $MYAPP_PIDFILE --chuid node-svc --exec /usr/local/n/versions/0.6.14/bin/node /opt/myapp/live/app.js >> /var/log/myapp/audit.node.log 2>&1

post-start script
    MYAPP_PID=`cat $MYAPP_PIDFILE`
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] + Started $UPSTART_JOB [$MYAPP_PID]: PROCESS=$PROCESS UPSTART_EVENTS=$UPSTART_EVENTS" >> /var/log/myapp/audit.upstart.log
end script

post-stop script
    MYAPP_PID=`cat $MYAPP_PIDFILE`
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] - Stopped $UPSTART_JOB [$MYAPP_PID]: PROCESS=$PROCESS UPSTART_STOP_EVENTS=$UPSTART_STOP_EVENTS EXIT_SIGNAL=$EXIT_SIGNAL EXIT_STATUS=$EXIT_STATUS" >> /var/log/myapp/audit.upstart.log
end script

The most likely scenario I can think of is that $MYAPP_PIDFILE has not been created yet. 我能想到的最有可能的情况是尚未创建$MYAPP_PIDFILE

Because you have not specified an 'expect' stanza, the post-start is run as soon as the main process has forked and execed. 因为您没有指定“ expect”节,所以一旦主进程派生并执行了后启动操作。 So, as you suspected, there is probably a race between start-stop-daemon running node and writing that pidfile and /bin/sh forking, execing, and forking again to exec cat $MYAPP_PIDFILE . 因此,正如您所怀疑的那样,在start-stop-daemon运行节点与写入pidfile和/bin/sh派生,执行并再次派生给exec cat $MYAPP_PIDFILE之间可能存在竞争。

The right way to do this is to rewrite your post-start as such: 正确的方法是这样重写启动后的内容:

post-start script
  for i in 1 2 3 4 5 ; do
    if [ -f $MYAPP_PIDFILE ] ; then
      echo ...
      exit 0
    fi
    sleep 1
  done
  echo "timed out waiting for pidfile"
  exit 1
end script

Its worth noting that in Upstart 1.4 (included first in Ubuntu 12.04), upstart added logging ability, so there's no need to redirect output into a special log file. 值得注意的是,在Upstart 1.4(首先包含在Ubuntu 12.04中)中,upstart增加了日志记录功能,因此无需将输出重定向到特殊的日志文件。 All console output defaults to /var/log/upstart/$UPSTART_JOB.log (which is rotated by logrotate). 所有控制台输出默认为/var/log/upstart/$UPSTART_JOB.log (由logrotate旋转)。 So those echos could just be bare echos. 因此,这些回声可能仅仅是裸露的回声。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM