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现存在两个问题:
- 如何解决服务间的依赖循环问题?
- 如何正确编写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: umountfs和X-Stop-After: umountfs,这会让insserv检测到停止序列的死锁——umountfs需要等dudriver停止,而dudriver又被要求在umountfs之后停止,形成了闭环。
修复步骤:
- 修改LSB头的停止依赖:删除冲突的停止配置项,因为你的脚本是启动时一次性执行,停止阶段不需要和umountfs绑定顺序。修改后相关配置如下:
# Required-Stop: # Should-Stop: # X-Stop-After: - 强制移除旧的启动链接:因为当前依赖错误导致无法正常移除,用
-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




