Как вынести данные с root FS без копирования сотен гигабайт

от автора

Привет, Хабр!

На связи команда инженеров сервисного центра с очередной нетривиальной задачей, которую мы решали у одного нашего крупного заказчика.

Многие Linux-серверы со временем сталкиваются с одной и той же проблемой: корневая файловая система постепенно «обрастает» данными приложений, снэпшоты виртуальных машин становятся слишком большими, резервное копирование занимает всё больше времени, а свободного места для классической миграции уже не остаётся. Особенно часто это встречается на старых системах, где изначальная разметка дисков создавалась без понимания того, какое прикладное программное обеспечение будет использоваться в будущем.

Так возникает необходимость вынести данные приложения на отдельную файловую систему, но традиционный подход требует полного копирования больших объёмов данных и длительного простоя сервисов. В этой статье мы покажем способ изменить разметку уже работающей Linux-системы без переустановки ОС и без копирования сотен гигабайт данных.

В Linux считается хорошей практикой размещать файловые системы (ФС) для прикладного программного обеспечения (ППО) на отдельных от ФС операционной системы (ОС). Например, если ППО располагается в директории /opt/example/, то ФС размещаем на отдельный диск. У этого подхода есть следующие преимущества:

1)      Если из-за сбоя ППО начнет занимать слишком много места, файловая система может переполниться. В такой ситуации, скорее всего, «зависнет» только само ППО, тогда как операционная система продолжит работать в штатном режиме. Это позволит системному администратору подключиться к системе обычным способом (например, через Secure Shell — SSH) и устранить проблему без загрузки в аварийном режиме для очистки диска.

2)      Если сервер работает в виде виртуальной машины (ВМ), удобно выносить файловую систему ППО на отдельный диск. В этом случае в снэпшот ВМ можно включать только диск с ОС, исключая диск с ППО. Это уменьшает размер этого снэпшота и ускоряет работу с ним. Такой подход особенно полезен при изменениях конфигурации ОС, когда данные ППО не требуют резервного копирования. Кроме того, это может быть важно для некоторых СРК.

Однако есть и нюансы. Человек, ответственный за разворачивание ОС, должен знать, какое именно ППО там будет стоять и в каких именно директориях оно будет хранить файлы. Помним: что-то хранится в /var/www/, что-то — в /home/something/ или в /u01/ и так далее.

Но зачастую у этого человека нет этой информации. Перед ним просто ставят задачу: «Сделай сервер Linux с диском в 200 гигабайт» или что-то в этом роде. При таких вводных простейший выход — сделать один диск и всего одну ФС — корневую, /. Но такой подход имеет недостатки, которые являются зеркальным отражением его плюсов. Возникают ситуации, когда нужно переделывать разметку ФС на уже существующих серверах. Решение «в лоб» — присоединить еще один диск и вынести данные на ФС /opt/example/, например.  

Итак, дано: весь диск 200 гигабайт, а размер данных в /opt/example/ — 180 гигабайт. Нам понадобится еще один 200-гигабайтный диск для того, чтобы скопировать данные, и после переноса на / останется много свободного места. Разумеется, копирование 180 гигабайт даже на быстрых дисках не происходит мгновенно. Такой процесс придется проводить с полной остановкой работы ППО, чтобы копии получились правильными и без искажений.

Мы написали этот текст, чтобы упростить вашу жизнь в похожей ситуации.

Термины:

BIOS, basic input-output system, Базовая система ввода-вывода

UEFI, Unified Extensible Firmware Interface, Единый расширяемый интерфейс программного обеспечения,

LVM Менеджер логических томов, logical volume manager

GRUB Великий объединенный загрузчик, GRand Unified Bootloader

Теперь приступим

Итак, у нас есть стандартный Debian 13 со стандартной разметкой из одного диска, установленный в BIOS-режиме и с тестовым пользователем в /opt/example/. В нашем случае эта директория почти ничего не весит, но мы будем проводить работы так, как будто она весит много гигабайт:

Скрытый текст
root@debian:~# lsblkNAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTSsda      8:0    0   32G  0 disk├─sda1   8:1    0 30,3G  0 part /├─sda2   8:2    0    1K  0 part└─sda5   8:5    0  1,7G  0 part [SWAP]sr0     11:0    1 1024M  0 romroot@debian:~# fdisk -l /dev/sdaDisk /dev/sda: 32 GiB, 34359738368 bytes, 67108864 sectorsDisk model: VBOX HARDDISKUnits: sectors of 1 * 512 = 512 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisklabel type: dosDisk identifier: 0xa08b7ba1Device     Boot    Start      End  Sectors  Size Id Type/dev/sda1  *        2048 63578111 63576064 30,3G 83 Linux/dev/sda2       63580158 67106815  3526658  1,7G  f W95 Ext'd (LBA)/dev/sda5       63580160 67106815  3526656  1,7G 82 Linux swap / Solarisroot@debian:~# df -hT /Файловая система Тип  Размер Использовано  Дост Использовано% Cмонтировано в/dev/sda1        ext4    30G         1,2G   27G            5% /root@debian:~# ls -laR /opt//opt/:итого 12drwxr-xr-x  3 root    root    4096 апр  6 18:26 .drwxr-xr-x 18 root    root    4096 апр  6 16:25 ..drwx------  2 example example 4096 апр  6 18:27 example/opt/example:итого 24drwx------ 2 example example 4096 апр  6 18:27 .drwxr-xr-x 3 root    root    4096 апр  6 18:26 ..-rw------- 1 example example   19 апр  6 18:27 .bash_history-rw-r--r-- 1 example example  220 мар  8 18:21 .bash_logout-rw-r--r-- 1 example example 3526 мар  8 18:21 .bashrc-rw-rw-r-- 1 example example    0 апр  6 18:27 file1-rw-r--r-- 1 example example  807 мар  8 18:21 .profileroot@debian:~#

Для примера добавим диск в 20 гигабайт и проведем его разметку так, как нам необходимо. При этом поставим пакет lvm2, чтобы задействовать LVM на этом диске:

Скрытый текст
root@debian:~# lsblkNAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTSsda      8:0    0   32G  0 disk├─sda1   8:1    0 30,3G  0 part /├─sda2   8:2    0    1K  0 part└─sda5   8:5    0  1,7G  0 part [SWAP]sdb      8:16   0   20G  0 disksr0     11:0    1 1024M  0 romroot@debian:~# fdisk /dev/sdbWelcome to fdisk (util-linux 2.41).Changes will remain in memory only, until you decide to write them.Be careful before using the write command.Device does not contain a recognized partition table.Created a new DOS (MBR) disklabel with disk identifier 0x0131a0fb.Command (m for help): nPartition type   p   primary (0 primary, 0 extended, 4 free)   e   extended (container for logical partitions)Select (default p):Using default response p.Partition number (1-4, default 1):First sector (2048-41943039, default 2048):Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-41943039, default 41943039):Created a new partition 1 of type 'Linux' and of size 20 GiB.Command (m for help): tSelected partition 1Hex code or alias (type L to list all): lvmChanged type of partition 'Linux' to 'Linux LVM'.Command (m for help): wThe partition table has been altered.Calling ioctl() to re-read partition table.Syncing disks.root@debian:~# fdisk -l /dev/sdbDisk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectorsDisk model: VBOX HARDDISKUnits: sectors of 1 * 512 = 512 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisklabel type: dosDisk identifier: 0x0131a0fbDevice     Boot Start      End  Sectors Size Id Type/dev/sdb1        2048 41943039 41940992  20G 8e Linux LVMroot@debian:~# apt install lvm2Установка:  lvm2Установка зависимостей:  dmeventd  libaio1t64  libdevmapper-event1.02.1  liblvm2cmd2.03  thin-provisioning-toolsСводка:  Обновление: 0, Установка: 6, Удаление: 0, Пропуск обновления: 0  Объём загрузки: 3 206 kB  Требуемое пространство: 11,1 MB / 29,0 GB доступноПродолжить? [Д/н] yПол:1 http://ftp.ru.debian.org/debian trixie/main amd64 libdevmapper-event1.02.1 amd64 2:1.02.205-2 [13,6 kB]Пол:2 http://ftp.ru.debian.org/debian trixie/main amd64 libaio1t64 amd64 0.3.113-8+b1 [14,9 kB]Пол:3 http://ftp.ru.debian.org/debian trixie/main amd64 liblvm2cmd2.03 amd64 2.03.31-2 [785 kB]Пол:4 http://ftp.ru.debian.org/debian trixie/main amd64 dmeventd amd64 2:1.02.205-2 [62,4 kB]Пол:5 http://ftp.ru.debian.org/debian trixie/main amd64 lvm2 amd64 2.03.31-2 [1 287 kB]Пол:6 http://ftp.ru.debian.org/debian trixie/main amd64 thin-provisioning-tools amd64 1.1.0-4+b1 [1 042 kB]Получено 3 206 kB за 5с (585 kB/s)Выбор ранее не выбранного пакета libdevmapper-event1.02.1:amd64.(Чтение базы данных … на данный момент установлено 36605 файлов и каталогов.)Подготовка к распаковке …/0-libdevmapper-event1.02.1_2%3a1.02.205-2_amd64.deb …Распаковывается libdevmapper-event1.02.1:amd64 (2:1.02.205-2) …Выбор ранее не выбранного пакета libaio1t64:amd64.Подготовка к распаковке …/1-libaio1t64_0.3.113-8+b1_amd64.deb …Распаковывается libaio1t64:amd64 (0.3.113-8+b1) …Выбор ранее не выбранного пакета liblvm2cmd2.03:amd64.Подготовка к распаковке …/2-liblvm2cmd2.03_2.03.31-2_amd64.deb …Распаковывается liblvm2cmd2.03:amd64 (2.03.31-2) …Выбор ранее не выбранного пакета dmeventd.Подготовка к распаковке …/3-dmeventd_2%3a1.02.205-2_amd64.deb …Распаковывается dmeventd (2:1.02.205-2) …Выбор ранее не выбранного пакета lvm2.Подготовка к распаковке …/4-lvm2_2.03.31-2_amd64.deb …Распаковывается lvm2 (2.03.31-2) …Выбор ранее не выбранного пакета thin-provisioning-tools.Подготовка к распаковке …/5-thin-provisioning-tools_1.1.0-4+b1_amd64.deb …Распаковывается thin-provisioning-tools (1.1.0-4+b1) …Настраивается пакет libdevmapper-event1.02.1:amd64 (2:1.02.205-2) …Настраивается пакет thin-provisioning-tools (1.1.0-4+b1) …Настраивается пакет libaio1t64:amd64 (0.3.113-8+b1) …Настраивается пакет liblvm2cmd2.03:amd64 (2.03.31-2) …Настраивается пакет dmeventd (2:1.02.205-2) …Created symlink '/etc/systemd/system/sockets.target.wants/dm-event.socket' → '/usr/lib/systemd/system/dm-event.socket'.dm-event.service is a disabled or a static unit, not starting it.Настраивается пакет lvm2 (2.03.31-2) …Created symlink '/etc/systemd/system/sysinit.target.wants/blk-availability.service' → '/usr/lib/systemd/system/blk-availability.service'.Created symlink '/etc/systemd/system/sysinit.target.wants/lvm2-monitor.service' → '/usr/lib/systemd/system/lvm2-monitor.service'.Created symlink '/etc/systemd/system/sysinit.target.wants/lvm2-lvmpolld.socket' → '/usr/lib/systemd/system/lvm2-lvmpolld.socket'.Обрабатываются триггеры для initramfs-tools (0.148.3) …update-initramfs: Generating /boot/initrd.img-6.12.74+deb13+1-amd64Обрабатываются триггеры для libc-bin (2.41-12+deb13u2) …Обрабатываются триггеры для man-db (2.13.1-1) …root@debian:~# pvcreate /dev/sdb1  Physical volume "/dev/sdb1" successfully created.root@debian:~# vgcreate vg_root /dev/sdb1  Volume group "vg_root" successfully createdroot@debian:~# lvcreate -L4g vg_root -n lv_swap  Logical volume "lv_swap" created.root@debian:~# lvcreate -l100%FREE vg_root -n lv_root  Logical volume "lv_root" created.root@debian:~# mkswap /dev/mapper/vg_root-lv_swapSetting up swapspace version 1, size = 4 GiB (4294963200 bytes)no label, UUID=1c40ccc2-e5e2-4d05-9b07-172f94cb2c7froot@debian:~# mkfs.ext4 /dev/mapper/vg_root-lv_rootmke2fs 1.47.2 (1-Jan-2025)Creating filesystem with 4193280 4k blocks and 1048576 inodesFilesystem UUID: e086d44c-cfb9-4b0d-beac-1621256af630Superblock backups stored on blocks:        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,        4096000Allocating group tables: doneWriting inode tables: doneCreating journal (16384 blocks): doneWriting superblocks and filesystem accounting information: doneroot@debian:~# lsblkNAME                MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTSsda                   8:0    0   32G  0 disk├─sda1                8:1    0 30,3G  0 part /├─sda2                8:2    0    1K  0 part└─sda5                8:5    0  1,7G  0 part [SWAP]sdb                   8:16   0   20G  0 disk└─sdb1                8:17   0   20G  0 part  ├─vg_root-lv_swap 254:0    0    4G  0 lvm  └─vg_root-lv_root 254:1    0   16G  0 lvmsr0                  11:0    1 1024M  0 romroot@debian:~#

Если бы мы хотели использовать вместо стандартной ФС ext4 другую, XFS, то пришлось бы  ставить пакет xfsprogs.  Обратите внимание: в примере выше мы не создали отдельного /boot/ — потому что GRUB 2 в Debian умеет загружаться напрямую с LVM, но в CentOS, например, потребовался бы отдельный раздел под /boot/, так как там GRUB 2 так не может. Поэтому для простоты демонстрации создаем два логических тома: один под корень (/), другой под раздел подкачки (swap).

Теперь необходимо загрузиться с образа «живой» системы. В нашем случае это тоже Debian 13, но подойдет любой дистрибутив, который умеет работать с LVM и в котором есть программа удаленной синхронизации rsync (мы используем ее локально). После переносим системные файлы. Кстати, перед загрузкой с образа «живой» системы мы изменили нумерацию дисков: /dev/sdb стал /dev/sda и наоборот. Теперь прежний /dev/sdb станет системным диском и будет логично, что он первый:

Скрытый текст
root@debian:~# lsblkNAME                MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTSloop0                 7:0    0  2.8G  1 loop /run/live/rootfs/filesystem.squashfssda                   8:0    0   20G  0 disk└─sda1                8:1    0   20G  0 part  ├─vg_root-lv_swap 254:0    0    4G  0 lvm  └─vg_root-lv_root 254:1    0   16G  0 lvmsdb                   8:16   0   32G  0 disk├─sdb1                8:17   0 30.3G  0 part├─sdb2                8:18   0    1K  0 part└─sdb5                8:21   0  1.7G  0 partsr0                  11:0    1  3.5G  0 rom  /run/live/mediumroot@debian:~# parted /dev/sdbGNU Parted 3.6Using /dev/sdbWelcome to GNU Parted! Type 'help' to view a list of commands.(parted) rm 5(parted) rm 2(parted) resizepart 1 100%(parted) quitInformation: You may need to update /etc/fstab.root@debian:~# e2fsck -f /dev/sdb1e2fsck 1.47.2 (1-Jan-2025)Pass 1: Checking inodes, blocks, and sizesPass 2: Checking directory structurePass 3: Checking directory connectivityPass 4: Checking reference countsPass 5: Checking group summary information/dev/sdb1: 41248/1986768 files (0.1% non-contiguous), 477393/7947008 blocksroot@debian:~# resize2fs /dev/sdb1resize2fs 1.47.2 (1-Jan-2025)Resizing the filesystem on /dev/sdb1 to 8388352 (4k) blocks.The filesystem on /dev/sdb1 is now 8388352 (4k) blocks long.root@debian:~# ls /mntroot@debian:~# mkdir /mnt/1 /mnt/2root@debian:~# mount /dev/sdb1 /mnt/1root@debian:~# mount /dev/mapper/vg_root-lv_root /mnt/2root@debian:~# swapon /dev/mapper/vg_root-lv_swaproot@debian:~# lsblkNAME                MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTSloop0                 7:0    0  2.8G  1 loop /run/live/rootfs/filesystem.squashfssda                   8:0    0   20G  0 disk└─sda1                8:1    0   20G  0 part  ├─vg_root-lv_swap 254:0    0    4G  0 lvm  [SWAP]  └─vg_root-lv_root 254:1    0   16G  0 lvm  /mnt/2sdb                   8:16   0   32G  0 disk└─sdb1                8:17   0   32G  0 part /mnt/1sr0                  11:0    1  3.5G  0 rom  /run/live/mediumroot@debian:~# ls /mnt/1bin   dev  home        initrd.img.old  lib64       media  opt   root  sbin  sys  usr  vmlinuzboot  etc  initrd.img  lib             lost+found  mnt    proc  run   srv   tmp  var  vmlinuz.oldroot@debian:~# ls /mnt/2lost+foundroot@debian:~# rsync -aAHXS --exclude 'opt/example/*' /mnt/1/* /mnt/2/root@debian:~# ls /mnt/2/bin   dev  home        initrd.img.old  lib64       media  opt   root  sbin  sys  usr  vmlinuzboot  etc  initrd.img  lib             lost+found  mnt    proc  run   srv   tmp  var  vmlinuz.oldroot@debian:~# ls /mnt/2/opt/exampleroot@debian:~# ls -a /mnt/2/opt/example/.  ..root@debian:~#

В примере выше мы провели несколько операций:

  1. На диске /dev/sdb (бывший /dev/sda) удалили старый раздел подкачки, а бывший корень расширили на все свободное место.

  2. Создали директории /mnt/1/ и /mnt/2/

  3. Бывший корень смонтировали в /mnt/1/

  4. Новый корень, пока пустой, смонтировали в /mnt/2/

  5. Все файлы старого корня, кроме содержимого директории /opt/example/, скопировали в новый корень.

Теперь продолжим:

root@debian:~# cd /mnt/1root@debian:/mnt/1# lsbin   dev  home        initrd.img.old  lib64       media  opt   root  sbin  sys  usr  vmlinuzboot  etc  initrd.img  lib             lost+found  mnt    proc  run   srv   tmp  var  vmlinuz.oldroot@debian:/mnt/1# ls | grep -e opt -e lostlost+foundoptroot@debian:/mnt/1# for i in $(ls | grep -v -e opt -e lost); do rm -rf $i; doneroot@debian:/mnt/1# lslost+found  optroot@debian:/mnt/1# mv -f opt/example/{.,}* .root@debian:/mnt/1# ls -a.  ..  .bash_history  .bash_logout  .bashrc  file1  lost+found  opt  .profileroot@debian:/mnt/1# rm -rf opt/root@debian:/mnt/1# ls -latotal 36drwxr-xr-x 3 root root  4096 Apr  6 17:02 .drwxr-xr-x 1 root root    80 Apr  6 16:59 ..-rw------- 1 1001 1001    19 Apr  6 15:27 .bash_history-rw-r--r-- 1 1001 1001   220 Mar  8 15:21 .bash_logout-rw-r--r-- 1 1001 1001  3526 Mar  8 15:21 .bashrc-rw-rw-r-- 1 1001 1001     0 Apr  6 15:27 file1drwx------ 2 root root 16384 Apr  6 13:19 lost+found-rw-r--r-- 1 1001 1001   807 Mar  8 15:21 .profileroot@debian:/mnt/1#

Мы сделали из бывшего корня директорию /opt/example/. При этом файлы директории никуда не уходили с ФС, а только меняли свое расположение на ней.

Осталось поправить таблицу разделов и переставить GRUB 2 для BIOS, чтобы ОС могла загрузиться с новой разметкой:

Скрытый текст
root@debian:/mnt/1# cdroot@debian:~# umount /mnt/1root@debian:~# lsblkNAME                MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTSloop0                 7:0    0  2.8G  1 loop /run/live/rootfs/filesystem.squashfssda                   8:0    0   20G  0 disk└─sda1                8:1    0   20G  0 part  ├─vg_root-lv_swap 254:0    0    4G  0 lvm  [SWAP]  └─vg_root-lv_root 254:1    0   16G  0 lvm  /mnt/2sdb                   8:16   0   32G  0 disk└─sdb1                8:17   0   32G  0 partsr0                  11:0    1  3.5G  0 rom  /run/live/mediumroot@debian:~# dd if=/dev/sdb of=/mnt/2/root/mbrbackup bs=446 count=11+0 records in1+0 records out446 bytes copied, 0.00131297 s, 340 kB/sroot@debian:~# dd if=/dev/zero of=/dev/sdb bs=446 count=11+0 records in1+0 records out446 bytes copied, 0.00817176 s, 54.6 kB/sroot@debian:~# mount /dev/sdb1 /mnt/2/opt/example/root@debian:~# lsblkNAME                MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTSloop0                 7:0    0  2.8G  1 loop /run/live/rootfs/filesystem.squashfssda                   8:0    0   20G  0 disk└─sda1                8:1    0   20G  0 part  ├─vg_root-lv_swap 254:0    0    4G  0 lvm  [SWAP]  └─vg_root-lv_root 254:1    0   16G  0 lvm  /mnt/2sdb                   8:16   0   32G  0 disk└─sdb1                8:17   0   32G  0 part /mnt/2/opt/examplesr0                  11:0    1  3.5G  0 rom  /run/live/mediumroot@debian:~# ls -ld /mnt/2/opt/example/drwxr-xr-x 3 root root 4096 Apr  6 17:02 /mnt/2/opt/example/root@debian:~# chown 1001:1001 /mnt/2/opt/example/root@debian:~# chmod 700 /mnt/2/opt/example/root@debian:~# ls -ld /mnt/2/opt/example/drwx------ 3 1001 1001 4096 Apr  6 17:02 /mnt/2/opt/example/root@debian:~# cp /mnt/2/etc/fstab /mnt/2/etc/fstab_backuproot@debian:~# grep -v -e "^#" -e "^$" /mnt/2/etc/fstabUUID=2764cb53-516c-46f7-a498-cbdb80a31dea /               ext4    errors=remount-ro 0       1UUID=d889b89e-035a-4556-89de-9092084ac37b none            swap    sw              0       0/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0root@debian:~# nano /mnt/2/etc/fstabroot@debian:~# grep -v -e "^#" -e "^$" /mnt/2/etc/fstab/dev/mapper/vg_root-lv_root /               ext4    errors=remount-ro 0       1UUID=2764cb53-516c-46f7-a498-cbdb80a31dea /opt/example               ext4    defaults 0       2/dev/mapper/vg_root-lv_swap none            swap    sw              0       0/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0root@debian:~# cat /mnt/2/etc/initramfs-tools/conf.d/resumeRESUME=UUID=d889b89e-035a-4556-89de-9092084ac37broot@debian:~# nano /mnt/2/etc/initramfs-tools/conf.d/resumeroot@debian:~# cat /mnt/2/etc/initramfs-tools/conf.d/resumeRESUME=/dev/mapper/vg_root-lv_swaproot@debian:~# mount --bind /dev /mnt/2/devroot@debian:~# mount --bind /proc /mnt/2/procroot@debian:~# mount --bind /sys  /mnt/2/sysroot@debian:~# chroot /mnt/2root@debian:/# grub-install /dev/sdaInstalling for i386-pc platform.Installation finished. No error reported.root@debian:/# update-initramfs -u -k allperl: warning: Setting locale failed.perl: warning: Please check that your locale settings:        LANGUAGE = (unset),        LC_ALL = (unset),        LC_CTYPE = (unset),        LC_NUMERIC = (unset),        LC_COLLATE = (unset),        LC_TIME = (unset),        LC_MESSAGES = (unset),        LC_MONETARY = (unset),        LC_ADDRESS = (unset),        LC_IDENTIFICATION = (unset),        LC_MEASUREMENT = (unset),        LC_PAPER = (unset),        LC_TELEPHONE = (unset),        LC_NAME = (unset),        LANG = "en_US.UTF-8"    are supported and installed on your system.perl: warning: Falling back to the standard locale ("C").perl: warning: Setting locale failed.perl: warning: Please check that your locale settings:        LANGUAGE = (unset),        LC_ALL = (unset),        LC_CTYPE = (unset),        LC_NUMERIC = (unset),        LC_COLLATE = (unset),        LC_TIME = (unset),        LC_MESSAGES = (unset),        LC_MONETARY = (unset),        LC_ADDRESS = (unset),        LC_IDENTIFICATION = (unset),        LC_MEASUREMENT = (unset),        LC_PAPER = (unset),        LC_TELEPHONE = (unset),        LC_NAME = (unset),        LANG = "en_US.UTF-8"    are supported and installed on your system.perl: warning: Falling back to the standard locale ("C").update-initramfs: Generating /boot/initrd.img-6.12.74+deb13+1-amd64update-initramfs: Generating /boot/initrd.img-6.12.73+deb13-amd64root@debian:/# update-grubGenerating grub configuration file ...Found linux image: /boot/vmlinuz-6.12.74+deb13+1-amd64Found initrd image: /boot/initrd.img-6.12.74+deb13+1-amd64Found linux image: /boot/vmlinuz-6.12.73+deb13-amd64Found initrd image: /boot/initrd.img-6.12.73+deb13-amd64Warning: os-prober will not be executed to detect other bootable partitions.Systems on them will not be added to the GRUB boot configuration.Check GRUB_DISABLE_OS_PROBER documentation entry.Adding boot menu entry for UEFI Firmware Settings ...doneroot@debian:/#

С помощью этой команды мы:

  1. Затерли нулями старую главную загрузочную запись (master boot record, MBR) на прежнем системном диске /dev/sdb, первые 446 байт. Благодаря этому ВМ не сможет случайно загружаться с уже нерабочим старым GRUB.

  2. Смонтировали ФС /opt/example/ на новое место в будущем chroot. В принципе, неважно, но на всякий случай.

  3. Скорректировали файл /etc/fstab в соответствии с тем, как сейчас будут располагаться ФС.

  4. Поправили файл /etc/initramfs-tools/conf.d/resume, чтобы ОС искала раздел подкачки при загрузке в новом месте.

  5. Собрали chroot и вход в него.

  6. Изнутри chroot установили GRUB 2 на /dev/sda, обновили временную файловую систему, используемую ядром Linux при начальной загрузке (initramfs), чтобы ОС искала раздел подкачки при загрузке в новом месте, обновили конфигурацию GRUB 2.

Теперь выходим из всего этого и загружаемся уже в новую ОС:

root@debian:/# exitexitroot@debian:~# poweroff

Как видно после загрузки, миграция / на иной диск прошла успешно:

root@debian:~# lsblkNAME                MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTSsda                   8:0    0   20G  0 disk└─sda1                8:1    0   20G  0 part  ├─vg_root-lv_swap 254:0    0    4G  0 lvm  [SWAP]  └─vg_root-lv_root 254:1    0   16G  0 lvm  /sdb                   8:16   0   32G  0 disk└─sdb1                8:17   0   32G  0 part /opt/examplesr0                  11:0    1 1024M  0 romroot@debian:~# ls -ld /opt/example/drwx------ 3 example example 4096 апр  6 20:02 /opt/example/root@debian:~# ls -la /opt/example/итого 40drwx------ 3 example example  4096 апр  6 20:02 .drwxr-xr-x 3 root    root     4096 апр  6 18:26 ..-rw------- 1 example example    19 апр  6 18:27 .bash_history-rw-r--r-- 1 example example   220 мар  8 18:21 .bash_logout-rw-r--r-- 1 example example  3526 мар  8 18:21 .bashrc-rw-rw-r-- 1 example example     0 апр  6 18:27 file1drwx------ 2 root    root    16384 апр  6 16:19 lost+found-rw-r--r-- 1 example example   807 мар  8 18:21 .profileroot@debian:~# ls /bin   dev  home        initrd.img.old  lib64       media  opt   root  sbin  sys  usr  vmlinuzboot  etc  initrd.img  lib             lost+found  mnt    proc  run   srv   tmp  var  vmlinuz.oldroot@debian:~#

Что мы можем еще сказать?

Миграции, описанные выше, позволяют исправить неудачную первоначальную разметку Linux-систем без переустановки ОС и без полного копирования больших объёмов данных. В рассмотренном сценарии удалось перенести операционную систему на новый диск, сохранив данные приложения на прежней файловой системе и избежав длительного копирования сотен гигабайт.

Такой подход позволяет существенно сократить время простоя сервисов, уменьшить объём операций ввода-вывода и обойтись без дополнительного дискового пространства, которое потребовалось бы для классической миграции.

При этом основная сложность подобных работ — не сами команды Linux, а аккуратная работа с загрузчиком, initramfs, UUID, LVM и порядком монтирования файловых систем.

Любые ошибки на этих этапах могут привести к неработоспособности системы после перезагрузки, поэтому подобные операции требуют:

• резервных копий;
• предварительного тестирования;
• и чёткого понимания механики загрузки Linux.

Надеюсь, наш текст позволит вам не изобретать космолет заново. Удачи!

ссылка на оригинал статьи https://habr.com/ru/articles/1054718/