![类似生成器的单元会创建另一个单元,并且两个单元都应在引导期间启动;那可能吗?](https://linux22.com/image/226763/%E7%B1%BB%E4%BC%BC%E7%94%9F%E6%88%90%E5%99%A8%E7%9A%84%E5%8D%95%E5%85%83%E4%BC%9A%E5%88%9B%E5%BB%BA%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%8D%95%E5%85%83%EF%BC%8C%E5%B9%B6%E4%B8%94%E4%B8%A4%E4%B8%AA%E5%8D%95%E5%85%83%E9%83%BD%E5%BA%94%E5%9C%A8%E5%BC%95%E5%AF%BC%E6%9C%9F%E9%97%B4%E5%90%AF%E5%8A%A8%EF%BC%9B%E9%82%A3%E5%8F%AF%E8%83%BD%E5%90%97%EF%BC%9F.png)
使用配置文件将一些旧式服务转换为systemd
单元,我编写了一个类似生成器(即:实际上不是 systemd 生成器)的服务,它创建(取决于配置文件)一些服务和需要这些服务的目标。目标应该在引导期间启动(在生成器运行之后)。
我这样做的原因不是使用普通的 systemd 生成器单元是相当有限的。
在正在运行的系统中进行测试时,一切似乎都正常,但重新启动后目标并未启动。通常手动启动目标就足够了。
以下是我的发电机组的基本内容:
[Unit]
Description=instance generator
Wants=nss-user-lookup.target time-sync.target paths.target
After=nss-user-lookup.target time-sync.target paths.target
Before=default.target iotwatch.target
ConditionPathExists=/etc/iotwatch.conf
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/lib/iotwatch/iotwatch-generator /run/systemd/system
TimeoutStartSec=10
RestartPreventExitStatus=2 3 4 5 7
SuccessExitStatus=7
StartLimitBurst=100
StartLimitInterval=2
RemainAfterExit=true
[Install]
WantedBy=default.target iotwatch.target
目标单元如下所示:
[Unit]
Description=iotwatch
Wants=paths.target [email protected] [email protected] [email protected] [email protected]
After=paths.target [email protected] [email protected] [email protected] [email protected]
After=nss-lookup.target time-sync.target
[Install]
WantedBy=default.target
Wants=
和的列表After=
由生成器单元动态添加。
典型的实例单元基本上如下所示:
# generated from /etc/iotwatch.conf for VAR (1fa9d6b1)
[Unit]
Description=iotwatch I/O performance monitor instance "VAR"
SourcePath=/etc/iotwatch.conf
PartOf=iotwatch.target
Requires=iotwatch-generator.service
After=iotwatch-generator.service
Wants=nss-user-lookup.target time-sync.target paths.target
After=nss-user-lookup.target time-sync.target paths.target
ConditionPathExists=/dev/v04/var
Conflicts=shutdown.target
[Service]
Type=forking
WorkingDirectory=/run/iotwatch-VAR
ExecStartPre=/bin/sh -c '[ -d "/run/iotwatch-VAR" ] || mkdir -p "/run/iotwatch-VAR" || exit 3'
ExecStartPre=/bin/sh -c '[ -h "/run/iotwatch-VAR/iotwatch-VAR" ] || ln -s "/usr/bin/iotwatch" "/run/iotwatch-VAR/iotwatch-VAR" || exit 3'
ExecStartPre=/bin/sh -c '[ -d "/var/log/iotwatch/VAR" -o 1 -eq 0 ] || mkdir "/var/log/iotwatch/VAR" || exit 3'
ExecStart=@/run/iotwatch-VAR/iotwatch-VAR iotwatch-VAR -l /var/log/iotwatch/VAR/iotwatch-VAR.log -m I -p/run/iotwatch-VAR/iotwatch-VAR.pid -d1 ...
ExecStartPost=/usr/bin/sleep 0.2
TimeoutStartSec=10
ExecStop=/run/iotwatch-VAR/iotwatch-VAR -l /var/log/iotwatch/VAR/iotwatch-VAR-stop.log -m I -p/run/iotwatch-VAR/iotwatch-VAR.pid -d0
TimeoutStopSec=30
PIDFile=/run/iotwatch-VAR/iotwatch-VAR.pid
Restart=always
RestartSec=10s
RestartPreventExitStatus=1 3
[Install]
WantedBy=iotwatch.target
(该单元有点复杂,因为它是从 LSB 脚本转换而来的,该脚本也执行生成器现在执行的操作)
所有服务均已启用。发电机组退出前执行的最后一个命令是/usr/bin/systemctl daemon-reload
。
可能是什么问题,有没有(干净的)解决方案?
启动期间会发生什么
当我启动系统时,发电机启动并Default
达到目标。
然而我看到
systemd[1]:无法启动创建易失性文件和目录
原因是正在创建的一个临时目录使用 LDAP 提供的用户,而此时 LDAP 客户端 (NSS) 尚未准备好。但我可以登录并systemctl start systemd-tmpfiles-setup.service
。我的服务单位仍然无法启动。
此时服务的状态是:
# systemctl status iotwatch.target
● iotwatch.target - iotwatch I/O performance monitor
Loaded: loaded (/run/systemd/system/iotwatch.target; enabled; vendor preset: disabled)
Active: inactive (dead)
# systemctl status iotwatch-generator.service
● iotwatch-generator.service - I/O performance monitor instance generator
Loaded: loaded (/usr/lib/systemd/system/iotwatch-generator.service; enabled; vendor preset: disabled)
Active: active (exited) since Fri 2023-11-24 12:06:16 CET; 20min ago
Main PID: 3075 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 512)
Memory: 0B
CGroup: /system.slice/iotwatch-generator.service
Nov 24 12:06:15 rksapv04 systemd[1]: Starting I/O performance monitor instance generator...
Nov 24 12:06:16 rksapv04 systemd[1]: Started I/O performance monitor instance generator.
# systemctl status [email protected]
● [email protected] - iotwatch I/O performance monitor instance "VAR"
Loaded: loaded (/etc/iotwatch.conf; enabled; vendor preset: disabled)
Active: inactive (dead)
手动启动目标时,所有实例都会启动。