需要帮助将 init.d 服务脚本转换为 systemd(CentOS)

需要帮助将 init.d 服务脚本转换为 systemd(CentOS)

我花了好几天的时间来解决一个非常令人沮丧的问题,而且我已经没有其他选择了。

我目前在工作中使用 CentOS 6.8 服务器来运行我们的网站。CentOS 6(Enterprise Linux 6 或 EL6)使用较旧的 init.d 模型来执行启动脚本。老板要求我使用一个程序,即 SonicWALL CDP Agent。他有一台 SonicWALL 备份服务器,他们的“代理”软件在后台运行,将特定文件和文件夹备份到服务器。它实际上是基于 Acronis TrueImage 构建的,但那是另一个故事。

最大的问题是他们的 CDP 代理使用 Adob​​e 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 脚本。

http://pastebin.com/FmrZcmcR

答案1

“Type=fokring” 适用于派生子服务并将其置于后台并正常退出的服务。查看您的输出,感觉您的程序并没有这样做。如果您将“Type=forking”更改为“Type=simple”,会发生什么情况?

答案2

首先,确定这些进程是否确实分叉。如果您在终端中启动“分叉”进程,它将释放终端并“进入后台”。此类进程需要Type=forking。否则,如果进程不释放终端,除非您使用 Ctrl+C 终止它或&在命令行末尾输入,那么它就是Type=simple。就这么简单。

第二,你提到必须按顺序启动的进程。您是否为它们两个都编写了单元文件?如果没有,请立即执行。

第三,不要忘记依赖关系。如果后一个进程(/sbin/cdp/cdpdaemon start)依赖于前一个进程(/sbin/cdp/cdpagentproxy),那么您需要在单元文件中表达它们之间的需求和顺序依赖关系。

例如,如果您创建的单元文件分别命名为cdpagentproxy.servicecdpdaemon.service,那么您必须在cdpdaemon.service单元文件中放入以下几行:

[Unit]
Requires=cdpagentproxy.service
After=cdpagentproxy.service

[Unit](当然,将这些行放在现有的部分内。我只是为了完整性才包含了部分标题。)

然后运行systemctl daemon-reload,终止两个进程并尝试手动启动该单元,或者简单地将其添加到自动启动并重新启动。

答案3

让我们稍微回顾一下。

sonicwall 进程与 RHEL/Centos7 不兼容。

就此打住。将其交给 Sonicwall 的优秀人员进行修复;这正是您应该向他们支付许可费的事情,他们(应该)拥有支持其软件的专业知识。

CentOS6 还需要五年的支持,但他们应该开始进行一个简单的过渡。

相关内容