准备协议不匹配
正如Wieland所暗示的那样,Type
该服务的重要性。该设置表明systemd 准备就绪的协议希望该服务讲话。一个simple
服务被认为是立即准备。在forking
服务的初始过程派生一个孩子然后退出之后,它就被视为准备就绪。一个dbus
服务被认为当一个服务器出现在桌面总线做好准备。依此类推。
如果您没有在服务单元中声明与该服务相匹配的就绪协议,那么事情就会出错。就绪协议不匹配会导致服务无法正确启动,或者(通常)被systemd诊断为(失败)故障。当某个服务被视为无法启动systemd时,请确保杀死该服务的每个孤立的附加进程(从故障的角度来看,这些附加进程可能一直作为故障的一部分运行),以使该服务正确地回到非活动状态州。
您正是在这样做。
首先,简单的东西:sh -c
不匹配Type=simple
或Type=forking
。
在simple
协议中,初始处理被取为是服务进程。但是实际上,sh -c
包装程序将实际的服务程序作为子进程运行。因此,对于初学者来说,这MAINPID
会出错并ExecReload
停止工作。使用时Type=simple
,首先必须使用sh -c 'exec …'
或不使用 sh -c
。后者通常是正确的做法,比某些人想像的要好。
sh -c
也不匹配Type=forking
。服务的就绪协议forking
非常具体。初始过程必须派生一个孩子,然后退出。systemd将超时应用于此协议。如果初始过程没有在分配的时间内分叉,则表示准备失败。如果初始过程没有在指定时间内退出,那也将是失败的。
不必要的恐怖是 ossec-control
这使我们想到了复杂的东西:那个ossec-control
脚本。
事实证明,这是一个System 5 rc
脚本,在4个到10个进程之间派生,而这些进程本身又在派生并退出。这是System 5 rc
脚本中的一种,它试图在一个脚本中管理整个服务器进程集,其中包括for
循环,竞争条件,sleep
试图避免它们的任意s,会导致系统处于半启动状态的故障模式,以及二十年前促使人们发明诸如AIX System Resource Controller和daemontools之类的所有其他恐怖因素。而且,不要忘记在二进制目录中隐藏的shell脚本,该脚本会即时重写以实现特质enable
和disable
动词。
因此,当您/bin/sh -c '/var/ossec/bin/ossec-control start'
发生的情况是:
- systemd分叉它期望的服务过程。
- 那是壳,叉
ossec-control
。
- 这反过来又在4到10个孙子之间分叉。
- 孙子们全部分叉并依次离开。
- 大孙子们都分叉并平行离开。
ossec-control
退出。
- 第一个外壳退出。
- 该服务工序都很大,great-孙子,不过因为工作的匹配这样既不的
forking
,也不在simple
准备协议,systemd认为服务作为一个整体已经失败,并关闭了回去。
实际上,在systemd下根本不需要这些恐怖。都没有
系统化模板服务单元
而是编写一个非常简单的模板单元:
[单元]
Description = OSSEC HIDS%i服务器
之后= network.target
[服务]
类型=简单
ExecStartPre = / usr / bin / env / var / ossec / bin /%p-%i -t
ExecStart = / usr / bin / env / var / ossec / bin /%p-%i -f
[安装]
WantedBy =多用户目标
将此另存为/etc/systemd/system/ossec@.service
。
各种实际服务是此模板的实例,名为:
ossec@dbd.service
ossec@agentlessd.service
ossec@csyslogd.service
ossec@execd.service
ossec@agentd.service
ossec@logcollector.service
ossec@syscheckd.service
ossec@maild.service
ossec@analysisd.service
ossec@remoted.service
ossec@monitord.service
然后,启用和禁用功能直接来自服务管理系统(已修复RedHat错误752774),不需要隐藏的shell脚本。
systemctl启用ossec @ dbd ossec @ agentlessd ossec @ csyslogd ossec @ maild ossec @ execd ossec @ analysisd ossec @ logcollector ossec @ remoted ossec @ syscheckd ossec @ monitord
此外,systemd可以直接了解和跟踪每个实际服务。它可以使用过滤他们的日志journalctl -u
。它可以知道单个服务何时失败。它知道应该启用和运行哪些服务。
顺便说一句:Type=simple
和-f
选项在这里与在许多其他情况下一样。实际上,很少有服务通过dint表示已准备就绪exit
,而在这里也不是这种情况。但这就是forking
类型的含义。由于某些错误的公认观念,即恶魔应该做的事情,主要在野外进行的服务只是分叉和退出。实际上不是。自1990年代以来就没有。现在该赶上了。
进一步阅读