Ubuntu – How to remove old kernels from the terminal

aptdpkggrub2kernel

I have been going through various questions about how to clean up old Linux kernels. They all seem to have different answers and they are old, so someone is bound to say the question is too old and start a new post, so here it is:

I want to do all the following:

  1. Remove old Linux kernels manually in terminal.
  2. Remove all configuration files
  3. Remove all header files
  4. Remove unnecessary inodes?
  5. Explain why dpkg -l | grep linux-image does not return the same results as what I see in my grub2 listing during boot
  6. Explain rc vs ii in the dpkg -l | grep linux-image listing
  7. Explain the discrepancy between entries in /usr/src directory (or wherever these files are found in other Ubuntu versions) and the above two methods of determining excess kernel versions.
  8. What are the ramifications of a complete cleanup of older kernels. Do I need to worry about dependencies? How do I know if any apps on my computer are dependent on the configurations files of older kernels.

What I don't want:

  • Links to other answers that you have not personally tested or do not address ALL the issues involved in a complete cleanup.
  • Any answer you have not personally tested.
  • Scripts that attempt to automatically clean everything at once. I just want to do this manually until I fully understand everything that is going on.

Let's please get a comprehensive solution to the kernel buildup problem. I am currently playing with an older version of Ubuntu (10.04) before I upgrade, but I have had the same problem with Ubuntu 12.04. If the solution is different for different versions, please state the version you used to test your solution.

What works:

uname -r

This correctly returns the kernel version I am currently using.

Things that don't work:

sudo apt-get autoremove
sudo apt-get clean
sudo apt-get autoremove linux-image-x.x.xx-xx-generic

What I thought should work, but did not:

sudo apt-get purge linux-image-x.x.xx-xx-generic

This worked to diminish the list generated by dpkg -l | grep linux-image:

sudo dpkg --purge linux-image-x.x.xx-xx-generic

Also here is a head start on the rc/ii issue:

ii means 'It should be installed and it is installed' whereas
rc means 'It's removed/uninstalled but it's configuration files are still there'.

I think this addresses the issue between the discrepancy between the terminal listing and the grub2 menu at bootup. As I recall, the ii listings match the grub2 listing. The question here is how did the ii entries get there in the first place?

Best Answer

The accumulation of old kernels until /boot is full, thereby breaking apt, is a bug: LP #1357093, with a fix implemented in all flavors of Ubuntu 16.04 and newer.

Most users who notice this problem installed 'whole-disk encryption', which creates a tiny unencrypted /boot partition. Since it's tiny, the partition fills quickly, and these users notice the problem much sooner than others.

When a new kernel is installed, the /etc/kernel/postinst.d/apt-auto-removal script marks older kernels as eligible for autoremoval...but doesn't run autoremove. The lack of autoremove was originally intended to allow a human to review the list of removed packages.

The bugfix to LP #1357093 works for most users - if it doesn't work for you, then there is another underlying cause preventing old kernel packages from being apt-marked as eligible for autoremove. Seek one-on-one help in the Ubuntu support channels.

In older versions of Ubuntu, you must fix weed old kernels to preserve space manually. How you fix it manually depends upon whether your /boot is full or not. Most users don't notice the problem until /boot is full, and they are getting apt and dpkg no-space-left-on-device errors.

If /boot is not full, and apt works properly, a simple

sudo apt-get autoremove      ## Ubuntu 14.04 and older
sudo apt autoremove          ## Ubuntu 16.04 and newer

should remove all kernel packages that are eligible for autoremoval.

If /boot is full, and apt actions fail with the dpkg error 'no space left on device', then it is too late to use autoremove.

It's too late because Aptdaemon queues package actions. Autoremove is at the back of the queue, and apt aborts the entire remaining queue when any action fails...including running out of space. (This is arguably a bug in apt/aptdaemon)

The best practice here is to use 'uname' and 'dpkg' to remove one or two old kernels, freeing space for apt to complete it's queued actions. Then autoremove will work.

Example:

$ uname -r
3.16.0-36-generic    ## This is kernel you MUST NOT remove.

$ dpkg -l | grep linux-image
rc  linux-image-3.16.0-23-generic    ## 'rc' means already removed
rc  linux-image-3.16.0-28-generic    ## 'rc' can be safely ignored
rc  linux-image-3.16.0-29-generic
ii  linux-image-3.16.0-30-generic    ## 'ii' means installed. Removable
ii  linux-image-3.16.0-31-generic    ## Removable
ii  linux-image-3.16.0-33-generic    ## Removable
ii  linux-image-3.16.0-34-generic    ## Backup working kernel. Don't remove
ii  linux-image-3.16.0-36-generic    ## Current kernel. DO NOT REMOVE

## Use dpkg to remove one older kernel, freeing enough space for apt to work
$ sudo dpkg --remove linux-image-3.16.0-30-generic
$ sudo apt-get autoremove     ## Ubuntu 14.04 and older
$ sudo apt autoremove         ## Ubuntu 16.04 and newer

If you have been ignoring the problem for a long time, then there are second-order effects, like linux-image-generic pointing to the wrong kernel version, and apt dependency errors. There is no single way of fixing all of these at once.

Generally, the easy way to clean up most of these problems is to clean the old packages out of your local package cache, update your package database, and reinstall the offending packages from the Ubuntu repositories (instead of your local cache).

$ sudo apt-get update       ## Refresh the package database (14.04 and older)
$ sudo apt update           ##                              (16.04 and newer)

$ sudo apt-get autoclean    ## Delete the obsolete packages from your local cache (14.04 and older)
$ sudo apt autoclean        ##                                                    (16.04 and newer)

$ sudo apt-get install --reinstall <packagename>     ## Reinstall the offending package with the latest version in the Ubuntu repositories (14.04 and older)
$ sudo apt install --reinstall <packagename>         ##                (16.04 and newer)

If you still encounter apt and/or dpkg errors, seek one-on-one help in the Ubuntu support channels.

Related Question