You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ubuntu系统init.d脚本启动依赖循环问题及预挂载配置咨询

解决init.d脚本依赖循环及磁盘挂载前执行的问题

我尝试将自定义脚本dudriver加入系统启动序列,该脚本需在挂载/etc/fstab中定义的磁盘前执行。/etc/init.d/dudriver脚本内容如下:

#!/bin/sh
# kFreeBSD do not accept scripts as interpreters, using #!/bin/sh and sourcing.
if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
    set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
fi
### BEGIN INIT INFO
# Provides: dudriver
# Required-Start: $network $named
# Required-Stop: umountfs
# Should-Start: udev
# Should-Stop: udev
# X-Start-Before: mountall
# X-Stop-After: umountfs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description:
# Description:
### END INIT INFO
if [ -x /opt/dudriver_startup.sh ]
then
    /opt/dudriver_startup.sh >>/var/log/dudriver_startup.log
fi
exit 0

多次编辑该脚本后执行命令出现如下错误:

root@sysman:/etc/init.d# update-rc.d dudriver remove
insserv: There is a loop between service umountfs and dudriver if stopped
insserv: loop involving service dudriver at depth 3
insserv: loop involving service umountfs at depth 2
insserv: loop involving service postgresql at depth 1
insserv: loop involving service cryptdisks at depth 4
insserv: loop involving service networking at depth 2
insserv: There is a loop between service umountfs and dudriver if stopped
insserv: loop involving service umountnfs at depth 3
insserv: exiting now without changing boot order!
update-rc.d: error: insserv rejected the script header

root@sysman:/etc/init.d# update-rc.d dudriver defaults
insserv: There is a loop between service umountfs and dudriver if stopped
insserv: loop involving service dudriver at depth 3
insserv: loop involving service umountfs at depth 2
insserv: loop involving service postgresql at depth 1
insserv: loop involving service cryptdisks at depth 4
insserv: loop involving service networking at depth 2
insserv: There is a loop between service umountfs and dudriver if stopped
insserv: loop involving service umountnfs at depth 3
insserv: exiting now without changing boot order!
update-rc.d: error: insserv rejected the script header

现存在两个问题:

  1. 如何解决服务间的依赖循环问题?
  2. 如何正确编写LSB头以实现dudriver脚本在磁盘挂载前执行?

系统信息:uname -a → Linux sysman 4.13.0-31-generic #34~16.04.1-Ubuntu SMP Fri Jan 19 17:11:01 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux


1. 解决服务间的依赖循环问题

你遇到的循环错误根源在LSB头的停止依赖配置:你同时设置了Required-Stop: umountfsX-Stop-After: umountfs,这会让insserv检测到停止序列的死锁——umountfs需要等dudriver停止,而dudriver又被要求在umountfs之后停止,形成了闭环。

修复步骤:

  1. 修改LSB头的停止依赖:删除冲突的停止配置项,因为你的脚本是启动时一次性执行,停止阶段不需要和umountfs绑定顺序。修改后相关配置如下:
    # Required-Stop:
    # Should-Stop:
    # X-Stop-After:
    
  2. 强制移除旧的启动链接:因为当前依赖错误导致无法正常移除,用-f参数强制清理:
    update-rc.d -f dudriver remove
    

2. 正确编写LSB头以实现磁盘挂载前执行

要让脚本在/etc/fstab定义的磁盘挂载前运行,核心是确保脚本在负责挂载处理的mountall服务之前启动,同时调整启动依赖避免冲突。

最终优化后的LSB头:

### BEGIN INIT INFO
# Provides: dudriver
# Required-Start: $syslog
# Required-Stop:
# Should-Start:
# Should-Stop:
# X-Start-Before: mountall
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Load custom driver before disk mount
# Description: Executes /opt/dudriver_startup.sh to load custom drivers prior to mounting fstab-defined disks
### END INIT INFO

关键配置说明:

  • X-Start-Before: mountall:这是核心,明确告知insserv脚本要在mountall(处理fstab挂载的服务)之前启动
  • Required-Start: $syslog:只依赖基础的日志服务,因为你要写入日志到/var/log(根分区已提前挂载),避免依赖$network这类可能需要挂载后资源的服务
  • 清空所有停止相关依赖:脚本仅在启动时执行,停止阶段无需特殊顺序

重新配置启动链接:

完成脚本修改后,执行以下命令添加启动序列:

update-rc.d dudriver defaults

你可以通过查看/etc/rc2.d/目录下的启动链接验证顺序,脚本的链接(如S10dudriver)的数字应该小于mountall的链接数字(通常是S13mountall),确保执行顺序正确。


内容的提问来源于stack exchange,提问作者user5177344

火山引擎 最新活动