Tell me more ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

My /boot partition is nearly full and I get a warning every time I reboot my system. I already deleted old kernel packages (linux-headers...), actually I did that to install a newer kernel version that came with the automatic updates. After installing that new version, the partition is nearly full again. So what else can I delete? Are there some other files associated to the old kernel images?

Here is a list of files that are on my /boot partition:

:~$ ls /boot/
abi-2.6.31-21-generic         lost+found
abi-2.6.32-25-generic         memtest86+.bin
abi-2.6.38-10-generic         memtest86+_multiboot.bin
abi-2.6.38-11-generic         System.map-2.6.31-21-generic
abi-2.6.38-12-generic         System.map-2.6.32-25-generic
abi-2.6.38-8-generic          System.map-2.6.38-10-generic
abi-3.0.0-12-generic          System.map-2.6.38-11-generic
abi-3.0.0-13-generic          System.map-2.6.38-12-generic
abi-3.0.0-14-generic          System.map-2.6.38-8-generic
boot                          System.map-3.0.0-12-generic
config-2.6.31-21-generic      System.map-3.0.0-13-generic
config-2.6.32-25-generic      System.map-3.0.0-14-generic
config-2.6.38-10-generic      vmcoreinfo-2.6.31-21-generic
config-2.6.38-11-generic      vmcoreinfo-2.6.32-25-generic
config-2.6.38-12-generic      vmcoreinfo-2.6.38-10-generic
config-2.6.38-8-generic       vmcoreinfo-2.6.38-11-generic
config-3.0.0-12-generic       vmcoreinfo-2.6.38-12-generic
config-3.0.0-13-generic       vmcoreinfo-2.6.38-8-generic
config-3.0.0-14-generic       vmcoreinfo-3.0.0-12-generic
extlinux                      vmcoreinfo-3.0.0-13-generic
grub                          vmcoreinfo-3.0.0-14-generic
initrd.img-2.6.31-21-generic  vmlinuz-2.6.31-21-generic
initrd.img-2.6.32-25-generic  vmlinuz-2.6.32-25-generic
initrd.img-2.6.38-10-generic  vmlinuz-2.6.38-10-generic
initrd.img-2.6.38-11-generic  vmlinuz-2.6.38-11-generic
initrd.img-2.6.38-12-generic  vmlinuz-2.6.38-12-generic
initrd.img-2.6.38-8-generic   vmlinuz-2.6.38-8-generic
initrd.img-3.0.0-12-generic   vmlinuz-3.0.0-12-generic
initrd.img-3.0.0-13-generic   vmlinuz-3.0.0-13-generic
initrd.img-3.0.0-14-generic   vmlinuz-3.0.0-14-generic

Currently, I'm using the 3.0.0-14-generic kernel.

share|improve this question

7 Answers

up vote 27 down vote accepted

You've a lot unused kernels. Remove all but the last kernels with:

sudo apt-get purge linux-image-{3.0.0-12,2.6.3{1-21,2-25,8-{1[012],8}}}

This is shorthand for:

sudo apt-get purge linux-image-3.0.0-12 linux-image-2.6.31-21 linux-image-2.6.32-25 linux-image-2.6.38-10 linux-image-2.6.38-11 linux-image-2.6.38-12 linux-image-2.6.38-8

Removing the linux-image-x.x.x-x package will also remove linux-image-x.x.x-x-generic.

The headers are installed into /usr/src and are used when building out-tree kernel modules (like the proprietary nvidia driver and virtualbox). Most users should remove these header packages if the matching kernel package (linux-image-*) is not installed.

To list all installed kernels, run:

dpkg -l linux-image-\* | grep ^ii

One command to show all kernels and headers that can be removed, excluding the current running kernel:

kernelver=$(uname -r | sed -r 's/-[a-z]+//')
dpkg -l linux-{image,headers}-"[0-9]*" | awk '/ii/{print $2}' | grep -ve $kernelver

It selects all packages named starting with linux-headers-<some number> or linux-image-<some number>, prints the package names for installed packages and then excludes the current loaded/running kernel (not necessarily the latest kernel!). This fits in the recommendation of testing a newer kernel before removing older, known-to-work kernels.

So, after upgrading kernels and rebooting to test it, you can remove all other kernels with:

sudo apt-get purge $(dpkg -l linux-{image,headers}-"[0-9]*" | awk '/ii/{print $2}' | grep -ve "$(uname -r | sed -r 's/-[a-z]+//')")
share|improve this answer
Fantastic answer. One further piece of info would help: How can you tell (for sure) which of the kernels you're using? Presumably you can't just assume it's the last one... Edit: And it looks like the answer is uname -a. Probably best to ensure you don't have a pending restart-to-install-new-kernel pending (as I did; but I noted the mismatch between uname -a and the "latest" kernel). – T.J. Crowder Jun 14 '12 at 8:39
The currently loaded kernel is indeed visible by executing uname -a. (you can extract the kernel version part with uname -r as often combined with sth like sudo apt-get install linux-headers-$(uname -r)). You can check the kernel that will be loaded on the next boot by checking the boot config, typically /boot/grub/grub.cfg. – Lekensteyn Jun 14 '12 at 11:06
@ Lekensteyn: Thanks again. Finding this answer this morning was really, really helpful. – T.J. Crowder Jun 14 '12 at 11:12
If only this answer was more generic with regards to other people's systems. Could you provide a line that automatically removes all but the newest kernel image? – freddyb Aug 13 '12 at 13:25
1  
@freddyb Done. Note that the commands prints/removes kernels other than the loaded/booted one. – Lekensteyn Aug 13 '12 at 13:57
show 4 more comments

Your boot partition is full. Since this is a kernel update, these files will be copied to the boot partition so you need to clean in out. Here is a blog post that will show you how to clear the old kernel images with one command. I'll give a basic synopsis of the method. Use this command to print out the current version of your kernel:

uname -r

Then use this command to print out all the kernels you have installed that aren't your newest kernel:

dpkg -l linux-* | awk '/^ii/{ print $2}' | grep -v -e `uname -r | cut -f1,2 -d"-"` | grep -e [0-9]

Make sure your current kernel isn't on that list. Notice how this is the majority of the final command (down below). To uninstall and delete these old kernels you will want to pipe these arguments to:

sudo apt-get -y purge

Now we can do everything we want by combining these last two commands into this unholy mess:

dpkg -l linux-* | awk '/^ii/{ print $2}' | grep -v -e `uname -r | cut -f1,2 -d"-"` | grep -e [0-9] | xargs sudo apt-get -y purge

And that one command will take care of everything for you. I will confirm that this does work perfectly but never trust anybody on the internet. :) For more info, the blog post gives a very good explanation of what each part of the command does so read through it so you are satisfied that it does what you want it to do.

share|improve this answer
This worked great, thanks. – Michael Durrant Feb 21 at 3:59

enter image description here

If you haven't already got synaptic manager installed:

sudo apt-get install synaptic

Start the application and select the options shown.

You should be able to highlight all the "linux-" packages with the version "2.6.x" where x is between 31 to 38 according to the files in your /boot folder.

Right-click each of those linux packages and choose the option "Mark for Complete Removal". Finally click the apply button. This will remove all the files and any associated files. Your /boot folder should now be a bit-more tidier.

share|improve this answer

You can stop using a separate /boot partition, then you won't have such limited space there. To do this, unmount the partition, then mount it somewhere else and copy all of the files there to the /boot directory in your root partition, then remove the entry from /etc/fstab and reinstall grub. For example ( you will need to use the correct partition ):

sudo -s
umount /boot
mount /dev/sda2 /mnt
cp -a /mnt/* /boot/
umount /mnt
gedit /etc/fstab
grub-install /dev/sda

You can then use gparted to delete the old /boot partition, and possibly extend the root partition to use that space. To extend the root partition you will need to boot from the livecd, and the free space needs to be immediately to the right. If the /boot partition is currently to the left of the root partition, then you will need to first move the root partition to the left, then extend it, but this can take a very, very long time, so may not be worth the trouble.

share|improve this answer
Moving /boot to my main partition isn't a solution for me since everything but /boot is encrypted. You couldn't know that from my question, sorry. – user6722 Dec 24 '11 at 14:15
apt-get autoremove

This command is doing the job automatically.

share|improve this answer
2  
As the name suggests, apt-get AUTOremove is an automated operation where the system takes its "best guess" what you are trying to achieve. It should not be used as a substitute for common sense system administration. The problem with this approach: If you (or an update) removes a package that is part of this dependency list the auto-remove function wants to remove all other packages in the dependency list, leaving you with a system without working desktop (and sometimes even with a completely broken system). – Rinzwind Nov 5 '12 at 10:09
Reference: 1 of many sources for this comment above: linuxquestions.org/questions/debian-26/… – Rinzwind Nov 5 '12 at 10:10

In aptitude or synaptic there is a section "old or manually installed packaged". There should be the old linux packages there.

share|improve this answer

Let me throw in my two cents here as well, although this is an old question.

Sharing is caring, so here we go with a Bash function I have been using successfully on Debian 5 and 6 as well as Ubuntu versions between 10.04 and 12.10. It has evolved a bit over time but never failed me. It automates the "decision process".

NB: feel free to point out flaws and suggest improvements and I'll try my best to incorporate them.

function prune-kernels
{
        [[ -f "/etc/debian_version" ]] || { echo -e "\033[01;32mERROR:\033[00m This has only been tested on Debian/Ubuntu."; return; }
        [[ -e "/vmlinuz" ]] || { echo -e "\033[01;32mERROR:\033[00m Expected /vmlinuz to exist."; return; }
        [[ "$UID" -eq "0" ]] || local SUDO=sudo
        # Figure out the name of the newest and the previous kernel
        local OLDKRNL=$(readlink -f /vmlinuz.old)
        local NOWKRNL=$(readlink -f /vmlinuz)
        # If vmlinuz doesn't exist, Also prune "/vmlinuz.old"?
        [[ -e "/vmlinuz.old" ]] || OLDKRNL="$NOWKRNL"
        # Also prune "/vmlinuz.old"? If so, pretend old and new have the same name to skip only the new one
        [[ "$1" == "--old" ]] && local OLDKRNL="$NOWKRNL"
        # Strip path
        OLDKRNL="${OLDKRNL##*/vmlinuz-}"
        NOWKRNL="${NOWKRNL##*/vmlinuz-}"
        local VERSIONS=$(echo $(for krnl in /boot/vmlinuz-*; do echo "${krnl##*/vmlinuz-}"; done) $(for krnl in $(dpkg -l|command grep 'linux-image'|command grep '^ii'|command grep -v 'meta-package'|command grep 'linux-image-[[:digit:]]\.[[:digit:]]*\.[[:digit:]]'|awk '{print $2}'); do echo ${krnl##linux-image-}; done)|sort|uniq|sed -e "s:$NOWKRNL::g;s:$OLDKRNL::g;s:$(uname -r)::g")
        echo -ne "\033[01;32mSkipping \033[01;33mthe following kernels:\033[00m $NOWKRNL"
        [[ "$(uname -r)" == "$NOWKRNL" ]] || { echo -ne ", $(uname -r)"; }
        echo -ne " (\033[0;32mcurrently running\033[00m)"
        [[ "$OLDKRNL" == "$NOWKRNL" ]] || echo -ne ", $OLDKRNL (\033[0;33mold kernel\033[00m)"
        echo ""
        # Remove packages
        local PACKAGES=$(for i in $VERSIONS; do echo -n "linux-image-$i linux-headers-$i "; done)
        if [[ -n "$PACKAGES" ]]; then
                echo -e "\033[0;32m[STEP 1] \033[01;33mRemoving packages\033[00m"
                $SUDO apt-get remove $PACKAGES || { echo -e "\033[01;31mSeems that apt-get was not successful, aborting.\033[00m"; return; }
        else
                echo -e "\033[01;32mNo packages need to be removed.\033[00m"
        fi
        # Remove any remaining kernel images etc from /boot
        local FILES=$(for fname in $(for i in $VERSIONS; do echo -n "/boot/abi-$i /boot/initrd.img-$i config-$i System.map-$i vmcoreinfo-$i vmlinuz-$i "; done); do [[ -f "$fname" ]] && { echo -n "$fname "; }; done)
        if [[ -n "$FILES" ]]; then
                echo -e "\033[0;32m[STEP 2] \033[01;33mNow removing remaining files:\033[00m $FILES"
                $SUDO rm -f $FILES
        else
                echo -e "\033[01;32mNothing else to clean up.\033[00m"
        fi
}

Put the function into a file and source it from your .bashrc or simply source it from the shell adhoc and run it then. Unless you did something fancy to your apt-get settings, this will prompt before taking action.

The function also takes a parameter --old to remove all but the running kernel. By default it will skip the running and the old (/vmlinuz.old) kernels during pruning.

Also note: this function does work nicely even in scenarios where the running kernel is older than the current (/vmlinuz link) and the old (/vmlinuz.old link) kernels.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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