Skip to content

Distro shut down even with running processes #8854

Closed

Description

Version

Microsoft Windows [Version 10.0.22621.521]

WSL Version

  • WSL 2
  • WSL 1

Kernel Version

5.15.62.1

Distro Version

Ubuntu 20.04

Other Software

Docker Engine version 20.10.18

Repro Steps

  1. Create fresh Ubuntu 20.04 image
  2. Enable systemd
  3. Install Docker into Ubuntu (Ansible example)
  4. Run nginx in Docker (docker run -d -p 80:80 nginx)
  5. Verify nginx is running in your browser (http://localhost/)
  6. Exit the shell

Expected Behavior

Since nginx is running, the distro should not shut down.

Prior to upgrading to 0.67.6 w/ systemd support, this was the (presumably correct, but definitely desired) behavior.

Actual Behavior

After a short period of time, the distro is forcefully shut down by the system.

Logging back in, you can see it was forcefully shut down:

 sh$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                       PORTS                               NAMES
ad20314283c5   nginx     "/docker-entrypoint.…"   14 minutes ago   Exited (255) 4 minutes ago   0.0.0.0:80->80/tcp, :::80->80/tcp   admiring_bardeen

Diagnostic Logs

No response

Activity

  1. cerebrate commented on Sep 22, 2022

    @cerebrate

    Unfortunately, this is the new documented behavior, per blog post:

    It is also important to note that with these change, systemd services will NOT keep your WSL instance alive.

    You've currently got to have something running as a child of init - the Microsoft init, not pid 1 - to keep the distro running. Not my preference, but.

  2. NotTheDr01ds commented on Sep 22, 2022

    @NotTheDr01ds

    This is (fairly) explicitly stated in Craig's DevBlog announcement:

    It is also important to note that with these change, systemd services will NOT keep your WSL instance alive. Your WSL instance will stay alive in the same way it did before, which you can read more about here.

    That was actually surprising to me, as Windows 11's wsl.conf boot.command used to keep services running after exiting the shell. It was only in the Preview releases that it was changed to terminate when all processing started interactively had terminated. Hence I filed #8661, thinking this was a regression. Based on the text above, it seems that this might have been an intentional change.

    Perhaps we should have a feature-request for a /etc/wsl.conf flag to allow the instance to continue running when any background task is still running.

  3. cerebrate commented on Sep 22, 2022

    @cerebrate

    Perhaps we should have a feature-request for a /etc/wsl.conf flag to allow the instance to continue running when any background task is still running.

    Or just "until systemctl poweroff", which is pretty much how the above should behave when systemd support is enabled.

  4. benhillis commented on Sep 22, 2022

    @benhillis
    Member

    Fair points - I think an option to keep distros running (and not idle terminate them) is a good idea.

  5. bradwilson commented on Sep 22, 2022

    @bradwilson
    Author

    systemd services will NOT keep your WSL instance alive

    Is a process launched by Docker considered to be a "systemd service"? Docker itself is, obviously, but things launched by Docker, I would've expected to keep the distro alive.

    It seems to me like they implemented one thing (always shut it down when there's no interactive shell) but documented something else (don't let systemd services keep it alive).

  6. bradwilson commented on Sep 22, 2022

    @bradwilson
    Author

    (BTW, hearing the description of "we only stay alive for things rooted on Microsoft's init" helps me understand the exact implementation. It's unfortunate that the blog post described in a way that doesn't seems to match the actual implementation. Why not just describe it in the technically correct way?)

  7. bradwilson commented on Sep 22, 2022

    @bradwilson
    Author

    Fair points - I think an option to keep distros running (and not idle terminate them) is a good idea.

    But what does this mean for systemd, then? I mean ps aux on a systemd-enabled distro has, as expected, a ton of stuff running. How would the proposed flag change the behavior? Would it basically always leave systemd distros always running, because of all those systemd processes? Or would the implementation better match the blog post description ("systemd services will NOT keep your WSL instance alive" but anything else will...?)

  8. NotTheDr01ds commented on Sep 22, 2022

    @NotTheDr01ds

    Fair points - I think an option to keep distros running (and not idle terminate them) is a good idea.

    Ben Hillis (@benhillis)

    Just for clarity, it would be great if that option still allowed distros to terminate if no other processes were running, similar to the way it worked with the [boot].command section in the GA Windows 11 release. I'd only expect/want it to stay running if there's some background process, whether it was started through:

    Basically, I think the flag would say "Work like it did in Windows 11 GA" ;-)

  9. NotTheDr01ds commented on Sep 22, 2022

    @NotTheDr01ds

    Brad Wilson (@bradwilson)

    It's unfortunate that the blog post described in a way that doesn't seems to match the actual implementation. Why not just describe it in the technically correct way?

    I'm not sure they realized they had ever changed it to work any other way. The way I read the description, it seems Craig thought that was the way it always worked.

    But what does this mean for systemd, then?

    I would expect that any background process would count as a keep-alive mechanism. And yes, that's one of the unfortunate things about Systemd - It typically starts a lot. How would you tell the difference between the System dbus instance vs. Nginx, for instance?

  10. NotTheDr01ds commented on Sep 22, 2022

    @NotTheDr01ds

    Answering my own question above, I guess it could be a "whitelist process" implementation, where /etc/wsl.conf had a keep-alive (or something named better) option with a list of processes that would prevent the distro from self-terminating.

    Just throwing it out there - I'm not tied to it by any means.

  11. bradwilson commented on Sep 22, 2022

    @bradwilson
    Author

    Basically, I think the flag would say "Work like it did in Windows 11 GA" ;-)

    I have doubts about this being what I want, though I recognize that may be where this falls back to (see my question above about systemd services in general keeping things alive with this new proposed flag).

    Having Docker keep the distro alive in Win11 GA is acceptable but not ideal. It's something that's I've come to accept, and I have quick commands to kill the things that are most likely to be "daemonized" in a pre-systemd world (notably, Docker and the GPG agent). In a world where we have systemd (and I have Docker's life cycle owned by systemd), I wouldn't want Docker itself to be something that would keep the distro alive, just the case of running Docker containers.

  12. NotTheDr01ds commented on Sep 22, 2022

    @NotTheDr01ds

    Brad Wilson (@bradwilson) Yes, our replies are getting out of sync ;-) - I saw that you post that concern above and posted a separate reply (actually two now) regarding it.

  13. bradwilson commented on Sep 22, 2022

    @bradwilson
    Author

    How would you tell the difference between the System dbus instance vs. Nginx, for instance?

    That's why I'm asking. A mode where "any background process keeps the distro alive" + systemd means the distro will never shut itself down, and I'll be running a lot of wsl -t distro to keep things clean. In that case, I'm better off without systemd (despite it ostensibly providing other value that I might want).

    That means it would also be critical to ensure that systemd is something I can opt out of. Microsoft makes it sounds like it will eventually become the default, which is fine, so long as the wsl.conf flag to disable it doesn't disappear.

  14. 41 remaining items

  15. everson-plantae commented on May 20, 2024

    @everson-plantae

    Firejox (@firejox) Your solution works well when there is only one active distribution, but I am working with two, when starting the second one, the process in the first one is interrupted.

  16. firejox commented on May 21, 2024

    @firejox

    Everson Neves (@everson-plantae) It is because the [signal name] in waitfor.exe [signal name] is globally shared. You need to use different signal names for different distributions. For example, there are Fedora and Ubuntu in WSL. You may use waitfor.exe FedoraAlive for Fedora and waitfor.exe UbuntuAlive for Ubuntu. Or you can use choice.exe with named pipe to keep distro alive. choice.exe is no need to setup special [signal name] for different distribution.

  17. astroboylrx commented on Jul 22, 2024

    @astroboylrx

    Firejox (@firejox) It seems WSL2 has become more aggressive when trying to shutdown itself.

    I added the systemd service suggested above (with the After=wsl-binfmt.service systemd-binfmt.service). However, after a night, WSL2 still shut down. Then I went to check the Task Manager, the waitfor.exe process is still there... somehow it survives but didn't keep WSL2 alive...

    Any suggestions would be greatly appreciated.

  18. cerebrate commented on Jul 22, 2024

    @cerebrate

    Like I said way back in the thread, the only processes that will keep the WSL session from being auto-terminated are children of the Microsoft init (not the pid 1 init, the WSL-supplied init). No systemd service can be this, so you won't get anywhere with those.

    To be clear, here's a pstree:

    systemd─┬─Relay(1061)───wait-forever.sh───sleep
            ├─2*[agetty]
            ├─automount───5*[{automount}]
            ├─containerd───12*[{containerd}]
            ├─dbus-daemon
            ├─dockerd───14*[{dockerd}]
            ├─init-systemd(De─┬─SessionLeader───Relay(1936)───machinectl
            │                 ├─SessionLeader───Relay(332257)───sleep
            │                 ├─init───{init}
            │                 ├─sh
            │                 └─{init-systemd(De}
            ├─polkitd───3*[{polkitd}]
            ├─rpc.gssd───{rpc.gssd}
            ├─rpcbind
    ...etc....
    

    What you are looking for is the Relay(number) parent. A process which has that above it in the tree (here, that would be wait-forever.sh, machinectl, and sleep) will keep the WSL instance running; one that doesn't, won't.

    _nohup_ing or _daemonize_ing a waitforever script is still the best option, I believe.

  19. Parsifa1 commented on Jul 23, 2024

    @Parsifa1

    I used to use dbus-launch true in shell config to solve this problem, but recently after I updated, wsl will automatically close after one night, is there any plan to add "wsl never automatically closes" to wslconfig?

  20. aki-k commented on Jul 23, 2024

    @aki-k

    is there any plan to add "wsl never automatically closes" to wslconfig?

    After following this saga since the beginning: "No."

  21. cerebrate commented on Jul 23, 2024

    @cerebrate

    is there any plan to add "wsl never automatically closes" to wslconfig?

    #8854 (comment) , but since it's got such a simple workaround, I can't imagine it's anywhere near the top of the WSL team's list of possible new features.

  22. astroboylrx commented on Jul 23, 2024

    @astroboylrx

    _nohup_ing or _daemonize_ing a waitforever script is still the best option, I believe.

    Alistair Young (@cerebrate) I tried _nohup_ing and WSL2 (Ubuntu 22.04) still stopped after a night. Previously dbus-launch true was sufficient to keep distro alive.
    Feels like the shutdown did become more aggressive since a very recent update (I think maybe I'm seeing what 汐 (@Parsifa1) sees).

    WSL version: 2.3.11.0
    Kernel version: 6.6.36.3-1
    WSLg version: 1.0.63
    MSRDC version: 1.2.5326
    Direct3D version: 1.611.1-81528511
    DXCore version: 10.0.26100.1-240331-1435.ge-release
    Windows version: 10.0.22635.3930
    
  23. darrenchang commented on Jul 25, 2024

    @darrenchang

    Fair points - I think an option to keep distros running (and not idle terminate them) is a good idea.

    Are there still plans to implement this?

  24. codeart1st commented on Oct 9, 2024

    @codeart1st

    Small update for Windows 11 24H2 the waitfor.exe solution won't work anymore.

    Job for keep-distro-alive.service failed because the control process exited with error code.
    See "systemctl status keep-distro-alive.service" and "journalctl -xeu keep-distro-alive.service" for details.
    

    I think it's a problem with the PreStart

    /mnt/c/Windows/system32/waitfor.exe /si MakeDistroAlive
    ERROR: Cannot send the specified signal.
    

    I disabled the PreStart part for now.

  25. hasancemcerit commented on Oct 9, 2024

    @hasancemcerit

    This workaround that got inspiration from other posts such as this one, is guaranteed to be working.

    I am running some dockerized application stack using compose on kali-linux.
    ▶ Prerequisite: systemd is enabled

    1. Create bash script keepalive.sh as below.
    #!/bin/bash
    # This script will run and make kali-linux distro running all the time.
    
    # check systemd and wait until it's up & running
    while :; do [[ ! $(systemctl is-system-running --wait 2> /dev/null) ]] && sleep 1 || break; done
    
    # run your docker compose, or whatever you want to run on wsl
    # docker compose -f docker-compose.yml --env-file docker.env -p your-project up --no-deps --detach
    
    # check if tmux is in the background, if not start a new session
    [[ ! $(tmux ls &> /dev/null) ]] && tmux new -d -s keepalive > /dev/null 2> /dev/null
    
    # check if infitinte tail is running, if not start
    [[ ! $(ps aux | grep tail | grep -v grep) ]] && nohup sh -c "tail -f /dev/null &" < /dev/null > /dev/null 2> /dev/null
    
    1. Create a scheduled task that runs on windows startup.
    wsl.exe -d kali-linux --exec bash ./keepalive.sh
    

    Enjoy that your app lives 💓 and will keep on living.

    Test it and see for yourself from windows 👀
    $❯ wsl -l -v

      NAME          STATE           VERSION
    * kali-linux    Running         2
    

    $❯ wsl -d kali-linux --exec tmux ls

    keepalive: 1 windows (created Wed Oct  9 08:33:48 2024)
    

    From wsl terminal:
    $❯ docker ps -a

    NAMES      STATE     IMAGE                           NETWORKS    PORTS
    app        running   ---                             host
    ...        running   ---                             app_net   
    postgres   running   postgres:17.0-alpine3.20        app_net   
    ...        running   ---                             app_net      
    portainer  running   portainer/portainer-ce:alpine   bridge      
    
  26. microsoft-github-policy-service commented on Oct 9, 2025

    @microsoft-github-policy-service
    Contributor

    This issue has been automatically closed since it has not had any activity for the past year. If you're still experiencing this issue please re-file this as a new issue or feature request.

    Thank you!

  27. aki-k commented on Oct 9, 2025

    @aki-k

    I can't believe this total ignorance of the users' wishes, from Microsoft.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions