150

I try to do do-release-upgrade but then I get:

Not enough free disk space

The upgrade has aborted. The upgrade needs a total of 25.7 M free space on disk '/boot'. Please free at least an additional 25.7 M of disk space on '/boot'. Empty your trash and remove temporary packages of former installations using 'sudo apt-get clean'.

Output of df:

                    237251272 214797108  10402504  96% /
udev                    488120         4    488116   1% /dev
tmpfs                   198676       668    198008   1% /run
none                      5120         0      5120   0% /run/lock
none                    496684         0    496684   0% /run/shm
/dev/sda1               233191    225867         0 100% /boot

How come there is no space left on boot? Here's the output of ls -as /boot:

total 221839
    4 .
    4 ..
  645 abi-2.6.32-34-generic-pae
  698 abi-2.6.35-30-generic-pae
  727 abi-2.6.38-12-generic-pae
  727 abi-3.0.0-12-generic-pae
  727 abi-3.0.0-13-generic-pae
  727 abi-3.0.0-14-generic-pae
  727 abi-3.0.0-15-generic-pae
  727 abi-3.0.0-16-generic-pae
  727 abi-3.0.0-17-generic-pae
  727 abi-3.0.0-19-generic-pae
  761 abi-3.0.0-20-generic-pae
  115 config-2.6.32-34-generic-pae
  128 config-2.6.35-30-generic-pae
  136 config-2.6.38-12-generic-pae
  140 config-3.0.0-12-generic-pae
  140 config-3.0.0-13-generic-pae
  140 config-3.0.0-14-generic-pae
  140 config-3.0.0-15-generic-pae
  140 config-3.0.0-16-generic-pae
  140 config-3.0.0-17-generic-pae
  140 config-3.0.0-19-generic-pae
  140 config-3.0.0-20-generic-pae
    5 grub
10773 initrd.img-2.6.32-34-generic-pae
13619 initrd.img-2.6.35-30-generic-pae
15365 initrd.img-2.6.38-12-generic-pae
16481 initrd.img-3.0.0-12-generic-pae
16487 initrd.img-3.0.0-13-generic-pae
16501 initrd.img-3.0.0-14-generic-pae
16476 initrd.img-3.0.0-15-generic-pae
16481 initrd.img-3.0.0-16-generic-pae
16478 initrd.img-3.0.0-17-generic-pae
   12 lost+found
  174 memtest86+.bin
  176 memtest86+_multiboot.bin
 1700 System.map-2.6.32-34-generic-pae
 1841 System.map-2.6.35-30-generic-pae
 2115 System.map-2.6.38-12-generic-pae
 2141 System.map-3.0.0-12-generic-pae
 2141 System.map-3.0.0-13-generic-pae
 2143 System.map-3.0.0-14-generic-pae
 2146 System.map-3.0.0-15-generic-pae
 2147 System.map-3.0.0-16-generic-pae
 2147 System.map-3.0.0-17-generic-pae
 2148 System.map-3.0.0-19-generic-pae
 2149 System.map-3.0.0-20-generic-pae
    2 vmcoreinfo-2.6.32-34-generic-pae
    2 vmcoreinfo-2.6.35-30-generic-pae
    2 vmcoreinfo-2.6.38-12-generic-pae
    2 vmcoreinfo-3.0.0-12-generic-pae
    2 vmcoreinfo-3.0.0-13-generic-pae
    2 vmcoreinfo-3.0.0-14-generic-pae
    2 vmcoreinfo-3.0.0-15-generic-pae
    2 vmcoreinfo-3.0.0-16-generic-pae
    2 vmcoreinfo-3.0.0-17-generic-pae
    2 vmcoreinfo-3.0.0-19-generic-pae
    2 vmcoreinfo-3.0.0-20-generic-pae
 4092 vmlinuz-2.6.32-34-generic-pae
 4347 vmlinuz-2.6.35-30-generic-pae
 4567 vmlinuz-2.6.38-12-generic-pae
 4675 vmlinuz-3.0.0-12-generic-pae
 4676 vmlinuz-3.0.0-13-generic-pae
 4681 vmlinuz-3.0.0-14-generic-pae
 4698 vmlinuz-3.0.0-15-generic-pae
 4700 vmlinuz-3.0.0-16-generic-pae
 4700 vmlinuz-3.0.0-17-generic-pae
 4703 vmlinuz-3.0.0-19-generic-pae
 4705 vmlinuz-3.0.0-20-generic-pae

Output of uname -a:

 Linux kitsch 3.0.0-17-generic-pae #30-Ubuntu SMP Thu Mar 8 17:53:35 UTC 2012 i686 i686 i386 GNU/Linux
2
  • related - askubuntu.com/questions/65096/… May 28, 2012 at 3:46
  • sudo apt-get autoremove Worked like a charm. In my case it cleaned up /boot from unused kernels. Disk usage went down from 100% to 40% used.
    – user310604
    Jul 30, 2014 at 11:11

7 Answers 7

201

Your /boot partition is filled with old kernels. It does that sometimes, not sure why it is never fixed. You can easily remove the old kernels if you know which packages they came in.

First check uname -a to check your current version.

Then run the following command:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

This command will list all packages that you no longer need. I don't like removing them automatically, I like to be in control when it comes to removing kernels. So for every package listed do the following:

sudo apt-get -y purge some-kernel-package

Intermezzo

This intermezzo describes in more detail how the commands work and tries to fix an issue with linux-libc-dev:amd64. Most users can skip this paragraph.

  • dpkg -l 'linux-*' - list all packages that have a name starting with 'linux-'
  • sed '/^ii/!d; - remove all lines that do not start with ii
  • uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/" - find the current running kernel version
  • /'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d - remove all lines, except the ones containing the current running kernel version number
  • s/^[^ ]* [^ ]* \([^ ]*\).*/\1/ - for each line list only the package name
  • /[0-9]/!d - remove lines that do not contain numbers.

To fix Frederick Nord's issue I think the command can be amended as follows:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d;/^linux-\(headers\|image\)/!d'

It basically adds an extra filter:

  • /^linux-\(headers\|image\)/!d - delete all lines that do not start with linux-headers or linux-image

/Intermezzo

Where some-kernel-package can be replaced with one of the packages listed. Just beware that you don't remove the kernel packages that are in current use (as listed by the uname -a) eg. sudo apt-get purge -y linux-headers-3.0.0-12 etc.

It can be automated further using the xargs command, but I don't like that. It is a personal thing. However, here's the command to do so:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge

This is what my /boot looks like, one spare kernel (2.6.38-11) just in case and 3.2.0-24 being current:

$ ls -l /boot
total 59388
-rw-r--r-- 1 root root   730545 Sep 13  2011 abi-2.6.38-11-generic
-rw-r--r-- 1 root root   791023 Apr 25 13:51 abi-3.2.0-24-generic
-rw-r--r-- 1 root root   130326 Sep 13  2011 config-2.6.38-11-generic
-rw-r--r-- 1 root root   140341 Apr 25 13:51 config-3.2.0-24-generic
drwxr-xr-x 3 root root     5120 May 27 17:46 grub
-rw-r--r-- 1 root root 20883146 Oct  1  2011 initrd.img-2.6.38-11-generic
-rw-r--r-- 1 root root 22474219 May  5 09:04 initrd.img-3.2.0-24-generic
drwxr-xr-x 2 root root    12288 Apr 16  2009 lost+found
-rw-r--r-- 1 root root   176764 Nov 27 11:00 memtest86+.bin
-rw-r--r-- 1 root root   178944 Nov 27 11:00 memtest86+_multiboot.bin
-rw------- 1 root root  2656297 Sep 13  2011 System.map-2.6.38-11-generic
-rw------- 1 root root  2884358 Apr 25 13:51 System.map-3.2.0-24-generic
-rw------- 1 root root     1369 Sep 13  2011 vmcoreinfo-2.6.38-11-generic
-rw------- 1 root root  4526784 Sep 13  2011 vmlinuz-2.6.38-11-generic
-rw------- 1 root root  4965776 Apr 25 13:51 vmlinuz-3.2.0-24-generic

And file system usage:

$ df -h /boot
Filesystem Size Used Avail Use% Mounted
/dev/sda5  228M  63M  154M  29% /boot
7
  • 2
    This solution was heavily inspired on an article by OzzyFrank at ubuntugenius.wordpress.com/2011/01/08/…
    – jippie
    May 27, 2012 at 15:37
  • 10
    Yes, why is this an issue is the question? This shouldn't be on the user to handle. Nov 1, 2013 at 20:58
  • 3
    FWIW: This also matched linux-libc-dev:amd64 for me. So it may very well be a little too generous. May 1, 2014 at 13:30
  • 5
    It does that sometimes, not sure why it is never fixed Ubuntu has made the decision, for better or worse, to provide regular new kernels as new packages rather than as upgrades to existing packages, to give the option of having multiple kernels installed and switching between them at will. I agree that this assumption doesn't suit the 95% of people who just want the latest kernel (and maybe one fallback in case of new boot problems), and who don't want to manage the installed kernels themself. Perhaps in the future Ubuntu will change this behaviour. For now, make sure your /boot is huge. Jul 30, 2014 at 11:19
  • 3
    @thomasrutter If you (like me and the 95% of people you are talking about) think this bug is important, vote on it here: bugs.launchpad.net/ubuntu/+source/update-manager/+bug/1183692
    – FriendFX
    Oct 12, 2016 at 11:24
55
sudo apt-get autoremove

did the trick for me, it cleaned up successfully all the unused kernel packages.

7
  • 5
    this is not correct. from man apt-get autoremove is used to remove packages that were automatically installed to satisfy dependencies for some package and that are no more needed. a kernel would not be installed to satisfy dependencies, they are installed during upgrades.
    – dward
    May 30, 2014 at 21:44
  • 5
    @neon_overload I just posted it because it did the trick, for me.
    – topless
    Jul 30, 2014 at 14:20
  • 1
    @dward It did free some space for me : before autremove : /dev/sda1, 240M total, 171M used, 57M free, 75% used /boot after: /dev/sda1, 240M total, 129M used, 98M free, 57% used /boot May 8, 2015 at 8:39
  • 11
    There should be a button to perform this task in the "Not enough free disk space" dialogue. This would especially help novice users that are not familiar with the command line.
    – Martin R.
    Jan 6, 2016 at 21:28
  • 2
    Did the trick without breaking my OS Mar 22, 2017 at 21:33
4

Compared to other GUI answers here, the advantage of this answer is native Ubuntu Bash is used without installing third-party applications.

Zenity and Bash based solution

Zenity provides a nice GUI interface to the terminal to process a list and select items with radio-buttons:

rm-kernels 1

The current kernel you booted with cannot be removed and isn't included in the list. The size reported is how much will be saved in /boot directory. More is saved on your disk because kernel binaries reside in other areas too. July 27, 2017 note: The directories /usr/src/*kernel_version* and /lib/modules/*kernel_version* are now included as well.

The Modified Date is discovered using the stat command. On my system that date is "touched" every time the kernel is booted using this (How do you find out when a specific kernel version was last booted?) cron reboot script. However, on your system the date will be the kernel release date, not the last time you booted it.

apt-get purge gives you chance to abort

You are given a final opportunity to view everything that will be purged and see the total disk space (somewhat misleading) that will be recovered:

The following packages will be REMOVED:
  linux-headers-4.7.1-040701* linux-headers-4.7.1-040701-generic*
  linux-headers-4.7.2-040702* linux-headers-4.7.2-040702-generic*
  linux-headers-4.7.3-040703* linux-headers-4.7.3-040703-generic*
  linux-headers-4.8.1-040801* linux-headers-4.8.1-040801-generic*
  linux-headers-4.8.10-040810* linux-headers-4.8.10-040810-generic*
  linux-headers-4.8.11-040811* linux-headers-4.8.11-040811-generic*
  linux-headers-4.8.4-040804* linux-headers-4.8.4-040804-generic*
  linux-headers-4.8.5-040805* linux-headers-4.8.5-040805-generic*
  linux-image-4.7.1-040701-generic* linux-image-4.7.2-040702-generic*
  linux-image-4.7.3-040703-generic* linux-image-4.8.1-040801-generic*
  linux-image-4.8.10-040810-generic* linux-image-4.8.11-040811-generic*
  linux-image-4.8.4-040804-generic* linux-image-4.8.5-040805-generic*
0 upgraded, 0 newly installed, 24 to remove and 2 not upgraded.
After this operation, 2,330 MB disk space will be freed.
Do you want to continue? [Y/n] 

The Code

Copy this code to an executable file named rm-kernels in /usr/local/bin:

#!/bin/bash

# NAME: rm-kernels
# PATH: /usr/local/bin
# DESC: Provide zenity item list of kernels to remove

# DATE: Mar 10, 2017. Modified Jul 28, 2017.

# NOTE: Will not delete current kernel.

#       With 10 kernels on an SSD, empty cache from sudo prompt (#) using:
#       # free && sync && echo 3 > /proc/sys/vm/drop_caches && free
#       First time for `du` 34 seconds.
#       Second time for `du` 1 second.

# PARM: If any parm 1 passed use REAL kernel size, else use estimated size.
#       By default `du` is not used and estimated size is displayed.

# Must be running as sudo
if [[ $(id -u) != 0 ]]; then
    zenity --error --text "root access required. Use: sudo rm-kernels"
    exit 99
fi

OLDIFS="$IFS"
IFS="|"
choices=()

current_version=$(uname -r)

for f in /boot/vmlinuz*
do
    if [[ $f == *"$current_version"* ]]; then continue; fi # skip current version
    [[ $f =~ vmlinuz-(.*) ]]
    v=${BASH_REMATCH[1]}        # example: 4.9.21-040921-generic
    v_main="${v%-*}"            # example: 4.9.21-040921

    # Kernel size in /boot/*4.9.21-040921-generic*
    s=$(du -ch /boot/*-$v* | awk '/total/{print $1}')

    if [[ $# -ne 0 ]] ; then    # Was a parameter passed?
        if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then
             # Kernel headers size in /usr/src/*4.9.21-040921*
             s2=$(du -ch --max-depth=1 /usr/src/*-$v_main* | awk '/total/{print $1}')
        else
             s2="0M"            # Linux Headers are not installed
        fi
        # Kernel image size in /lib/modules/4.9.21-040921-generic*
        s3=$(du -ch --max-depth=1 /lib/modules/$v* | awk '/total/{print $1}')
    else
        # Estimate sizof of optional headers at 125MB and size of image at 220MB
        if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then
             s2="125M"
        else
             s2="0M"            # Linux Headers are not installed
        fi
        s3="220M"
    fi

    # Strip out "M" provided by human readable option of du and add 3 sizes together
    s=$(( ${s//[^0-9]*} + ${s2//[^0-9]*} + ${s3//[^0-9]*} ))
    t=$(( t + s ))
    s=$s" MB"
    d=$(date --date $(stat -c %y $f) '+%b %d %Y') # Last modified date for display
    choices=("${choices[@]}" false "$v" "$d" "$s")
done

# adjust width & height below for your screen 640x480 default for 1920x1080 HD screen
# also adjust font="14" below if blue text is too small or too large

choices=(`zenity \
        --title "rm-kernels - Total: $t MB excluding: $current_version" \
        --list \
        --separator="$IFS" \
        --checklist --multiple \
        --text '<span foreground="blue" font="14">Check box next to kernel(s) to remove</span>' \
        --width=640 \
        --height=480 \
        --column "Select" \
        --column "Kernel Version Number" \
        --column "Modified Date" \
        --column " Size " \
        "${choices[@]}"`)
IFS="$OLDIFS"

i=0
list=""
for choice in "${choices[@]}" ; do
    if [ "$i" -gt 0 ]; then list="$list- "; fi # append "-" from last loop
    ((i++))

    short_choice=$(echo $choice | cut -f1-2 -d"-")
    header_count=$(find /usr/src/linux-headers-$short_choice* -maxdepth 0 -type d | wc -l)

    # If -lowlatency and -generic are purged at same time the _all header directory
    # remains on disk for specific version with no -generic or -lowlatency below.
    if [[ $header_count -lt 3 ]]; then
        # Remove all w.x.y-zzz headers
        list="$list""linux-image-$choice- linux-headers-$short_choice"
    else
        # Remove w.x.y-zzz-flavour header only, ie -generic or -lowlatency
        list="$list""linux-image-$choice- linux-headers-$choice" 
    fi

done

if [ "$i" -gt 0 ] ; then
     apt-get purge $list
fi

NOTE: You need sudo permission to create the file so use:

gksu gedit /usr/local/bin/rm-kernels

To make file executable use:

sudo chmod +x /usr/local/bin/rm-kernels

NOTE: For a server (Text based, not GUI) version of this script see: How do I remove old kernel versions to clean up the boot menu?


July 28, 2017 Updates

The calculated size of each kernel was taken from /boot/*kernel_version* which were 5 files totaling ~50 MB. The formula has changed to include the files in /usr/src/*kernel_version* and /lib/modules/*kernel_version*. The calculated size for each kernel is now ~400 MB. The above code for rm-kernels and rm-kernels-server has been updated. However, the sample screens above do not reflect these changes yet.

The default is to estimate the size of files for linux-headers at 125 MB and linux-image at 220 MB because du can be painfully slow unless files are in cache. To get the real size using du pass any parameter to the script.

The total of all kernel sizes (excluding the current running version which cannot be removed) is now show in the title bar.

The dialog box used to display each Kernel's Last Access Date. This date can get mass overwritten for all kernels during backup or similar operations. The dialog box now shows the Modified Date instead.

5
  • You are amazing! Really great thanks! You made me happy!
    – zhartaunik
    Jun 16, 2017 at 16:00
  • Great! Thanks for sharing. Finally easy and convenient way to handle this boring kernel management
    – Skazzi
    Mar 4, 2021 at 15:29
  • @Skazzi The script is almost four years old. It was probably written before Ubuntu introduced "signed kernels". Let me know if there are files left over after using script and I will update it. Mar 4, 2021 at 17:59
  • Doesn't it work anymore? "rmdir: failed to remove '/lib/modules/5.15.0-43-generic': Directory not empty"
    – smartmouse
    Aug 22, 2022 at 21:34
  • 1
    @smartmouse The modules library appeared a couple years ago after the answer was posted. Aug 23, 2022 at 0:52
1

For commandline ease:

https://github.com/erichs/bootnukem

git clone https://github.com/erichs/bootnukem.git
cd bootnukem
sudo ./install.sh

Then

sudo bootnukem --dry-run
1

You can easily handle kernels via synaptic package manager. But first you should know the currently used kernel-release name. You can find this out by running uname -r in terminal prompt:

linux@linux-desktop:~$ uname -r
4.4.0-75-generic

So at least this version you should keep untouched. Open synaptic and start filling in quick filter placeholder as shown below:

quick filter search box at top in synaptic

Now you can select all packages which you wish to delete and do:

Mark for complete removal > Apply

I would suggest to keep at least a latest current kernel package and one previous kernel. For instance in this case you can safely get rid of linux-image-4.4.0-66-generic and linux-image-extra-4.4.0-66-generic, but it would be good to keep 4.4.0-72 and of course 4.4.0-75.

0

Works on Linux Mint 18.3 (based on Ubuntu 16.04).

sudo apt-get purge $(dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | head -n -1) --assume-yes

Source: https://ubuntuforums.org/showthread.php?t=2248846&p=13146650#post13146650

0

I had a similar problem when I was trying to do an update using Software Updater and for me sudo apt full-upgrade did the trick.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .