XFS clone to a smaller disk

Начали дохнуть диски на сервере 1С. Сегодня поменял SSD диск с операционной системой и столкнулся с некоторыми проблемами. Так, что сегодня рассмотрим, что называется «XFS clone to a smaller disk» или как «клонировать XFS на диск меньшего размера».

Ищем диск и пытаемся клонировать

Поскольку на сервере имеется RAID0+1 массив на BTRFS, то надо сперва найти диск с операционной системой:

$ df -h
Filesystem                 Size  Used Avail Use% Mounted on
/dev/mapper/cl_ethan-root   50G   28G   23G  56% /
devtmpfs                    16G     0   16G   0% /dev
tmpfs                       16G     0   16G   0% /dev/shm
tmpfs                       16G  8.9M   16G   1% /run
tmpfs                       16G     0   16G   0% /sys/fs/cgroup
/dev/sda1                 1014M  324M  691M  32% /boot
/dev/sdb                   466G   65G  401G  14% /opt
/dev/mapper/cl_ethan-home  165G   83G   82G  51% /home
tmpfs                      3.2G     0  3.2G   0% /run/user/1000

Здесь видим, что раздел /dev/sda1 содержит в себе boot, значит диск /dev/sda и есть наш пациент. Теперь надо выяснить в каком слоте находится диск. К сожалению сервер Supermicro и вместо аппаратного RAID используется софтверный так, что LED Blink работать не будет, но можем узнать серийный номер диска и сравнить с серийными номерами дисков в корзинах:

$ lshw -C disk
  *-disk:0
       description: ATA Disk
       product: INTEL SSDSC2KG24
       physical id: 0
       bus info: scsi@0:0.0.0
       logical name: /dev/sda
       version: 0100
       serial: BTYG91240FQ6240AGN
       size: 223GiB (240GB)
       capabilities: partitioned partitioned:dos
       configuration: ansiversion=5 logicalsectorsize=512 sectorsize=4096 signature=b2dd5937
  *-disk:1
       description: ATA Disk
       product: WDC WDS250G1B0A-
       vendor: Western Digital
       physical id: 1
       bus info: scsi@1:0.0.0
       logical name: /dev/sdb
       logical name: /opt
       version: 00WD
       serial: 164520401252
       size: 232GiB (250GB)
       configuration: ansiversion=5 logicalsectorsize=512 mount.fstype=btrfs mount.options=rw,relatime,ssd,space_cache,subvolid=5,subvol=/ sectorsize=512 state=mounted
  *-disk:0
       description: ATA Disk
       product: Samsung SSD 860
       physical id: 0
       bus info: scsi@4:0.0.0
       logical name: /dev/sdc
       version: 2B6Q
       serial: S3Y9NX0M411951B
       size: 232GiB (250GB)
       configuration: ansiversion=5 logicalsectorsize=512 sectorsize=512
  *-disk:1
       description: ATA Disk
       product: WDC WDS250G1B0A-
       vendor: Western Digital
       physical id: 1
       bus info: scsi@5:0.0.0
       logical name: /dev/sdd
       version: 00WD
       serial: 164520401503
       size: 232GiB (250GB)
       configuration: ansiversion=5 logicalsectorsize=512 sectorsize=512
  *-disk:2
       description: ATA Disk
       product: WDC WDS250G1B0A-
       vendor: Western Digital
       physical id: 0.0.0
       bus info: scsi@6:0.0.0
       logical name: /dev/sde
       version: 00WD
       serial: 164520402583
       size: 232GiB (250GB)
       configuration: ansiversion=5 logicalsectorsize=512 sectorsize=512

Здесь мы видим, что disk:0 является блочным устройством /dev/sda и его серийный номер «BTYG91240FQ6240AGN» (на самом деле пост пишется уже после замены диска и проблемным был один из дисков WDC WDS250G1B0A). Зная серийный номер, мы знаем какой диск заменить.

Из-за того, что свободные корзины являются болванками и на них не посадить SSD было решено подключить новый диск через док-станцию. Записываем CloneZilla на флешку и при попытке склонировать disk to disk получаем сообщение о том, что объем нового диска меньше, чем у текущего и отказ в клонировании. Целый день гугления не прошел даром и по крупицам была собрана информация как выйти из данной ситуации. Путь тернистый, но рабочий.

Игры с LVM

Загружаемся с LiveUSB и первым делом надо воссоздать структуру текущего диска на новом. Смотрим, как устроен текущий диск:

$ lsblk
NAME              MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                 8:0    0 223.6G  0 disk
├─sda1              8:1    0     1G  0 part /boot
└─sda2              8:2    0 222.6G  0 part
  ├─cl_ethan-root 253:0    0    50G  0 lvm  /
  ├─cl_ethan-swap 253:1    0     8G  0 lvm  [SWAP]
  └─cl_ethan-home 253:2    0 164.5G  0 lvm  /home
sdb                 8:16   0 232.9G  0 disk /opt
sdc                 8:32   0 232.9G  0 disk
sdd                 8:48   0 232.9G  0 disk
sde                 8:64   0 232.9G  0 disk
sdf                     8:80   1  28.7G  0 disk 
├─sdf1                  8:81   1   1.4G  0 part /run/initramfs/live
├─sdf2                  8:82   1   4.9M  0 part 
└─sdf3                  8:83   1  19.6M  0 part 
loop0                   7:0    0    20K  1 loop 
loop1                   7:1    0   4.3M  1 loop 
└─live-osimg-min      253:5    0     8G  1 dm   
loop2                   7:2    0   1.3G  1 loop 
loop3                   7:3    0     8G  1 loop 
├─live-rw             253:3    0     8G  0 dm   /
├─live-base           253:4    0     8G  1 dm   
└─live-osimg-min      253:5    0     8G  1 dm   
loop4                   7:4    0   512M  0 loop 
└─live-rw             253:3    0     8G  0 dm   /

Разбиваем таким же образом новый диск, который определился как /dev/sdg:

$ fdisk /dev/sdg
n # новый раздел (/boot)
p # primary partition
# default (1st partition)
# default 
+1G # размер /boot
# готово!
n # новый раздел (для LVM)
p # primary partition
# default (2nd partition)
# default 
# default (использовать все доступное пространство)
# готово!
a # установить флаг загрузки
1 # partition 1
p # перепроверяем разделы
w # записываем изменения на диск

После этого диск sdg исчез. Пришлось перезагрузить док-станцию после чего диск появился.

Создаем файловую систему раздела /boot:

$ mkfs.xfs -f /dev/sdg1

Создаем LVM структуру:

# создаем физический том
$ pvcreate /dev/sdg2
# создаем группу
$ vgcreate cl_newethan /dev/sdg2
# создаем логический том для свопа
$ lvcreate -L 8G -n swap cl_newethan
# создаем логический том /root
$ lvcreate -L 50G -n root cl_newethan
# создаем логический том /home и отдаем ей все свободное пространство
$ lvcreate -l 100%FREE -n home cl_newethan

Теперь создаем файловую систему для логических томов:

$ mkfs.xfs /dev/cl_newethan/root
$ mkfs.xfs /dev/cl_newethan/home
$ mkswap -L swap /dev/cl_newethan/swap
$ swapon /dev/cl_newethan/swap

Активация группы:

$ vgchange -a y cl_newethan

Монтируем старые и новые разделы:

$ mkdir -p /mnt/ethan/{boot,root,home}
$ mount /dev/sda1 /mnt/ethan/boot
$ mount /dev/cl_ethan/root /mnt/ethan/root
$ mount /dev/cl_ethan/home /mnt/ethan/home
$ mkdir -p /mnt/newethan/{boot,root,home}
$ mount /dev/sdg1 /mnt/newethan/boot
$ mount /dev/cl_newethan/root /mnt/newethan/root
$ mount /dev/cl_newethan/home /mnt/newethan/home

Проверяем структуру:

$ lsblk
NAME                  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                     8:0    0 232.9G  0 disk 
├─sda1                  8:1    0     1G  0 part 
└─sda2                  8:2    0 231.9G  0 part 
  ├─cl_ethan-swap 253:0    0   7.8G  0 lvm  [SWAP]
  ├─cl_ethan-home 253:1    0 174.1G  0 lvm  
  └─cl_ethan-root 253:2    0    50G  0 lvm  
sdb                     8:16   0 232.9G  0 disk 
sdc                     8:32   0 232.9G  0 disk 
sdd                     8:48   0 232.9G  0 disk 
sde                     8:64   0 232.9G  0 disk 
sdf                     8:80   1  28.7G  0 disk 
├─sdf1                  8:81   1   1.4G  0 part /run/initramfs/live
├─sdf2                  8:82   1   4.9M  0 part 
└─sdf3                  8:83   1  19.6M  0 part 
sdg                     8:96   0 223.6G  0 disk 
├─sdg1                  8:97   0     1G  0 part 
└─sdg2                  8:98   0 222.6G  0 part 
  ├─cl_newethan-swap    253:6    0     8G  0 lvm  
  ├─cl_newethan-root    253:7    0    50G  0 lvm  
  └─cl_newethan-home    253:8    0 164.5G  0 lvm  
loop0                   7:0    0    20K  1 loop 
loop1                   7:1    0   4.3M  1 loop 
└─live-osimg-min      253:5    0     8G  1 dm   
loop2                   7:2    0   1.3G  1 loop 
loop3                   7:3    0     8G  1 loop 
├─live-rw             253:3    0     8G  0 dm   /
├─live-base           253:4    0     8G  1 dm   
└─live-osimg-min      253:5    0     8G  1 dm   
loop4                   7:4    0   512M  0 loop 
└─live-rw             253:3    0     8G  0 dm   /

Структура обоих дисков примерно одинаковая. Можно приступать к клонированию разделов…и тут у меня отключились диски @_@

Траблы

После перезапуска док-станции диск появился под названием sdh. При этом тома уже не хотели читаться. При попытке удалить тома и пересоздать появлялась ошибка, что /dev/cl_newethan уже существует. Решение было следующее:

$ swapoff /dev/cl_newethan
$ dmsetup remove /dev/cl_newethan/swap
$ dmsetup remove /dev/cl_newethan/root
$ dmsetup remove /dev/cl_newethan/home

Далее еще раз перезапустил док-станцию и диск снова подхватился как sdg. Пересоздал разделы и тома, но при этом диск все равно пропадал и проблема всплывала снова. Решил поменять док-станцию (благо был запасной) и заметил, что диск сильно нагрет, потому оставил остывать после чего проблем больше не возникало.

Клонирование XFS

Пожалуй, самый простой этап:

$ xfsdump -l0 -J - /mnt/ethan/boot | xfsrestore -J - /mnt/newethan/boot
$ xfsdump -l0 -J - /mnt/ethan/home | xfsrestore -J - /mnt/newethan/home
$ xfsdump -l0 -J - /mnt/ethan/root | xfsrestore -J - /mnt/newethan/root

Выясняем UUID старого и нового дисков:

$ blkid|grep 'sda1'
/dev/sda1: UUID="3055d690-7b2d-4380-a3ed-4c78cd0456ba" TYPE="xfs"
$ blkid|grep 'sdg1'
/dev/sdg1: UUID="24b2b96b-2a34-4497-b273-6081e5785abc" TYPE="xfs"

Правим UUID в конфигах:

$ sed -i "s/3055d690-7b2d-4380-a3ed-4c78cd0456ba/24b2b96b-2a34-4497-b273-6081e5785abc/g" /mnt/newethan/root/etc/fstab
$ sed -i "s/3055d690-7b2d-4380-a3ed-4c78cd0456ba/24b2b96b-2a34-4497-b273-6081e5785abc/g" /mnt/newethan/boot/grub2/grub.cfg

Размонтируем разделы:

$ umount /mnt/ethan/{boot,root,home}
$ umount /mnt/newethan/{boot,root,home}

Переименовываем старый и новый тома:

$ vgrename /dev/cl_ethan /dev/cl_ethanold
$ vgrename /dev/cl_newethan /dev/cl_ethan

Переустанавливаем загрузчик:

$ mount /dev/cl_ethan/root /mnt
$ mount /dev/sdg1 /mnt/boot
$ mount -t devtmpfs /dev /mnt/dev
$ mount -t proc /dev /mnt/dev
$ mount -t sysfs /sys /mnt/sys
$ chroot /mnt grub2-install /dev/sdg
$ shutdown -h now

Меняем диск. Запускаем сервер и радуемся результату ?