有没有办法等待启动完成

sky*_*ing 9 startup systemd

有了systemd一个可以查询是否已经启动由命令完成

systemctl is-system-running
Run Code Online (Sandbox Code Playgroud)

如果启动未完成,则返回错误代码。如果您想等待引导完成,当然可以重新运行该命令,直到它返回0

我认为“必须有更好的方法”来做到这一点。有没有不依赖轮询的方法?

我想这样做的原因是我目前有一个脚本,可以将固件下载到设备,然后重新启动并希望监视它以查看它是否正常启动。我目前systemctl is-system-running通过 SSH发出,直到它返回0或者它没有在启动应该完成的时间内完成。当然,我希望这一切尽快结束。

fil*_*den 5

可以在不循环轮询此命令的情况下等待此条件,但不幸的是,这并不那么简单......

一旦启动完成,systemd 将在 D-Bus 上发布一个StartupFinished 信号,因此可以观察它并获得通知。

这是一个简单的dbus-wait工具,可以观察 D-Bus 上的信号。

我设法使用以下命令等到启动完成:

dbus-wait org.freedesktop.systemd1.Manager StartupFinished
Run Code Online (Sandbox Code Playgroud)

这种方法的问题在于存在竞争条件。如果首先我检查系统是否正在运行(使用systemctl is-system-running)并看到它仍在“启动”然后决定等待信号,那么到时候可能dbus-wait会连接到总线并开始等待信号,那 systemd 只是完成启动并已经在总线上发布了这个信号,这将dbus-wait等待一个不会发生并最终超时的事件......

另一方面,通过首先注册事件的监视,然后检查属性,如果它仍未设置为“正在运行”,则应该可以以不受竞争条件影响的方式实现这一点,然后运行事件循环等待信号。

我实现了上述方法并将其提交给上游 systemd。我的建议是允许systemctl is-system-running --wait为此目的运行(但它可能最终以不同的语法使其进入 systemd,可能是一个单独的命令。)关于新 systemd 功能的提议可以在 systemd 项目的PR #9796 中找到. (一旦它被接受并合并,我会更新这个答案。)


更新PR #9796刚刚合并到 systemd,因此从 systemd v240 开始,可以使用以下命令等待引导完成:

systemctl is-system-running --wait
Run Code Online (Sandbox Code Playgroud)


slm*_*slm 4

等待单位文件

\n\n

这是一个可以满足您需求的原型。要从这里启动 systemd 单元文件,waity.service

\n\n
$ cat /etc/systemd/system/waity.service\n[Unit]\nDescription=Waity Service\nAfter=systend-user-sessions.service\n\n[Service]\nType=simple\nExecStart=/opt/bin/waity.sh\n
Run Code Online (Sandbox Code Playgroud)\n\n

等待脚本

\n\n

它运行一个脚本来询问 systemd 以查看它是否已完成启动:

\n\n
$ cat /opt/bin/waity.sh\n#!/bin/bash\n\nwhile $(sleep 10); do\n  echo "waiting for systemd to finish booting..."\n  if systemctl is-system-running | grep -qE "running|degraded"; then\n    break\n  fi\ndone\n\necho "systemd finished booting..."\necho "...do something else..."\n
Run Code Online (Sandbox Code Playgroud)\n\n

运行示例

\n\n

现在启用该服务:

\n\n
$ systemctl enable --now waity.service\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,当我们启动系统时,该服务将处于 10 秒的循环中,直到它看到 的操作is-system-running返回systemctlarunningdegraded状态。其中任何一个都表明系统已完成启动。

\n\n

该服务的状态:

\n\n
$ systemctl status waity.service\n\xe2\x97\x8f waity.service - Waity Service\n   Loaded: loaded (/etc/systemd/system/waity.service; static; vendor preset: disabled)\n   Active: inactive (dead)\n\nAug 03 22:06:01 centos7 waity.sh[4519]: Got unexpected auxiliary data with level=1 and type=2\nAug 03 22:06:01 centos7 waity.sh[4519]: Got unexpected auxiliary data with level=1 and type=2\nAug 03 22:06:01 centos7 waity.sh[4519]: systemd finished booting...\nAug 03 22:06:01 centos7 waity.sh[4519]: ...do something else...\nAug 03 22:06:01 centos7 systemd[1]: Child 4519 belongs to waity.service\nAug 03 22:06:01 centos7 systemd[1]: waity.service: main process exited, code=exited, status=0/SUCCESS\nAug 03 22:06:01 centos7 systemd[1]: waity.service changed running -> dead\nAug 03 22:06:01 centos7 systemd[1]: waity.service: cgroup is empty\nAug 03 22:06:01 centos7 systemd[1]: Collecting waity.service\nAug 03 22:07:17 centos7 systemd[1]: Collecting waity.service\n
Run Code Online (Sandbox Code Playgroud)\n\n

我们可以在上面的消息中看到我们已检测到启动完成:

\n\n
Aug 03 22:06:01 centos7 waity.sh[4519]: systemd finished booting...\nAug 03 22:06:01 centos7 waity.sh[4519]: ...do something else...\n
Run Code Online (Sandbox Code Playgroud)\n\n

到那时我们就可以做...do something else.... 一旦这一切完成,该服务将进入完成/停止状态。

\n