I use Virtualbox (via Vagrant) pretty extensively. Unfortunately, sometimes it just hangs. (Two cases when it tends to happen is when I put my laptop to sleep with the VM on or when I try to run too many things on the VM. Not every time, but often enough to be a nuisance – say, maybe once a month. And given that I regularly have uptime on the order of weeks – Emacs uptime, not computer uptime, mind you, though in my case it is usually almost the same), I don’t want to reboot the system. Unfortunately, in such situations even vagrant
halt --force
doesn’t help.
What helps is just killing all Vagrant processes and saying vagrant
halt
(for some reason, just killing them is not enough – go figure). The naive way to find all Vagrant processes is to say ps aux | grep
vagrant
and manually copy all the pids to a kill -9
command. That ps
/grep
invocation has an annoying side effect of listing itself – after all, it also matches the vagrant
regex. There is a neat workaround where you say ps aux | grep [v]agrant
– and I learned it from the grep Info manual of all places!
Once I showed this trick to a friend, and he pointed me to the pgrep
command. You can just say pgrep vagrant
and see the PIDs of all vagrant
processes. This is not helping, though, because the list can be actually empty – the executable name for these processes is usually ruby
. However, the string vagrant
obviously appears in the command-line arguments, so here’s how you can get the PIDs of the Vagrant-related processes on your machine: pgrep --full vagrant
. And to kill all of them, just say kill -9 $(pgrep --full vagrant)
(in Bash).
But we can do even better! I checked the manpage for pgrep
, and it turns out that it has a variant called pkill
which both finds and kills the processes it found. (Interestingly, it seems that the binaries for pgrep
and pkill
are identical, which implies the common trick where the behavior of some program depends on the filename of its executable, but they are neither hard- nor symlinks on my system.) So, an even shorter way of killing all Vagrant-related processes is pkill -9 --full vagrant
. (For the sake of completeness, there’s also pwait
which waits until all “selected” processes finish their job.)
So, I wrote an extremely simple script, just this and then vagrant
halt
in the correct directory, to deal with my unresponsive Vagrant processes.
That’s it for today!