Разделы и монтирование: mount, fstab, df, du

Учимся видеть блочные устройства и разделы, монтировать их в дерево каталогов, прописывать монтирование на старте через fstab и быстро находить, кто съел диск.

Монтирование — подключение файловой системы раздела к точке (каталогу) в общем дереве /. До монтирования раздел существует как блочное устройство, но его файлы недоступны.

Зачем это знать на практике

Подключили новый диск к серверу или USB-флешку к ноутбуку — её надо смонтировать. Сервер не загружается, потому что в fstab опечатка. Логи внезапно забили корневой раздел, и сервис упал. Всё это — повседневная работа с разделами и монтированием. Без неё вы не выйдете за пределы того, что настроил установщик.

Блочные устройства и разделы

Диски в Linux представлены файлами устройств в /dev: /dev/sda — первый SATA/SAS-диск, /dev/nvme0n1 — первый NVMe-накопитель. Разделы на них нумеруются: /dev/sda1, /dev/sda2 или /dev/nvme0n1p1. Наглядную карту даёт lsblk:

lsblk
# NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
# sda           8:0    0   100G  0 disk
# ├─sda1        8:1    0   512M  0 part /boot
# └─sda2        8:2    0  99.5G  0 part /
# sdb           8:16   0   1T    0 disk
# └─sdb1        8:17   0   1T    0 part /data

Колонка TYPE отличает целый диск (disk) от раздела (part), а MOUNTPOINTS показывает, куда раздел смонтирован. Тип файловой системы на разделах удобно смотреть через lsblk -f или blkid:

sudo blkid
# /dev/sda2: UUID="3f1b...c9" TYPE="ext4"
# /dev/sdb1: UUID="9a77...0e" TYPE="ext4"

UUID — постоянный идентификатор файловой системы. Он важен: имена /dev/sdb могут меняться местами между загрузками, а UUID — нет.

mount и umount

Ручное монтирование: указываем устройство и точку монтирования (существующий пустой каталог).

sudo mkdir -p /mnt/data
sudo mount /dev/sdb1 /mnt/data        # подключить
mount | grep sdb1                      # проверить, что смонтировано
sudo umount /mnt/data                  # отключить

Если umount ругается «target is busy», значит, какой-то процесс держит файл на этом разделе. Найти виновника помогает lsof или fuser:

sudo lsof +D /mnt/data       # какие процессы открыли файлы внутри
sudo fuser -vm /mnt/data     # кто использует точку монтирования

Автомонтирование через /etc/fstab

Чтобы раздел монтировался автоматически при загрузке, его прописывают в /etc/fstab. Каждая строка — шесть полей: устройство, точка, тип ФС, опции, dump, fsck-порядок.

# <device>            <mount point>  <type>  <options>          <dump> <pass>
UUID=9a77...0e        /data          ext4    defaults,noatime    0      2

Поле pass: 0 — не проверять, 1 — для корня, 2 — для остальных. Использовать UUID вместо /dev/sdb1 — хорошая практика. После правки проверьте конфиг БЕЗ перезагрузки:

sudo mount -a            # смонтировать всё из fstab; ошибки вылезут сразу
findmnt --verify         # синтаксическая проверка fstab

Опасность: ошибка в fstab может сделать систему незагружаемой. Опция nofail в строке некритичного раздела разрешает загрузку, даже если устройство отсутствует.

df против du: сколько занято и кем

Это две разные вещи, и их путаница — источник вечных вопросов.

ИнструментЧто отвечает
df -hСколько свободно/занято на каждой смонтированной ФС (взгляд «сверху», от файловой системы)
du -shСколько занимает конкретный каталог суммой файлов (взгляд «снизу», от содержимого)
df -h                      # обзор всех разделов
# Filesystem  Size  Used Avail Use% Mounted on
# /dev/sda2    98G   71G   22G  77% /

du -sh /var/log            # размер одного каталога
# 3.4G  /var/log

Кто занял диск: рецепт поиска

Идём от корня вглубь, на каждом уровне сортируя по размеру:

# топ-10 самых жирных подкаталогов текущего уровня
sudo du -h --max-depth=1 / 2>/dev/null | sort -rh | head -n 10
# спускаемся в найденного «толстяка» и повторяем
sudo du -h --max-depth=1 /var 2>/dev/null | sort -rh | head -n 10

Конструкция 2>/dev/null прячет ошибки доступа, sort -rh сортирует «человеческие» размеры по убыванию. Для интерактивного поиска удобна утилита ncdu — она строит навигируемое дерево размеров.

Как это работает под капотом

Ядро ведёт таблицу монтирования: какая ФС подключена к какому каталогу. Когда вы обращаетесь к /data/file, VFS (Virtual File System — слой абстракции ядра) определяет, что /data — точка монтирования, и перенаправляет запрос драйверу ext4 на /dev/sdb1. Один каталог может «накрыть» другой: если смонтировать ФС поверх непустого каталога, старое содержимое временно скрывается под новой ФС (не удаляется — просто становится недоступным до umount). Именно поэтому df (спрашивает у ядра по таблице ФС) и du (обходит файлы) могут расходиться: du не видит файлы под точкой монтирования, а удалённый, но открытый файл df ещё считает занятым.

Частые ошибки

  • Монтировать поверх непустого каталога и потом «терять» файлы. Они никуда не делись — отмонтируйте ФС и увидите.
  • Прописывать в fstab /dev/sdX вместо UUID. При добавлении диска буквы перетасуются, и не туда смонтируется не то.
  • Расхождение df и du. Если df показывает заполнение, а du — нет, ищите удалённый, но открытый файл: sudo lsof | grep deleted. Перезапуск процесса освободит место.

Итоги

  • Диски и разделы — это файлы в /dev; карту даёт lsblk, типы ФС и UUID — blkid.
  • mount/umount подключают и отключают ФС; «target is busy» лечится поиском процесса через lsof/fuser.
  • /etc/fstab монтирует разделы на старте; правьте по UUID, проверяйте через mount -a и findmnt --verify, спасайтесь опцией nofail.
  • df -h отвечает «сколько свободно на ФС», du -sh — «сколько занимает каталог»; их расхождение часто означает открытый удалённый файл.
Проверьте себя
1. Почему в /etc/fstab разделы рекомендуют указывать по UUID, а не по /dev/sdb1?
AUUID занимает меньше места в файле конфигурации
BИмена /dev/sdX могут поменяться местами между загрузками, а UUID привязан к самой файловой системе и не меняется
Cmount не умеет работать с путями /dev напрямую
DUUID шифрует раздел и защищает данные
2. df -h показывает, что корневой раздел заполнен, но du по тому же разделу насчитывает заметно меньше. Какая причина наиболее вероятна?
AФайл fstab повреждён
BЗакончились inode, а не байты
CКакой-то процесс держит открытым уже удалённый большой файл — место не освобождено
Ddu всегда занижает размер вдвое