My boot partition is on a SSD, so it doesn't have room for more than about 8 installed kernel versions, and eventually some kernel update will fail to install because my boot partition is full of old versions. There are many questions out there about how to remove old versions (even how to automate the process), but my question is simply this: Why doesn't apt-get autoremove detect and remove them automatically, and is there a way I can make it do so? I mean, apt-get is what installed them anyway, so it knows about them, so why does it choose to leave all old versions around?

  • 3
    possible duplicate of Why doesn't Ubuntu remove old kernels automatically? – Martin Schröder Jun 11 '15 at 8:27
  • 1
    Autoremove does remove old kernels under most circumstances. Kernels accumulate because the system does not run autoremove automatically by default. That's a setting in unattended-upgrades, and can be changed. Autoremove cannot remove old kernels when previously-queued apt actions (like installing a new kernel) fail (due to insufficient space). See bugs.launchpad.net/bugs/1357093 for a patch to unattended-upgrades that will begin removing old kernels automatically. – user535733 Dec 31 '15 at 18:10
up vote 30 down vote accepted

As to answer why , refer to the file /etc/apt/apt.conf.d/01autoremove-kernels

enter image description here

As you can see, apt is told to never autoremove the kernels , as told by another (script) file, /etc/kernel/postinst.d/apt-auto-removal. And here it is:

enter image description here

If your script-fu is good enough you could edit it to save only couple kernels, though I can't help you there as my script fu isn't that good

Update:

In the /etc/kernel/postinst.d/apt-auto-removal there is this part:

if [ "$latest_version" != "$installed_version" ] \
   || [ "$latest_version" != "$running_version" ] \
   || [ "$installed_version" != "$running_version" ]
then
        # We have at least two kernels that we have reason to think the
        # user wants, so don't save the second-newest version.
        previous_version=
fi

So if you compare the output of 01autoremove-kernels file and uname -r you'll realize that the currently running kernel and the most recent before it, are kept to be never removed by that script. There turns out is another file /etc/apt/apt.conf.d/01autoremove, where there is lines:

    APT
    {
      NeverAutoRemove
      {
            "^firmware-linux.*";
            "^linux-firmware$";
      };
  VersionedKernelPackages
  {
        # linux kernels
        "linux-image";
        "linux-headers";
        "linux-image-extra";
        "linux-signed-image";
        # kfreebsd kernels
        "kfreebsd-image";
        "kfreebsd-headers";
        # hurd kernels
        "gnumach-image";
        # (out-of-tree) modules
        ".*-modules";
        ".*-kernel";
        "linux-backports-modules-.*";
        # tools
        "linux-tools";
  };

So you could comment these out, and it will allow you to auto-remove the kernels with apt-autoremove, though remember - do this at your own risk

  • 1
    Very interesting! My /etc/apt/apt.conf.d/01autoremove-kernels has many lines, but only two versions among all of them: 3.13.0.{39,43}. But dpkg -l linux-* lists four versions, 3.13.0.{39,40,41,43}, so something other than /etc/apt/apt.conf.d/01autoremove-kernels is keeping those middle versions around, right? – BlueBomber Dec 20 '14 at 0:28
  • 1
    TL:DR : 01autoremove is the file you want, 01autoremove-kernels is probably just a protection, so that apt doesn't remove currently installed kernel and most recent (just in case newest screws up) – Sergiy Kolodyazhnyy Dec 20 '14 at 0:46
  • 1
    Unless I'm misreading 01autoremove, it's just protecting against auto-removal of the dependency packages, like linux-image-extra. Changing it shouldn't affect whether or not linux-image-3.16.0-31-generic gets autoremoved. None of the patterns in it match the package names that we want auto-removed. – Peter Cordes Apr 11 '15 at 9:41
  • 1
    @PeterCordes Don't remove or comment lines in /etc/apt/apt.conf.d/01autoremove. That does not help you in autoremoving old versioned kernel packages, but may have unwanted effects. The file does not protect from autoremoving linux-image-extra but packages that match regular expressions in the NeverAutoRemove section. – jarno Dec 24 '15 at 12:51
  • 2
    @BlueBomber, the reason why apt-get autoremovedoes not remove the kernels not listed in /etc/apt/apt.conf.d/01autoremove-kernelsis that those kernels are marked as manually installed; see my answer. – jarno Dec 26 '15 at 13:55

For me it helped to install latest (X)ubuntu (15.10). In earlier releases kernel packages may be marked as manually installed, at least, if installed by using Software Updater, so that sudo apt-get autoremove --purge can't delete them. There are bug reports concerning the issue: Bug #1175637, Bug #1439769

In earlier release, you could try to mark kernel packages automatically installed by sudo apt-mark auto $(apt-mark showmanual | grep -E "^linux-([[:alpha:]]+-)+[[:digit:].]+-[^-]+(|-.+)$") and run sudo apt-get autoremove --purge thereafter to see, if it makes difference. The command should still not remove kernels packages shown in /etc/apt/apt.conf.d/01autoremove-kernels, but it is safest to run apt-get autoremove with --dry-run option first.

  • Oh, the autoremove command tend to remove too many kernels, see Bug #1440608 – jarno Dec 24 '15 at 18:54
  • 1
    the apt-mark did the trick for me, wish I could upvote 10 times :P – Mike Gleason jr Couturier Feb 27 at 17:31

Update: the mentioned link no longer seems to be working.

Here's a link to a kernel purge script with fail-safe that Dustin Kirkland wrote a few years ago. It should still work on 12.04.

[removed non-working link]

I was going to test it on my 14.04 machine, but it seems I'm no longer experiencing the problem there (finally fixed via the regular update channel?). So if anyone with a lot of old kernels on his/her machine wants to test it, please do and share your findings.

KERNELS1=$(uname -r|cut -d - -f1-2); KERNELS2=$(for i in $(ls -l /vmlinuz*|awk '{print $(NF-0)}'); do echo $i |xargs basename|cut -d - -f2-3; done); dpkg -l|egrep 'linux-headers-[0-9]\.[0-9]\.[0-9]-[0-9]|linux-image-[0-9]\.[0-9]\.[0-9]-[0-9]'|egrep -v ''"${KERNELS1}"'|'"${KERNELS2}"''|awk '{print $2}'|xargs apt-get purge -y

I use this on Ubuntu 12.04!

This will keep the current running kernel as well as the newest installed kernel (vmlinuz) and the one before (vmlinuz.old). All other kernels and headers will be removed.

  • 4
    You really should explain what this does! – guntbert Sep 10 '15 at 8:55

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.