I noticed that I could not connect to one of my virutal machines (VM). I have a script that checks to see if the machines were offline and if so it will start them. Thus I did some investigating. What I found was not what I was expecting.
The VM in question was in fact showing as running in the VirtualBox. What happened was that it had attempted to upgrade to the next version of the Linux kernel. Only problem was that it ran out of space when unpackaging the archive. Thus I had to remove the existing kernels on the disk before it would continue. Here's how I did it.
Find The Old Kernels
You need to find the existing kernels on the system. Since this was not my first time cleaning up the file system, I created a shell script that I can use that will display the kernels that are installed on the system. You can view the script in my Ubuntu Automation repository.
When you run the script, it will give you an output like the following:
iamadmin@thepost:~/ubuntu-automation/utils$ . list_linux_kernels.sh rc linux-image-4.15.0-101-generic 4.15.0-101.102 amd64 Signed kernel image generic rc linux-image-4.15.0-106-generic 4.15.0-106.107 amd64 Signed kernel image generic rc linux-image-4.15.0-108-generic 4.15.0-108.109 amd64 Signed kernel image generic ii linux-image-4.15.0-111-generic 4.15.0-111.112 amd64 Signed kernel image generic rc linux-image-4.15.0-34-generic 4.15.0-34.37 amd64 Signed kernel image generic rc linux-image-4.15.0-38-generic 4.15.0-38.41 amd64 Signed kernel image generic rc linux-image-4.15.0-39-generic 4.15.0-39.42 amd64 Signed kernel image generic rc linux-image-4.15.0-42-generic 4.15.0-42.45 amd64 Signed kernel image generic rc linux-image-4.15.0-43-generic 4.15.0-43.46 amd64 Signed kernel image generic rc linux-image-4.15.0-46-generic 4.15.0-46.49 amd64 Signed kernel image generic rc linux-image-4.15.0-47-generic 4.15.0-47.50 amd64 Signed kernel image generic rc linux-image-4.15.0-50-generic 4.15.0-50.54 amd64 Signed kernel image generic rc linux-image-4.15.0-51-generic 4.15.0-51.55 amd64 Signed kernel image generic rc linux-image-4.15.0-54-generic 4.15.0-54.58 amd64 Signed kernel image generic rc linux-image-4.15.0-58-generic 4.15.0-58.64 amd64 Signed kernel image generic rc linux-image-4.15.0-88-generic 4.15.0-88.88 amd64 Signed kernel image generic rc linux-image-4.15.0-99-generic 4.15.0-99.100 amd64 Signed kernel image generic
The break down of the output is as follows.
- Lines that begin with "rc" are the ones that can be removed without any problem.
- Lines that begin with "ii" should not be removed as they are being used by the system.
- The second column of the output, represents the name of the image. This is what you will use in the next section to remove the old kernels from the system.
Remove The Old Kernels
Automatically Remove Them
If you have enabled automatic updates to run on your Ubuntu system, then you can configure the old Linux images and headers to be removed.
On Ubuntu 20.04, this would mean enabling or adding the below text to the /etc/apt/apt.conf.d/50unattended-upgrades file.
NOTE: Before making updates to files in the /etc directory, I would recommend that you create a backup of the file or set up version control, like Etckeeper, for this directory.
// Remove unused automatically installed kernel-related packages // (kernel images, kernel headers and kernel version locked tools). Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Now that you have identified the kernels to be remove, then the next step is to remove them. You can use either apt or dpkg to remove them. My preference is to use apt. Thus the command below would look like the following:
iamadmin@thepost:~/ubuntu-automation/utils$ sudo apt-get autoremove --purge linux-image-4.15.0-34-generic \ linux-image-4.15.0-38-generic linux-image-4.15.0-39-generic linux-image-4.15.0-42-generic linux-image-4.15.0-43-generic \ linux-image-4.15.0-46-generic linux-image-4.15.0-47-generic linux-image-4.15.0-50-generic linux-image-4.15.0-51-generic \ linux-image-4.15.0-54-generic linux-image-4.15.0-58-generic linux-image-4.15.0-88-generic linux-image-4.15.0-99-generic
You will need to replace the names of each of the packages in provided in the previous section to be used in this section of the code.
After entering the command, you may receive a prompt similiar to the one below.
Reading package lists... Done Building dependency tree Reading state information... Done The following packages will be REMOVED: linux-headers-4.15.0-36* linux-headers-4.15.0-36-generic* linux-headers-4.15.0-44* linux-headers-4.15.0-44-generic* linux-headers-4.15.0-45* linux-headers-4.15.0-45-generic* linux-headers-4.15.0-52* linux-headers-4.15.0-52-generic* linux-headers-4.15.0-70* linux-headers-4.15.0-70-generic* linux-headers-4.15.0-72* linux-headers-4.15.0-72-generic* linux-headers-4.15.0-74* linux-headers-4.15.0-74-generic* linux-headers-4.15.0-76* linux-headers-4.15.0-76-generic* linux-headers-4.15.0-91* linux-headers-4.15.0-91-generic* linux-image-unsigned-4.15.0-70-generic* 0 upgraded, 0 newly installed, 19 to remove and 7 not upgraded. After this operation, 814 MB disk space will be freed. Do you want to continue? [Y/n] y
If you do receive such prompt, enter in "Y".
I received a message that some directories were not able to be removed. The reason being is because they were not empty. Thus the package manager would not remove these.
rmdir: failed to remove '/lib/modules/4.15.0-70-generic': Directory not empty
It is safe to remove this and any other directories that are listed. To remove them, you will need to run the command:
sudo rm -r /lib/modules/4.15.0-70-generic
My experience has been that sometimes the old packages are not automatically removed when Unattended Upgrades runs. I have not quite figured out why this is the case.
Linux packages take up a lot of space on your system. By making sure you clean them off when they are no longer used, you can make sure that your system runs smoothly and does not become clogged with old junk.