부팅이 완료될 때까지 기다리는 방법이 있습니까?

부팅이 완료될 때까지 기다리는 방법이 있습니까?

다음 명령어를 통해 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발생하지 않는 이벤트를 기다리다가 결국 시간 초과됩니다.

반면에, 이를 Race Condition에 영향을 받지 않는 방식으로 구현하는 것이 가능해야 하며, 먼저 이벤트에 대한 Watch를 등록한 다음 속성을 확인하고, 여전히 "running"으로 설정되지 않은 경우 이벤트를 실행하는 것이 가능해야 합니다. 루프가 신호를 기다리고 있습니다.

위의 방법을 구현하고 이를 업스트림 systemd에 제안했습니다. 내 제안은 이 목적으로 실행을 허용하는 것입니다 systemctl is-system-running --wait(그러나 이는 결국 systemd에서 다른 구문(별도의 명령)을 사용하게 될 수 있습니다.) 새로운 systemd 기능에 대한 제안은 다음에서 찾을 수 있습니다.홍보 #9796systemd 프로젝트에서. (이 답변이 승인되고 병합되면 업데이트하겠습니다.)


고쳐 쓰다:홍보 #9796방금 systemd에 병합되었으므로 systemd v240부터 다음을 사용하여 시작이 완료될 때까지 기다릴 수 있습니다.

systemctl is-system-running --wait

답변2

유닛 파일을 기다리는 중

귀하의 요구에 맞는 프로토타입은 다음과 같습니다. 첫 번째는 시스템 단위 파일입니다 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

이제 시스템을 부팅하면 서비스는 확인된 is-system-running작업 이 또는 상태를 systemctl반환할 때까지 10초 동안 루프를 유지합니다 . 둘 중 하나는 시스템 부팅이 완료되었음을 나타냅니다.runningdegraded

이 서비스의 상태:

$ 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.... 이 작업이 완료되면 서비스는 완료됨/중지됨 상태가 됩니다.

관련 정보