init.d 守护进程脚本中的锁文件用途 (linux)

发布于 2024-12-07 17:06:51 字数 902 浏览 2 评论 0原文

当查看 /etc/init.d/ 中的各种守护程序脚本时,我似乎无法理解“lockfile”变量的用途。在启动守护进程之前似乎没有检查“lockfile”变量。

例如,/etc/init.d/ntpd 中的一些代码:

prog=ntpd
lockfile=/var/lock/subsys/$prog

start() {
        [ "$EUID" != "0" ] && exit 4
        [ "$NETWORKING" = "no" ] && exit 1
        [ -x /usr/sbin/ntpd ] || exit 5
        [ -f /etc/sysconfig/ntpd ] || exit 6
        . /etc/sysconfig/ntpd

        # Start daemons.
        echo -n $"Starting $prog: "
        daemon $prog $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && touch $lockfile
        return $RETVAL
}

“lockfile”变量在做什么?

另外,当用 C++ 编写我自己的守护进程时(例如按照 http 底部的示例) ://www.itp.uzh.ch/~dpotter/howto/daemonize),我是否将编译后的二进制文件直接放入 /etc/init.d/ 中,或者将一个调用该二进制文件的脚本放在那里。 (即用对我的二进制文件的调用替换上面代码中的“daemon $prog”?)

When looking at various daemon scripts in /etc/init.d/, I can't seem to understand the purpose of the 'lockfile' variable. It seems like the 'lockfile' variable is not being checked before starting the daemon.

For example, some code from /etc/init.d/ntpd:

prog=ntpd
lockfile=/var/lock/subsys/$prog

start() {
        [ "$EUID" != "0" ] && exit 4
        [ "$NETWORKING" = "no" ] && exit 1
        [ -x /usr/sbin/ntpd ] || exit 5
        [ -f /etc/sysconfig/ntpd ] || exit 6
        . /etc/sysconfig/ntpd

        # Start daemons.
        echo -n $"Starting $prog: "
        daemon $prog $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && touch $lockfile
        return $RETVAL
}

What is the 'lockfile' variable doing?

Also, when writing my own daemon in C++ (such as following the example at the bottom of http://www.itp.uzh.ch/~dpotter/howto/daemonize), do I put the compiled binary directly in /etc/init.d/ or do I put a script there that calls the binary. (i.e. replacing the 'daemon $prog' in the code above with a call to my binary?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鹤舞 2024-12-14 17:06:51

整个事情是一个非常脆弱和误导的尝试,试图跟踪给定的守护进程是否正在运行,以便知道以后是否/如何关闭它。使用 pid 没有帮助,因为 pid 对于除进程的直接父进程之外的任何进程都没有意义;任何其他用途都有无法解决且危险的竞争条件(即您最终可能会杀死另一个不相关的进程)。不幸的是,这种设计不当(或者更确切地说是未经设计)的黑客行为是大多数 UNIX 系统上的标准做法……

有几种方法可以正确解决该问题。一种是 systemd 方法,但 systemd 在某些圈子中并不受欢迎,因为它“臃肿”并且难以使用远程 /usr首次启动后安装。在任何情况下,解决方案将涉及:

  1. 使用一个主进程,将所有守护进程作为直接子进程生成(即抑制各个守护进程内的“守护进程”),从而可以使用它们的 pid 来监视它们的退出,跟踪它们的状态,并根据需要杀死他们。
  2. 安排每个守护进程继承一个无用的文件描述符,仅作为进程终止的一部分,它将保持打开和原子关闭。管道(匿名或命名的 fifo)、套接字甚至普通文件都是可能的,但是一旦“另一端”关闭就给出 EOF 的文件类型是最合适的,因为可以阻止等待此状态。对于普通文件,可以使用链接计数(来自 stat),但无法在不重复轮询的情况下等待它。

无论如何,lockfile/pidfile 方法是丑陋的、容易出错的,并且几乎不比简单的 killall foobard 这样的懒惰方法更好(这当然也是错误的)。

The whole thing is a very fragile and misguided attempt to keep track of whether a given daemon is running in order to know whether/how to shut it down later. Using pids does not help, because a pid is meaningless to any process except the direct parent of a process; any other use has unsolvable and dangerous race conditions (i.e. you could end up killing another unrelated process). Unfortunately, this kind of ill-designed (or rather undesigned) hackery is standard practice on most unix systems...

There are a couple approaches to solving the problem correctly. One is the systemd approach, but systemd is disliked among some circles for being "bloated" and for making it difficult to use a remote /usr mounted after initial boot. In any case, solutions will involve either:

  1. Use of a master process that spawns all daemons as direct children (i.e. inhibiting "daemonizing" within the individual daemons) and which thereby can use their pids to watch for them exiting, keep track of their status, and kill them as desired.
  2. Arranging for every daemon to inherit an otherwise-useless file descriptor, which it will keep open and atomically close only as part of process termination. Pipes (anonymous or named fifos), sockets, or even ordinary files are all possibilities, but file types which give EOF as soon as the "other end" is closed are the most suitable, since it's possible to block waiting for this status. With ordinary files, the link count (from stat) could be used but there's no way to wait on it without repeated polling .

In any case, the lockfile/pidfile approach is ugly, error-prone, and hardly any better than lazy approaches like simply killall foobard (which of course are also wrong).

音栖息无 2024-12-14 17:06:51

“lockfile”变量的作用是什么?

它可能什么都没有,也可能是例如。通过此行注入到 $OPTIONS

   . /etc/sysconfig/ntpd

守护进程采用选项 -p pidfile ,其中 $lockfile 可以去。守护进程将其 $PID 写入此文件中。

我是否将编译后的二进制文件直接放入/etc/init.d/中,还是将调用该二进制文件的脚本放在那里

/etc 中不应该有二进制文件,并且习惯上编辑 /etc/init.d 脚本来更改配置。二进制文件应转到 /(s)bin/usr/(s)bin

What is the 'lockfile' variable doing?

It could be nothing or it could be eg. injected into $OPTIONS by this line

   . /etc/sysconfig/ntpd

The daemon takes the option -p pidfile where $lockfile could go. The daemon writes its $PID in this file.

do I put the compiled binary directly in /etc/init.d/ or do I put a script there that calls the binary

The latter. There should be no binaries in /etc, and its customary to edit /etc/init.d scripts for configuration changes. Binaries should go to /(s)bin or /usr/(s)bin.

离线来电— 2024-12-14 17:06:51

rc 脚本会跟踪它是否正在运行,并且不会停止未运行的内容。

The rc scripts keep track of whether or not it is running and don't bother stopping what is not running.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文