Linux doesn’t always run smoothly on Hyper-V, although it’s undeniable that the situation has gotten substantially better as Microsoft has put more effort into it.
Sometimes, the way that Linux manifests a problem befuddles administrators that are used to the Windows platform. When issues crop up that we’re unfamiliar with, there is a strong temptation to wonder if it’s because there’s something wrong with Linux or if it’s a Hyper-V issue. From experience, I know that most people tend to blame Hyper-V first.
One such scenario is a Linux-based virtual machine is instructed to shut down or restart, but never does. The assumption seems to be that something has gone wrong in the guest-to-host communications process. One “fix” that I saw was to disable Dynamic Memory. Sorry, but that isn’t a fix — at best, it’s a work-around.
This article was written using Ubuntu Linux, but should be applicable to any Debian-based distribution. Other distributions might have similar symptoms and fixes, although you’ll have to look elsewhere for a translation. Depending on your confidence in your Linux system and skills, you might want to take a backup before trying the steps shown here.
Unfortunately, there isn’t a single reason that a Linux system might refuse to shut down. It’s very verbose about it, though, so you might be able to just watch the process and find out that it’s hanging up in a particular location and search on that for a fix. The case that I’m going to present here is one that can happen to anyone, is fairly simple to reproduce, and (at least for me), has a fix that is not at all obvious.
The symptom is quite simple: the guest goes through all the motions of shutting down and reaches the point where it should stop or restart, and then simply hangs:
The final line states “Reached target Shutdown.” When all is well, this is the very last thing that’s displayed before the guest shuts down or restarts, as instructed.
I stumbled on the fix for this by accident. If you’re having the same problem that I did, there’s a very simple way to find out. Run the following at any prompt:
In the output, check the Mounted on column for the /boot mount point. If it is all, or mostly, consumed, this is likely to be your problem. Compare to the following:
What’s likely happened is that you’ve updated the system kernel a few times. Unlike other packages, old kernels are not automatically cleaned up by the normal processes.
How to Clean Up Old Kernels on Ubuntu Linux
- The very first thing to do is find out which kernel you’re currently running. The reason is simple: don’t delete that one. To determine your current kernel version, type the following:
On my system, that produced:
From that, I know that I do not want to delete anything about kernel version 3.19.0-33. Why would Linux allow me to delete that version? I don’t know. Maybe it won’t; I didn’t try. Why doesn’t Windows stop me from running “deltree %systemroot%”? The point is, take a few seconds to protect you from yourself.
- The next thing you need is a list of old kernels that are hanging around. That’s discovered with:
Shell1dpkg --get-selections | grep linux-image
Mine produced the following output:
I don’t know what the story is behind the items marked as deinstall. They take up zero space. I deleted them anyway.
- To remove an item from the list, just enter the following:
1apt-get remove --purge linux-image-220.127.116.11-21-generic
You do not need to specifically remove the items marked with the word “extra”. They will be automatically removed along with the kernel of the same name.
- You’ll then be taken through the normal apt-get process of confirming the removal and watching the results as they happen.
- Repeat the above steps for any remaining kernels… except the one from step 1. In case you’re wondering, I worked from oldest to newest but I don’t believe that it matters.
Note: It is possible to issue multiple items after –purge, but I recommend that you not do so in this case. I actually caused my test system to hang when I tried that. It recovered just fine, but I don’t know that you’d want to take that kind of gamble on a production system.
If you’re running through PuTTY, there is a way to make this process faster. First, type out the remove line:
apt-get remove --purge
Make sure you put in a space after purge. Then, scroll back up to the list of kernels. Highlight the oldest:
Then just right-click. PuTTY will automatically append the highlighted text wherever the cursor is, automatically producing this line (or whatever you highlighted on your system):
apt-get remove --purge linux-image-3.19.0-21-generic
That’s it! Just press [Enter] and finish up as normal from step 4.
Once all the old kernels are removed, run df again. You should have much different results:
If your Linux system is in a place where a bit of downtime won’t hurt anyone, verify your results the easiest way:
shutdown -r now
If all went well, your Linux guest should restart as expected. Unless you deleted your active kernel, the worst-case scenario is that you have a much cleaner boot partition.
- I’m not promising that this will allow your Linux guest to properly shutdown or restart every time. Linux under Hyper-V is improving; it’s not bullet-proof. However, the condition described in this article consistently causes this issue. Applying this fix will dramatically improve the odds of avoiding the issue.
- While not nearly as urgent, you can remove the header files for those old kernels as well. Start at step 2 with “linux-headers” as your search criteria.
- If you followed my earlier article or the Microsoft recommended article, you’ve also get a number of “linux-virtual” items. Leave those alone.