有没有办法等待启动完成

有没有办法等待启动完成

可以通过systemd命令查询开机是否完成

systemctl is-system-running

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

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

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

答案1

可以等待这个条件而不在循环中轮询这个命令,但不幸的是它并不那么简单......

systemd 将发布一个启动完成信号一旦启动完成,就可以在 D-Bus 上进行监视,因此可以对其进行监视并获得通知。

这里有一个简单的dbus-wait工具可以监视 D-Bus 上的信号。

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

dbus-wait org.freedesktop.systemd1.Manager StartupFinished

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

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

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


更新公关#9796刚刚合并到 systemd 中,因此从 systemd v240 开始,可以使用以下命令等待启动完成:

systemctl is-system-running --wait

答案2

等待单位文件

这是一个可以满足您需求的原型。首先是一个 systemd 单元文件waity.service

$ cat /etc/systemd/system/waity.service
[Unit]
Description=Waity Service
After=systend-user-sessions.service

[Service]
Type=simple
ExecStart=/opt/bin/waity.sh

等待脚本

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

$ cat /opt/bin/waity.sh
#!/bin/bash

while $(sleep 10); do
  echo "waiting for systemd to finish booting..."
  if systemctl is-system-running | grep -qE "running|degraded"; then
    break
  fi
done

echo "systemd finished booting..."
echo "...do something else..."

运行示例

现在启用该服务:

$ systemctl enable --now waity.service

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

该服务的状态:

$ systemctl status waity.service
● waity.service - Waity Service
   Loaded: loaded (/etc/systemd/system/waity.service; static; vendor preset: disabled)
   Active: inactive (dead)

Aug 03 22:06:01 centos7 waity.sh[4519]: Got unexpected auxiliary data with level=1 and type=2
Aug 03 22:06:01 centos7 waity.sh[4519]: Got unexpected auxiliary data with level=1 and type=2
Aug 03 22:06:01 centos7 waity.sh[4519]: systemd finished booting...
Aug 03 22:06:01 centos7 waity.sh[4519]: ...do something else...
Aug 03 22:06:01 centos7 systemd[1]: Child 4519 belongs to waity.service
Aug 03 22:06:01 centos7 systemd[1]: waity.service: main process exited, code=exited, status=0/SUCCESS
Aug 03 22:06:01 centos7 systemd[1]: waity.service changed running -> dead
Aug 03 22:06:01 centos7 systemd[1]: waity.service: cgroup is empty
Aug 03 22:06:01 centos7 systemd[1]: Collecting waity.service
Aug 03 22:07:17 centos7 systemd[1]: Collecting waity.service

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

Aug 03 22:06:01 centos7 waity.sh[4519]: systemd finished booting...
Aug 03 22:06:01 centos7 waity.sh[4519]: ...do something else...

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

相关内容