Исправляем последствия неправильно разбитой файловой системы в Linux Debian (Часть первая — уменьшаем размер root)

в 12:44, , рубрики: Debian, filesystem, hdd, linux, метки: , ,

Какие могут быть причины для раздела диска на уже работающей машине?
Доставшиеся в наследство сервера, желание переосмыслить жизнь или просто хорошо провести вечер.

У меня причины было две:
1. На арендованных виртуальных серверах выделен всего один раздел под файловую систему (нет даже swap).
2. Хорошо провести вечер и ещё немножечко получить практических знаний о том, что ещё такого позволяет сделать Linux практически стандартными средствами.

Итак, план действий такой:
1. Уменьшить размер корневого раздела до фактически занимаемого места (часть 1);
2. Установить LVM и создать необходимые разделы (часть 2);
3. Разнести бывший корень по новым разделам (часть 3).

В моей ситуации сложности добавляет относительно малый объём виртуального жесткого диска: всего 15GB.
Все испытания проводил со специально созданной для этого виртуальной машины, но описанные действия успешно проведены на арендованных серверах с минимальным простоем.

Начинаем с уменьшения размера корневого раздела.

Для этих целей нам понадобится установочный диск Debian Squeeze.
Весь текст первой части, по сути, вольный перевод How To Resize ext3 Partitions Without Losing Data + грабли на которые я наступил.

Для начала немного статистики:

> df -h
Файловая система      Разм  Исп  Дост  Исп% смонтирована на
/dev/sda1              16G  967M   14G   7% /
tmpfs                 502M     0  502M   0% /lib/init/rw
udev                  497M  156K  497M   1% /dev
tmpfs                 502M     0  502M   0% /dev/shm

Я взял приближенный к реальности размер жесткого диска и накатил туда Debian Squeeze в режиме автоматической установки (и автоматической разметки жесткого диска). Что получилось в результате — видно выше.

Ещё немного статистики (советую и вам снять все эти показатели, а также бэкапы перед началом манипуляций с ФС):

> df -B 4k
Файловая система     4K-блоков      Исп  Доступно  Исп% смонтирована на
/dev/sda1              3947756    247517   3499702   7% /
tmpfs                   128368         0    128368   0% /lib/init/rw
udev                    127157        39    127118   1% /dev
tmpfs                   128368         0    128368   0% /dev/shm
> sudo fdisk -l
[sudo] password for sabo: 
Disk /dev/sda: 17.2 GB, 17179869184 bytes
255 heads, 63 sectors/track, 2088 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00049f1f
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1        1998    16043008   83  Linux
/dev/sda2            1998        2089      731137    5  Extended
/dev/sda5            1998        2089      731136   82  Linux swap / Solaris
> sudo fdisk -s /dev/sda1
16043008

На этом со статистикой закончим.

Загрузимся с установочного диска Debian в режиме Rescue mode.
На предложения выбора устройства, используемого в качестве корневой файловой системы, нам нужно ответить «Не использовать корневую файловую систему» и запустить оболочку в среде программы установки.

Блочим ФС:

~ # e2fsck -n /dev/sda1
e2fsck 1.41.12 (17-May-2010)
/dev/sda1: clean, 42194/1003680 files, 310509/4010752 blocks

Т.к. у меня установлена ФС ext3, необходимо удалить журнал для преобразования в ext2 (иначе resize2fs, о котором речь пойдет дальше, не сможет изменить размер ФС).

~ # tune2fs -O ^has_journal /dev/sda1
tune2fs 1.41.12 (17-May-2010)

Обратите внимание: в качестве параметра используется заглавная латинская буква O.

Проверим раздел:

~ # e2fsck -f /dev/sda1
e2fsck 1.41.12 (17-May-2010)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sda1: 42194/1003680 files (0.9% non-contiguous), 277708/4010752 blocks

Теперь настало изменить размер файловой системы. У меня на диске в данном случае занято 967MB. Это значит, что я вполне могу оставить ФС размером в 2000MB.

~ # resize2fs /dev/sda1 2000M
resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/sda1 to 512000 (<b>4k</b>) blocks.
The filesystem on /dev/sda1 is now <b>512000</b> blocks long.

Данные, которые я выделил (512000 и 4k), запишите куда-нибудь на листочек, а лучше в виде татуировки на руке — они нам понадобятся при следующих расчётах.

Запускаем fdisk для… удаления раздела. Все правильно, именно удаления — ваши данные, по идее, никуда не денутся. Так как мы удаляем раздел, fdisk работает с жестким диском (обратите внимание на аргумент /dev/sda).

~ # fdisk /dev/sda
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').
Command (m for help):

Тут есть важный момент. Если fdisk выдаёт вам предупреждение «DOS-compatible mode is deprecated», лучше к нему прислушаться, иначе вновь созданный раздел не будет работать (в примере я переключаюсь в режим просмотра секторов, соответственно, если такого предупреждение вы у себя не увидели, то и переключать ничего не надо).

~ # fdisk /dev/sda
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').
Command (m for help): c
DOS Compatibility flag is not set
Command (m for help): u
Changing display/entry units to sectors
Command (m for help): p
Disk /dev/sda: 17.2 GB, 17179869184 bytes
255 heads, 63 sectors/track, 2088 cylinders, total 33554432 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00049f1f
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048    32088063    16043008   83  Linux
/dev/sda2        32090110    33552383      731137    5  Extended
/dev/sda5        32090112    33552383      731136   82  Linux swap / Solaris
Command (m for help):

После этого, удаляем раздел sda1:

Command (m for help): d
Partition number (1-5): 1
Command (m for help): p
Disk /dev/sda: 17.2 GB, 17179869184 bytes
255 heads, 63 sectors/track, 2088 cylinders, total 33554432 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00049f1f
   Device Boot      Start         End      Blocks   Id  System
/dev/sda2        32090110    33552383      731137    5  Extended
/dev/sda5        32090112    33552383      731136   82  Linux swap / Solaris

А теперь создадим новый раздел, но уже меньшего размера:

Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
p
Partition number (1-4): 1
First sector (2048-33554431, default 2048): 2048
Last sector, +sectors or +size{K,M,G} (2048-32090109, default 32090109): +2109440K

Первый сектор оставляем по умолчанию, а вот последний высчитываем по хитрой формуле:

resize2fs output (512000) умножаем на размер блока (4k) и зачем-то (я однозначного ответа дать не могу) добавляем от 3% до 5%. Я добавил три, итого:

> echo '512000 * 4 * 1.03' | bc -l
2109440.00

Наш корневой раздел был загрузочным (за неимением другого), поэтому новый раздел тоже создаем загрузочным и смотрим, что получилось:

Command (m for help): a
Partition number (1-5): 1
Command (m for help): p
Disk /dev/sda: 17.2 GB, 17179869184 bytes
255 heads, 63 sectors/track, 2088 cylinders, total 33554432 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00049f1f
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     4220927     2109440   83  Linux
/dev/sda2        32090110    33552383      731137    5  Extended
/dev/sda5        32090112    33552383      731136   82  Linux swap / Solaris

Красота!

Сохраняем изменения:

Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.

Перезагружаем компьютер и снова загружаемся с установочного диска и входим в режим восстановления.

Блочим ФС:

~ # e2fsck -n /dev/sda1
e2fsck 1.41.12 (17-May-2010)
/dev/sda1: clean, 42194/130560 files, 219000/512000 blocks

Заново создаем журнал:

~ # tune2fs -j /dev/sda1
tune2fs 1.41.12 (17-May-2010)
Creating journal inode: done
This filesystem will be automatically checked every 30 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Все готово!
Перезагружаемся и выбираем загрузку уже с жёсткого диска.

Смотрим на результат трудов:

> df -h
Файловая система      Разм  Исп  Дост  Исп% смонтирована на
/dev/sda1             2,0G  856M 1013M  46% /
tmpfs                 502M     0  502M   0% /lib/init/rw
udev                  497M  156K  497M   1% /dev
tmpfs                 502M     0  502M   0% /dev/shm
> df
Файловая система     1K-блоков      Исп  Доступно  Исп% смонтирована на
/dev/sda1              2015184    876140   1036648  46% /
tmpfs                   513472         0    513472   0% /lib/init/rw
udev                    508628       156    508472   1% /dev
tmpfs                   513472         0    513472   0% /dev/shm

> df -B 4k
Файловая система     4K-блоков      Исп  Доступно  Исп% смонтирована на
/dev/sda1               503796    219035    259162  46% /
tmpfs                   128368         0    128368   0% /lib/init/rw
udev                    127157        39    127118   1% /dev
tmpfs                   128368         0    128368   0% /dev/shm
> sudo fdisk -lc
Disk /dev/sda: 17.2 GB, 17179869184 bytes
255 heads, 63 sectors/track, 2088 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00049f1f
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1         263     2109440   83  Linux
/dev/sda2            1998        2089      731137    5  Extended

/dev/sda5 1998 2089 731136 82 Linux swap / Solaris

> sudo fdisk -s /dev/sda1
2109440

Если у вас получилось, я очень рад. Теперь можно создавать новые разделы. Если нет — попытайтесь разобраться в чём причина :)

П.С. Создаем раздел для теста:

> sudo fdisk /dev/sda
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').
Command (m for help): c
DOS Compatibility flag is not set
Command (m for help): u
Changing display/entry units to sectors
Command (m for help): p
Disk /dev/sda: 17.2 GB, 17179869184 bytes
255 heads, 63 sectors/track, 2088 cylinders, total 33554432 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00049f1f
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     4220927     2109440   83  Linux
/dev/sda2        32090110    33552383      731137    5  Extended
/dev/sda5        32090112    33552383      731136   82  Linux swap / Solaris
Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
p
Partition number (1-4): 3
First sector (4220928-33554431, default 4220928): 
Using default value 4220928
Last sector, +sectors or +size{K,M,G} (4220928-32090109, default 32090109): 
Using default value 32090109
Command (m for help): p
Disk /dev/sda: 17.2 GB, 17179869184 bytes
255 heads, 63 sectors/track, 2088 cylinders, total 33554432 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00049f1f
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     4220927     2109440   83  Linux
/dev/sda2        32090110    33552383      731137    5  Extended
/dev/sda3         4220928    32090109    13934591   83  Linux
/dev/sda5        32090112    33552383      731136   82  Linux swap / Solaris
Partition table entries are not in disk order
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Устройство или ресурс занято.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

Перезагружаемся.

Форматируем sda3 в ext4:

> sudo mkfs.ext4 /dev/sda3
[sudo] password for sabo: 
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
871408 inodes, 3483647 blocks
174182 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=3569352704
107 block groups
32768 blocks per group, 32768 fragments per group
8144 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 32 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Монтируем:

> sudo mount /dev/sda3 /mnt

Результат:

> df -h
Файловая система      Разм  Исп  Дост  Исп% смонтирована на
/dev/sda1             2,0G  856M 1013M  46% /
tmpfs                 502M     0  502M   0% /lib/init/rw
udev                  497M  160K  497M   1% /dev
tmpfs                 502M     0  502M   0% /dev/shm
/dev/sda3              14G  162M   13G   2% /mnt

P.S. Если эта тема интересна посетителям хабра, у меня уже написаны две вторые части.
Статью решил разделить на три независимые части для удобства обсуждения.

Автор: devpreview

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js