systemd在ExecStop完成之前终止我的进程

时间:2015-05-25 09:33:26

标签: linux admin autostart systemd

我试图更新我的应用程序以将其与systemd一起使用。 当我使用Upstart时,我只是创建一个 /etc/init.d/myService 脚本:

#!/bin/bash
#chkconfig: 2345 90 10
#description: myDescription

### BEGIN INIT INFO
# Provides: myService
# Required-Start: sshd
# Required-Stop: sshd
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start myService
# Description:
### END INIT INFO

SCRIPT=$(readlink -f $0)
lockfile="/var/lock/subsys/myService"

do_start() {
    if [ -d "/var/lock/subsys" ]; then
        touch $lockfile
    fi
    ...
}

do_stop() {
    ...
    if [ -d "/var/lock/subsys" ]; then
        if [ -f "$lockfile" ]; then
            rm -f $lockfile
        fi
    fi
}

do_status() {
    ...
}


case "$1" in
  start)
    do_start
    exit 0
    ;;
  stop)
    do_stop
    exit 0
    ;;
  status)
    do_status
    exit 0
    ;;
  restart)
    do_stop
    do_start
    exit 0
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
    exit 3
    ;;
esac

一切都很好。

注意,此脚本会生成一些将在后台执行的子进程。 要将它与systemd一起使用,我制作了以下服务文件( myService.service ):

[Unit]
Description=My Description
Requires=sshd.service
After=sshd.service
Before=shutdown.target reboot.target halt.target

[Service]
Type=oneshot
ExecStart=/etc/init.d/myService start
ExecStop=/etc/init.d/myService stop
RemainAfterExit=yes
KillMode=none

[Install]
WantedBy=multi-user.target

如果我跑

systemctl stop myService.service

一切正常。我的应用程序通过 /etc/init.d/myService stop 命令成功停止。

但我有以下问题: 当我重新启动系统并且 /etc/init.d/myService stop 正在执行时,我应该通过 myService 脚本停止的进程已经被杀死。我应该控制很多进程(大约7个进程),系统本身不应该终止它。

我尝试使用Type = forking并将PIDFile指定为进程的pidfile,它具有最长的生命周期(它应该在最后一次停止时开始),但是我的所有进程都被终止了。 / p>

是否有任何简单的方法可以避免杀死我的子进程?

1 个答案:

答案 0 :(得分:0)

找到了解决方案。

我跑了hadoop& hbase,它们的一些组件是通过与localhost的ssh连接开始的,并且以这种方式启动的进程无法由systemd控制。 这是分布式系统的设计,但在我的情况下,工作是在一台机器上进行的。所以我已经替换了 hadoop / bin / slaves.sh

for slave in `cat "$HOSTLIST"|sed  "s/#.*$//;/^$/d"`; do
 ssh $HADOOP_SSH_OPTS $slave $"${@// /\\ }" \
   2>&1 | sed "s/^/$slave: /" &
 if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
   sleep $HADOOP_SLAVE_SLEEP
 fi
done

for slave in `cat "$HOSTLIST"|sed  "s/#.*$//;/^$/d"`; do
eval "$@"
 if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
   sleep $HADOOP_SLAVE_SLEEP
 fi
done

问题已解决,现在流程显示在服务流程树中。

Hbase可能有相同的解决方案,但现在它以distribute = false开头,并且不会通过ssh启动任何进程。