![需要帮助将 init.d 服务脚本转换为 systemd(CentOS)](https://linux22.com/image/688491/%E9%9C%80%E8%A6%81%E5%B8%AE%E5%8A%A9%E5%B0%86%20init.d%20%E6%9C%8D%E5%8A%A1%E8%84%9A%E6%9C%AC%E8%BD%AC%E6%8D%A2%E4%B8%BA%20systemd%EF%BC%88CentOS%EF%BC%89.png)
我花了好几天的时间来解决一个非常令人沮丧的问题,而且我已经没有其他选择了。
我目前在工作中使用 CentOS 6.8 服务器来运行我们的网站。CentOS 6(Enterprise Linux 6 或 EL6)使用较旧的 init.d 模型来执行启动脚本。老板要求我使用一个程序,即 SonicWALL CDP Agent。他有一台 SonicWALL 备份服务器,他们的“代理”软件在后台运行,将特定文件和文件夹备份到服务器。它实际上是基于 Acronis TrueImage 构建的,但那是另一个故事。
最大的问题是他们的 CDP 代理使用 Adobe AIR。他们一定是这样设计的,以便跨平台(因为他们有适用于 Windows/OSX/Linux 的安装程序),但当然,Adobe 不久前就完全停止了对 64 位 Linux 上的 AIR 的支持。他们的网站提供了一些安装步骤,但可以追溯到 Red Hat 5.5,甚至不是 6。
我确实设法按照 EL6 的步骤在 EL7 上安装 AIR,并注意软件包名称在存储库中发生了哪些变化。值得注意的是,普通的 GUI 安装程序 (AdobeAIRInstaller.bin) 不起作用,并且即使在以 root 身份运行时也会显示“您的管理员可能禁止安装”的错误,但 .rpm 文件可以正常工作。
我有最新的:
adobeair-core-2.6.0-19170.noarch.rpm
adobeair-2.6.0-19170.i686.rpm
与 GTK2 i686 库结合,这实际上是可行的。
但是,CDP 代理比这更复杂。需要运行两个系统服务才能使代理软件真正发挥作用(如果您仔细想想,自动备份无论如何都需要这两个系统服务才能发挥作用)。
但是他们的安装程序已经过时了,将启动脚本放在 init.d 中。这“应该”在 EL7 中起作用,但实际上却不起作用。我花了几个小时摆弄它,但它就是不起作用。
因此,基本上有两个二进制文件需要运行。启动它们的命令是:
/sbin/cdp/cdpagentproxy
/sbin/cdp/cdpdaemon start
如果我打开终端并手动运行它们,它们就会工作 - 而且我可以打开 CDP 代理并且它也能工作。但是,由于 init.d/systemd 不兼容,它们不会在启动时启动。
因此我创建了几个简单的“服务”,并将它们放在正确的位置。例如 cdpdaemon.service 文件:
[Unit]
Description=CDP Daemon Service
After=syslog.target network.target
[Service]
Type=forking
ExecStart=/sbin/cdp/cdpdaemon start
[Install]
WantedBy=multi-user.target
我将其放入/usr/lib/systemd/system/cdpdaemon.service
并在中创建了它的符号链接/etc/systemd/system/multi-user.target.wants/cdpdaemon.service
。
但是当我尝试检查状态时发生了以下情况:
[root@localhost Desktop]# systemctl status cdpdaemon.service
● cdpdaemon.service - CDP Daemon Service
Loaded: loaded (/usr/lib/systemd/system/cdpdaemon.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sun 2016-08-21 22:08:13 EDT; 10s ago
Process: 1596 ExecStart=/sbin/cdp/cdpdaemon start (code=exited, status=0/SUCCESS)
Main PID: 1633 (code=exited, status=127)
Aug 21 22:08:13 localhost.localdomain systemd[1]: Starting CDP Daemon Service...
Aug 21 22:08:13 localhost.localdomain cdpdaemon[1596]: Starting process.
Aug 21 22:08:13 localhost.localdomain systemd[1]: Started CDP Daemon Service.
Aug 21 22:08:13 localhost.localdomain systemd[1]: cdpdaemon.service: main process exited, code=exited, status=127/n/a
Aug 21 22:08:13 localhost.localdomain systemd[1]: Unit cdpdaemon.service entered failed state.
Aug 21 22:08:13 localhost.localdomain systemd[1]: cdpdaemon.service failed.
另一个也发生同样的情况。它似乎试图运行,但随后停止并报告错误。如果我打开终端并简单地输入/sbin/cdp/cdpdaemon start
,它就可以正常工作。
我在这里做错了什么吗?我不明白“目标”选项的不同类型,也不明白“之后”和类型。(我基本上是采用了一个有效的服务,复制了文本并更改了命令)
我想另一种选择是制作一个在特定时间运行的 cronjob(假设是晚上 11 点,如果备份在午夜运行)来运行这两个命令,但这似乎是错误的做法。
该程序确实运行了,但如果不启动两个辅助进程,我就无法让它自行运行。
编辑:我想我会提供安装 .sh 文件以防它有帮助。您可以看到它在哪里检查您正在运行的发行版并创建 init.d 脚本。
答案1
“Type=fokring” 适用于派生子服务并将其置于后台并正常退出的服务。查看您的输出,感觉您的程序并没有这样做。如果您将“Type=forking”更改为“Type=simple”,会发生什么情况?
答案2
首先,确定这些进程是否确实分叉。如果您在终端中启动“分叉”进程,它将释放终端并“进入后台”。此类进程需要Type=forking
。否则,如果进程不释放终端,除非您使用 Ctrl+C 终止它或&
在命令行末尾输入,那么它就是Type=simple
。就这么简单。
第二,你提到二必须按顺序启动的进程。您是否为它们两个都编写了单元文件?如果没有,请立即执行。
第三,不要忘记依赖关系。如果后一个进程(/sbin/cdp/cdpdaemon start
)依赖于前一个进程(/sbin/cdp/cdpagentproxy
),那么您需要在单元文件中表达它们之间的需求和顺序依赖关系。
例如,如果您创建的单元文件分别命名为cdpagentproxy.service
和cdpdaemon.service
,那么您必须在cdpdaemon.service
单元文件中放入以下几行:
[Unit]
Requires=cdpagentproxy.service
After=cdpagentproxy.service
[Unit]
(当然,将这些行放在现有的部分内。我只是为了完整性才包含了部分标题。)
然后运行systemctl daemon-reload
,终止两个进程并尝试手动启动该单元,或者简单地将其添加到自动启动并重新启动。
答案3
让我们稍微回顾一下。
sonicwall 进程与 RHEL/Centos7 不兼容。
就此打住。将其交给 Sonicwall 的优秀人员进行修复;这正是您应该向他们支付许可费的事情,他们(应该)拥有支持其软件的专业知识。
CentOS6 还需要五年的支持,但他们应该开始进行一个简单的过渡。