Is there a way to wait for boot to complete [on hold]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












With systemd one can query if the boot has completed by the command



systemctl is-system-running


which returns error code if boot hasn't completed. If one want to wait for the boot to complete one can of course rerun the command until it returns 0.



I think there "must be a better way" to do this. Is there a method that doesn't rely on polling?



The reason I want to do this is that I currently have a script that downloads firmware to a device that is then rebooted and want to monitor it to see if it boots cleanly. I currently do this by issuing systemctl is-system-running via SSH until it returns 0 or it doesn't within the time the boot ought to have completed. Of course I want this to finish as soon as possible.







share|improve this question













put on hold as unclear what you're asking by Ignacio Vazquez-Abrams, schily, Rui F Ribeiro, Thomas, Jesse_b 2 days ago


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.














  • Of course. Write a service that requires the system to finish starting.
    – Ignacio Vazquez-Abrams
    Aug 3 at 13:02










  • @IgnacioVazquez-Abrams I was thinking of a doing this in a script.
    – skyking
    Aug 3 at 13:03










  • @IgnacioVazquez-Abrams It would be nice to mention exactly what you think is unclear in the question so I can improve it. (I think it's quite clear myself)
    – skyking
    18 hours ago










  • That wasn't my close reason, but okay.
    – Ignacio Vazquez-Abrams
    15 hours ago
















up vote
3
down vote

favorite












With systemd one can query if the boot has completed by the command



systemctl is-system-running


which returns error code if boot hasn't completed. If one want to wait for the boot to complete one can of course rerun the command until it returns 0.



I think there "must be a better way" to do this. Is there a method that doesn't rely on polling?



The reason I want to do this is that I currently have a script that downloads firmware to a device that is then rebooted and want to monitor it to see if it boots cleanly. I currently do this by issuing systemctl is-system-running via SSH until it returns 0 or it doesn't within the time the boot ought to have completed. Of course I want this to finish as soon as possible.







share|improve this question













put on hold as unclear what you're asking by Ignacio Vazquez-Abrams, schily, Rui F Ribeiro, Thomas, Jesse_b 2 days ago


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.














  • Of course. Write a service that requires the system to finish starting.
    – Ignacio Vazquez-Abrams
    Aug 3 at 13:02










  • @IgnacioVazquez-Abrams I was thinking of a doing this in a script.
    – skyking
    Aug 3 at 13:03










  • @IgnacioVazquez-Abrams It would be nice to mention exactly what you think is unclear in the question so I can improve it. (I think it's quite clear myself)
    – skyking
    18 hours ago










  • That wasn't my close reason, but okay.
    – Ignacio Vazquez-Abrams
    15 hours ago












up vote
3
down vote

favorite









up vote
3
down vote

favorite











With systemd one can query if the boot has completed by the command



systemctl is-system-running


which returns error code if boot hasn't completed. If one want to wait for the boot to complete one can of course rerun the command until it returns 0.



I think there "must be a better way" to do this. Is there a method that doesn't rely on polling?



The reason I want to do this is that I currently have a script that downloads firmware to a device that is then rebooted and want to monitor it to see if it boots cleanly. I currently do this by issuing systemctl is-system-running via SSH until it returns 0 or it doesn't within the time the boot ought to have completed. Of course I want this to finish as soon as possible.







share|improve this question













With systemd one can query if the boot has completed by the command



systemctl is-system-running


which returns error code if boot hasn't completed. If one want to wait for the boot to complete one can of course rerun the command until it returns 0.



I think there "must be a better way" to do this. Is there a method that doesn't rely on polling?



The reason I want to do this is that I currently have a script that downloads firmware to a device that is then rebooted and want to monitor it to see if it boots cleanly. I currently do this by issuing systemctl is-system-running via SSH until it returns 0 or it doesn't within the time the boot ought to have completed. Of course I want this to finish as soon as possible.









share|improve this question












share|improve this question




share|improve this question








edited Aug 3 at 13:07
























asked Aug 3 at 13:01









skyking

1486




1486




put on hold as unclear what you're asking by Ignacio Vazquez-Abrams, schily, Rui F Ribeiro, Thomas, Jesse_b 2 days ago


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.






put on hold as unclear what you're asking by Ignacio Vazquez-Abrams, schily, Rui F Ribeiro, Thomas, Jesse_b 2 days ago


Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.













  • Of course. Write a service that requires the system to finish starting.
    – Ignacio Vazquez-Abrams
    Aug 3 at 13:02










  • @IgnacioVazquez-Abrams I was thinking of a doing this in a script.
    – skyking
    Aug 3 at 13:03










  • @IgnacioVazquez-Abrams It would be nice to mention exactly what you think is unclear in the question so I can improve it. (I think it's quite clear myself)
    – skyking
    18 hours ago










  • That wasn't my close reason, but okay.
    – Ignacio Vazquez-Abrams
    15 hours ago
















  • Of course. Write a service that requires the system to finish starting.
    – Ignacio Vazquez-Abrams
    Aug 3 at 13:02










  • @IgnacioVazquez-Abrams I was thinking of a doing this in a script.
    – skyking
    Aug 3 at 13:03










  • @IgnacioVazquez-Abrams It would be nice to mention exactly what you think is unclear in the question so I can improve it. (I think it's quite clear myself)
    – skyking
    18 hours ago










  • That wasn't my close reason, but okay.
    – Ignacio Vazquez-Abrams
    15 hours ago















Of course. Write a service that requires the system to finish starting.
– Ignacio Vazquez-Abrams
Aug 3 at 13:02




Of course. Write a service that requires the system to finish starting.
– Ignacio Vazquez-Abrams
Aug 3 at 13:02












@IgnacioVazquez-Abrams I was thinking of a doing this in a script.
– skyking
Aug 3 at 13:03




@IgnacioVazquez-Abrams I was thinking of a doing this in a script.
– skyking
Aug 3 at 13:03












@IgnacioVazquez-Abrams It would be nice to mention exactly what you think is unclear in the question so I can improve it. (I think it's quite clear myself)
– skyking
18 hours ago




@IgnacioVazquez-Abrams It would be nice to mention exactly what you think is unclear in the question so I can improve it. (I think it's quite clear myself)
– skyking
18 hours ago












That wasn't my close reason, but okay.
– Ignacio Vazquez-Abrams
15 hours ago




That wasn't my close reason, but okay.
– Ignacio Vazquez-Abrams
15 hours ago










2 Answers
2






active

oldest

votes

















up vote
1
down vote













Waiting Unit file



Here's a prototype that does what your looking for. To start here's a systemd unit file, 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


Waiting Script



It runs a script which does the interrogating of systemd to see if it's finished booting:



$ 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..."


Example run



Now enable this service:



$ systemctl enable --now waity.service


Now when we start up our system this service will sit in a 10 second loop until it sees that the is-system-running action of systemctl returns either a running or degraded state. Either of these is an indication that the system has completed booting.



The status of this service:



$ 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


We can see in the above messages that we've detected a completed boot:



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


At which point we could do the ...do something else.... Once this is all complete this service will go to a done/dead state.






share|improve this answer





















  • This is a very complete answer and it seems to do exactly what the OP asked for, since it removes the need to externally poll the system. I wonder if there's a solution without busy waiting as well, as one would do asynchronously with callbacks or promises in JavaScript.
    – Telmo Trooper
    Aug 4 at 2:29






  • 1




    @TelmoTrooper - I saw none, but that doesn't mean there aren't. Given this is running just during a boot, it runs every 10 seconds, and then once the boot is complete it stops, this will run at most maybe a half dozen times, seems reasonable to me, IMO.
    – slm♦
    Aug 4 at 2:31










  • Sim doesn't this have the same drawback as my original solution? Namely that it will be between 0 and 10s late due to the polling loop? That's what I wanted to avoid.
    – skyking
    18 hours ago










  • @skyking - there's a race condition in the other approach using D-Bus, you can't escape it, hence why I did a simple polling solution here, to be able to gain access to the is-system-running action of systemctl. The amount of time can be controlled with this approach by making a tighter loop. I see no other method beyond this here.
    – slm♦
    18 hours ago

















up vote
1
down vote













It is possible to wait for this condition without polling this command on a loop, but unfortunately it's not that straightforward...



systemd will post a StartupFinished signal on D-Bus once the boot is complete, so it is possible to watch for that and get a notification for it.



Here is a simple dbus-wait tool that can watch for signals on D-Bus.



I managed to wait until startup was completed by using this command:



dbus-wait org.freedesktop.systemd1.Manager StartupFinished


The problem with this approach is that there's a race condition there. If first I check whether the system is running (with systemctl is-system-running) and see that it's still "starting" and then decide to wait for the signal, it's possible that by the time dbus-wait will connect to the bus and start waiting for the signal, that systemd just finished startup and already posted this signal in the bus, which will make dbus-wait wait for an event that won't happen and eventually time out...



On the other hand, it should be possible to implement this in a way that is free from race conditions, by first registering the watch for the event, then checking the property and if it's still not set to "running" then run the event loop to wait for the signal.



I implemented the approach above and proposed it to upstream systemd. My suggestion is to allow running systemctl is-system-running --wait for this purpose (but it is possible this might end up making it to systemd with a different syntax, possibly a separate command.) The proposal for the new systemd feature can be found at PR #9796 on systemd project. (I'll update this answer once it's accepted and merged.)






share|improve this answer




























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    Waiting Unit file



    Here's a prototype that does what your looking for. To start here's a systemd unit file, 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


    Waiting Script



    It runs a script which does the interrogating of systemd to see if it's finished booting:



    $ 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..."


    Example run



    Now enable this service:



    $ systemctl enable --now waity.service


    Now when we start up our system this service will sit in a 10 second loop until it sees that the is-system-running action of systemctl returns either a running or degraded state. Either of these is an indication that the system has completed booting.



    The status of this service:



    $ 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


    We can see in the above messages that we've detected a completed boot:



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


    At which point we could do the ...do something else.... Once this is all complete this service will go to a done/dead state.






    share|improve this answer





















    • This is a very complete answer and it seems to do exactly what the OP asked for, since it removes the need to externally poll the system. I wonder if there's a solution without busy waiting as well, as one would do asynchronously with callbacks or promises in JavaScript.
      – Telmo Trooper
      Aug 4 at 2:29






    • 1




      @TelmoTrooper - I saw none, but that doesn't mean there aren't. Given this is running just during a boot, it runs every 10 seconds, and then once the boot is complete it stops, this will run at most maybe a half dozen times, seems reasonable to me, IMO.
      – slm♦
      Aug 4 at 2:31










    • Sim doesn't this have the same drawback as my original solution? Namely that it will be between 0 and 10s late due to the polling loop? That's what I wanted to avoid.
      – skyking
      18 hours ago










    • @skyking - there's a race condition in the other approach using D-Bus, you can't escape it, hence why I did a simple polling solution here, to be able to gain access to the is-system-running action of systemctl. The amount of time can be controlled with this approach by making a tighter loop. I see no other method beyond this here.
      – slm♦
      18 hours ago














    up vote
    1
    down vote













    Waiting Unit file



    Here's a prototype that does what your looking for. To start here's a systemd unit file, 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


    Waiting Script



    It runs a script which does the interrogating of systemd to see if it's finished booting:



    $ 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..."


    Example run



    Now enable this service:



    $ systemctl enable --now waity.service


    Now when we start up our system this service will sit in a 10 second loop until it sees that the is-system-running action of systemctl returns either a running or degraded state. Either of these is an indication that the system has completed booting.



    The status of this service:



    $ 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


    We can see in the above messages that we've detected a completed boot:



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


    At which point we could do the ...do something else.... Once this is all complete this service will go to a done/dead state.






    share|improve this answer





















    • This is a very complete answer and it seems to do exactly what the OP asked for, since it removes the need to externally poll the system. I wonder if there's a solution without busy waiting as well, as one would do asynchronously with callbacks or promises in JavaScript.
      – Telmo Trooper
      Aug 4 at 2:29






    • 1




      @TelmoTrooper - I saw none, but that doesn't mean there aren't. Given this is running just during a boot, it runs every 10 seconds, and then once the boot is complete it stops, this will run at most maybe a half dozen times, seems reasonable to me, IMO.
      – slm♦
      Aug 4 at 2:31










    • Sim doesn't this have the same drawback as my original solution? Namely that it will be between 0 and 10s late due to the polling loop? That's what I wanted to avoid.
      – skyking
      18 hours ago










    • @skyking - there's a race condition in the other approach using D-Bus, you can't escape it, hence why I did a simple polling solution here, to be able to gain access to the is-system-running action of systemctl. The amount of time can be controlled with this approach by making a tighter loop. I see no other method beyond this here.
      – slm♦
      18 hours ago












    up vote
    1
    down vote










    up vote
    1
    down vote









    Waiting Unit file



    Here's a prototype that does what your looking for. To start here's a systemd unit file, 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


    Waiting Script



    It runs a script which does the interrogating of systemd to see if it's finished booting:



    $ 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..."


    Example run



    Now enable this service:



    $ systemctl enable --now waity.service


    Now when we start up our system this service will sit in a 10 second loop until it sees that the is-system-running action of systemctl returns either a running or degraded state. Either of these is an indication that the system has completed booting.



    The status of this service:



    $ 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


    We can see in the above messages that we've detected a completed boot:



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


    At which point we could do the ...do something else.... Once this is all complete this service will go to a done/dead state.






    share|improve this answer













    Waiting Unit file



    Here's a prototype that does what your looking for. To start here's a systemd unit file, 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


    Waiting Script



    It runs a script which does the interrogating of systemd to see if it's finished booting:



    $ 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..."


    Example run



    Now enable this service:



    $ systemctl enable --now waity.service


    Now when we start up our system this service will sit in a 10 second loop until it sees that the is-system-running action of systemctl returns either a running or degraded state. Either of these is an indication that the system has completed booting.



    The status of this service:



    $ 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


    We can see in the above messages that we've detected a completed boot:



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


    At which point we could do the ...do something else.... Once this is all complete this service will go to a done/dead state.







    share|improve this answer













    share|improve this answer



    share|improve this answer











    answered Aug 4 at 2:10









    slm♦

    232k65479648




    232k65479648











    • This is a very complete answer and it seems to do exactly what the OP asked for, since it removes the need to externally poll the system. I wonder if there's a solution without busy waiting as well, as one would do asynchronously with callbacks or promises in JavaScript.
      – Telmo Trooper
      Aug 4 at 2:29






    • 1




      @TelmoTrooper - I saw none, but that doesn't mean there aren't. Given this is running just during a boot, it runs every 10 seconds, and then once the boot is complete it stops, this will run at most maybe a half dozen times, seems reasonable to me, IMO.
      – slm♦
      Aug 4 at 2:31










    • Sim doesn't this have the same drawback as my original solution? Namely that it will be between 0 and 10s late due to the polling loop? That's what I wanted to avoid.
      – skyking
      18 hours ago










    • @skyking - there's a race condition in the other approach using D-Bus, you can't escape it, hence why I did a simple polling solution here, to be able to gain access to the is-system-running action of systemctl. The amount of time can be controlled with this approach by making a tighter loop. I see no other method beyond this here.
      – slm♦
      18 hours ago
















    • This is a very complete answer and it seems to do exactly what the OP asked for, since it removes the need to externally poll the system. I wonder if there's a solution without busy waiting as well, as one would do asynchronously with callbacks or promises in JavaScript.
      – Telmo Trooper
      Aug 4 at 2:29






    • 1




      @TelmoTrooper - I saw none, but that doesn't mean there aren't. Given this is running just during a boot, it runs every 10 seconds, and then once the boot is complete it stops, this will run at most maybe a half dozen times, seems reasonable to me, IMO.
      – slm♦
      Aug 4 at 2:31










    • Sim doesn't this have the same drawback as my original solution? Namely that it will be between 0 and 10s late due to the polling loop? That's what I wanted to avoid.
      – skyking
      18 hours ago










    • @skyking - there's a race condition in the other approach using D-Bus, you can't escape it, hence why I did a simple polling solution here, to be able to gain access to the is-system-running action of systemctl. The amount of time can be controlled with this approach by making a tighter loop. I see no other method beyond this here.
      – slm♦
      18 hours ago















    This is a very complete answer and it seems to do exactly what the OP asked for, since it removes the need to externally poll the system. I wonder if there's a solution without busy waiting as well, as one would do asynchronously with callbacks or promises in JavaScript.
    – Telmo Trooper
    Aug 4 at 2:29




    This is a very complete answer and it seems to do exactly what the OP asked for, since it removes the need to externally poll the system. I wonder if there's a solution without busy waiting as well, as one would do asynchronously with callbacks or promises in JavaScript.
    – Telmo Trooper
    Aug 4 at 2:29




    1




    1




    @TelmoTrooper - I saw none, but that doesn't mean there aren't. Given this is running just during a boot, it runs every 10 seconds, and then once the boot is complete it stops, this will run at most maybe a half dozen times, seems reasonable to me, IMO.
    – slm♦
    Aug 4 at 2:31




    @TelmoTrooper - I saw none, but that doesn't mean there aren't. Given this is running just during a boot, it runs every 10 seconds, and then once the boot is complete it stops, this will run at most maybe a half dozen times, seems reasonable to me, IMO.
    – slm♦
    Aug 4 at 2:31












    Sim doesn't this have the same drawback as my original solution? Namely that it will be between 0 and 10s late due to the polling loop? That's what I wanted to avoid.
    – skyking
    18 hours ago




    Sim doesn't this have the same drawback as my original solution? Namely that it will be between 0 and 10s late due to the polling loop? That's what I wanted to avoid.
    – skyking
    18 hours ago












    @skyking - there's a race condition in the other approach using D-Bus, you can't escape it, hence why I did a simple polling solution here, to be able to gain access to the is-system-running action of systemctl. The amount of time can be controlled with this approach by making a tighter loop. I see no other method beyond this here.
    – slm♦
    18 hours ago




    @skyking - there's a race condition in the other approach using D-Bus, you can't escape it, hence why I did a simple polling solution here, to be able to gain access to the is-system-running action of systemctl. The amount of time can be controlled with this approach by making a tighter loop. I see no other method beyond this here.
    – slm♦
    18 hours ago












    up vote
    1
    down vote













    It is possible to wait for this condition without polling this command on a loop, but unfortunately it's not that straightforward...



    systemd will post a StartupFinished signal on D-Bus once the boot is complete, so it is possible to watch for that and get a notification for it.



    Here is a simple dbus-wait tool that can watch for signals on D-Bus.



    I managed to wait until startup was completed by using this command:



    dbus-wait org.freedesktop.systemd1.Manager StartupFinished


    The problem with this approach is that there's a race condition there. If first I check whether the system is running (with systemctl is-system-running) and see that it's still "starting" and then decide to wait for the signal, it's possible that by the time dbus-wait will connect to the bus and start waiting for the signal, that systemd just finished startup and already posted this signal in the bus, which will make dbus-wait wait for an event that won't happen and eventually time out...



    On the other hand, it should be possible to implement this in a way that is free from race conditions, by first registering the watch for the event, then checking the property and if it's still not set to "running" then run the event loop to wait for the signal.



    I implemented the approach above and proposed it to upstream systemd. My suggestion is to allow running systemctl is-system-running --wait for this purpose (but it is possible this might end up making it to systemd with a different syntax, possibly a separate command.) The proposal for the new systemd feature can be found at PR #9796 on systemd project. (I'll update this answer once it's accepted and merged.)






    share|improve this answer

























      up vote
      1
      down vote













      It is possible to wait for this condition without polling this command on a loop, but unfortunately it's not that straightforward...



      systemd will post a StartupFinished signal on D-Bus once the boot is complete, so it is possible to watch for that and get a notification for it.



      Here is a simple dbus-wait tool that can watch for signals on D-Bus.



      I managed to wait until startup was completed by using this command:



      dbus-wait org.freedesktop.systemd1.Manager StartupFinished


      The problem with this approach is that there's a race condition there. If first I check whether the system is running (with systemctl is-system-running) and see that it's still "starting" and then decide to wait for the signal, it's possible that by the time dbus-wait will connect to the bus and start waiting for the signal, that systemd just finished startup and already posted this signal in the bus, which will make dbus-wait wait for an event that won't happen and eventually time out...



      On the other hand, it should be possible to implement this in a way that is free from race conditions, by first registering the watch for the event, then checking the property and if it's still not set to "running" then run the event loop to wait for the signal.



      I implemented the approach above and proposed it to upstream systemd. My suggestion is to allow running systemctl is-system-running --wait for this purpose (but it is possible this might end up making it to systemd with a different syntax, possibly a separate command.) The proposal for the new systemd feature can be found at PR #9796 on systemd project. (I'll update this answer once it's accepted and merged.)






      share|improve this answer























        up vote
        1
        down vote










        up vote
        1
        down vote









        It is possible to wait for this condition without polling this command on a loop, but unfortunately it's not that straightforward...



        systemd will post a StartupFinished signal on D-Bus once the boot is complete, so it is possible to watch for that and get a notification for it.



        Here is a simple dbus-wait tool that can watch for signals on D-Bus.



        I managed to wait until startup was completed by using this command:



        dbus-wait org.freedesktop.systemd1.Manager StartupFinished


        The problem with this approach is that there's a race condition there. If first I check whether the system is running (with systemctl is-system-running) and see that it's still "starting" and then decide to wait for the signal, it's possible that by the time dbus-wait will connect to the bus and start waiting for the signal, that systemd just finished startup and already posted this signal in the bus, which will make dbus-wait wait for an event that won't happen and eventually time out...



        On the other hand, it should be possible to implement this in a way that is free from race conditions, by first registering the watch for the event, then checking the property and if it's still not set to "running" then run the event loop to wait for the signal.



        I implemented the approach above and proposed it to upstream systemd. My suggestion is to allow running systemctl is-system-running --wait for this purpose (but it is possible this might end up making it to systemd with a different syntax, possibly a separate command.) The proposal for the new systemd feature can be found at PR #9796 on systemd project. (I'll update this answer once it's accepted and merged.)






        share|improve this answer













        It is possible to wait for this condition without polling this command on a loop, but unfortunately it's not that straightforward...



        systemd will post a StartupFinished signal on D-Bus once the boot is complete, so it is possible to watch for that and get a notification for it.



        Here is a simple dbus-wait tool that can watch for signals on D-Bus.



        I managed to wait until startup was completed by using this command:



        dbus-wait org.freedesktop.systemd1.Manager StartupFinished


        The problem with this approach is that there's a race condition there. If first I check whether the system is running (with systemctl is-system-running) and see that it's still "starting" and then decide to wait for the signal, it's possible that by the time dbus-wait will connect to the bus and start waiting for the signal, that systemd just finished startup and already posted this signal in the bus, which will make dbus-wait wait for an event that won't happen and eventually time out...



        On the other hand, it should be possible to implement this in a way that is free from race conditions, by first registering the watch for the event, then checking the property and if it's still not set to "running" then run the event loop to wait for the signal.



        I implemented the approach above and proposed it to upstream systemd. My suggestion is to allow running systemctl is-system-running --wait for this purpose (but it is possible this might end up making it to systemd with a different syntax, possibly a separate command.) The proposal for the new systemd feature can be found at PR #9796 on systemd project. (I'll update this answer once it's accepted and merged.)







        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered 2 days ago









        Filipe Brandenburger

        2,894417




        2,894417












            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay