Раздел /boot заполнен старыми ядрами, а apt отказывается их удалять: выход через dpkg

Тупик, знакомый владельцам виртуальных машин со старой разметкой: маленький отдельный /boot, годы обновлений, и в какой-то момент установка любого пакета падает с «No space left on device».

Что было. На Ubuntu 16.04 при установке очередного пакета обновление ядра не смогло записать образ initramfs: /boot был заполнен полностью. Обычный apt-get purge старых ядер не срабатывал: чтобы завершить прерванную настройку пакетов, apt сначала пытался достроить тот же initramfs, для которого места не было. Круг замкнулся.

Что помогло. Удалить одно-два старых ядра напрямую через dpkg, минуя apt:

uname -r                              # какое ядро загружено сейчас — его не трогаем
dpkg --list 'linux-image*' | grep ^ii # какие установлены
sudo dpkg -P linux-image-4.13.0-36-generic   # старое ядро из списка

Как только появилось место, sudo dpkg --configure -a и sudo apt-get autoremove --purge довели дело до конца. Затем автор переустановил метапакет linux-generic-hwe-16.04, чтобы снова получать обновления ядра, и подтвердил, что система в порядке.

Правила безопасности.

  1. Никогда не удалять текущее ядро (uname -r) и метапакеты linux-image-generic, linux-generic.
  2. Если совсем нет места даже для dpkg, вручную удалить только файлы initrd.img-* старых версий из /boot, а потом штатно удалить их пакеты.
  3. После очистки проверить ls /boot и df -h /boot, убедиться, что update-grub отработал.

Как не возвращаться к этому.

  • После каждого обновления ядра sudo apt autoremove --purge. В современных Ubuntu старые ядра удаляются автоматически, если пакеты не помечены как установленные вручную; проверка: apt-mark showmanual | grep linux-image.
  • При создании виртуальной машины отдельный /boot меньше 1 ГБ лучше не делать вовсе.

Управление ядрами описано в документации Ubuntu.