Восстановление из бэкапа BTRFS (mbr)
Полное восстановление системы из созданных снимков btrfs
В предыдущей статье мы сделали снимки(snapshot) двух подтомов(subvolume) с системой, в один из которых предварительно поместили образ загрузочного раздела. Эти снимки мы переслали на другой носитель, для надёжности, и не прогадали. Ибо в этой статье мы пошагово восстановимся из этих снимков. Предположим, что основной диск с системой у нас накрылся... теперь у нас есть совершенно новый диск подходящего размера, и диск со снимками. Благодаря этой инструкции мы пошагово, полностью восстановим систему в состояние на момент созданных снимков.
- Всё достаточно просто, нам необходимо на новом диске воссоздать структуру накрывшегося диска, который состоял из двух разделов. Первый раздел будет загрузочным в формате ext4, в нём мы востановим раздел загрузки из образа созданного в первой статье, а второй раздел будет основным btrfs, куда примем потдома из нашего хранилища backup-ов.
- Есть пара моментов, которые нужно будет учесть, это смена UUID разделов на новом носителе, их нам нужно указать в конфигурационном файле загрузки fstab, имена подтомов тоже немного поменялись... Ещё необходимо будет снять защиту от записи, с подтомов после переноса их на целевой диск командой btrfs property set.
- Также необходимо будет войти в режим chroot и переустановить загрузчик GRUB2. И после выполнения этих процедур, наша система будет полностью восстановлена.
Итак добавляем новый диск в виртуальную машину, на который и будем востанаваливаться. 40gb, судя по размерам репозитария, нам хватит с лихвой. Все необходимые инструкции по работе в программе VirtualBox здесь.
Загружаемся с live образа, у меня например MXlinux, удобный, дистрибутив, который кстати на день создания этого туториала занимает первое место в рейтинге https://distrowatch.com/
Здесь при выполнении операций подготовки к бэкапу, сразу входим в режим суперпользователя root, чтобы не вводить постоянно слово sudo
lsblk -f
И вот что мы видим:
☯
Terminal:
⌕
≡
✕
demo@mx1:~/Desktop $ sudo su We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things: #1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility. [sudo] password for demo: root@mx1:/home/demo/Desktop# lsblk -f NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINT loop0 squashfs 4.0 0 100% /live/linux sda sdb └─sdb1 btrfs f7274863-edf2-44f1-b64d-7d2ce764f441 sr0 iso9660 Joliet Exten MX-Live 2021-10-19-23-10-23-00 0 100% /live/boot- root@mx1:/home/demo/Desktop#
Здесь вам уже должно быть ясно, что диск sda, который у нас сейчас вообще без разделов будет целевым. А диск sdb, у которого есть раздел sdb1, это наш репозитарий с backup-ом.
- Создадим точку монтирования, смонтируем раздел с нашим бэкапом.
- Запишем сохраннёный MBR диска вместе с таблицей разделов на целевой диск sda.
mount /dev/sdb1 /mnt/sdb1
ls /mnt/sdb1/
ls /mnt/sdb1/backup_4_11_21/root_bp/
dd if=/mnt/sdb1/backup_4_11_21/root_bp/backup_boot/file.mbr of=/dev/sda bs=512 count=1
lsblk -f
☯
Terminal:
⌕
≡
✕
root@mx1:/home/demo/Desktop# mkdir /mnt/sdb1 root@mx1:/home/demo/Desktop# mount /dev/sdb1 /mnt/sdb1 root@mx1:/home/demo/Desktop# ls /mnt/sdb1/ backup_4_11_21 root@mx1:/home/demo/Desktop# ls /mnt/sdb1/backup_4_11_21 home_bp root_bp root@mx1:/home/demo/Desktop# ls /mnt/sdb1/backup_4_11_21/root_bp backup_boot boot etc lib lost+found mnt proc run srv tmp var bin dev home lib64 media opt root sbin sys usr root@mx1:/home/demo/Desktop# ls /mnt/sdb1/backup_4_11_21/root_bp/backup_boot dd_sda1_boot_1024mb.iso file.mbr root@mx1:/home/demo/Desktop# dd if=/mnt/sdb1/backup_4_11_21/root_bp/backup_boot/file.mbr of=/dev/sda bs=512 count=1 1+0 records in 1+0 records out 512 bytes copied, 0.000542411 s, 944 kB/s root@mx1:/home/demo/Desktop# root@mx1:/home/demo/Desktop# lsblk -f NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINT loop0 squashfs 4.0 0 100% /live/linux sda ├─sda1 └─sda2 sdb └─sdb1 btrfs f7274863-edf2-44f1-b64d-7d2ce764f441 8.1G 53% /mnt/sdb1 sr0 iso9660 Joliet Extension MX-Live 2021-10-19-23-10-23-00 0 100% /live/boot-dev root@mx1:/home/demo/Desktop#
Так мы получили диск с MBR и нужными нам разделами, теперь нужно отформатировать разделы в нужном нам формате. sda1 в ext4, и sda2 в btrfs. Хотя в нашем случае sda1 можно даже не форматировать, ведь он будет полностью востановлен утилитой dd из образа, вместе с форматом файловой системы... Но sda2 сейчас форматируем обязательно.
Открываем gparted и делаем это.
Однако если вы самостоятельно решили создавать таблицу разделов не используя file.mbr, то не забудьте установить и флаг загрузки boot в первый раздел. Для струкур разделов диска MBR как в этом случае, это имеет большое значение, чего не скажешь про GPT. Подробнее о структурах и их различиях можно узнать здесь.
Теперь создаём каталог - точку монтирования и для btrfs раздела /mnt/sda2 целевого диска, монтируемся.
mount /dev/sda2 /mnt/sda2
Настала пора, можно сказать, ключевого момента в процедуре востанавления системы из бэкапа - пересылаем подтома из sdb1 на этот диск sda2, но помним, что снимки всё ещё остаются в readonly
btrfs send /mnt/sdb1/backup_4_11_21/home_bp | btrfs receive /mnt/sda2
☯
Terminal:
⌕
≡
✕
root@mx1:/home/demo/Desktop# mkdir /mnt/sda2 root@mx1:/home/demo/Desktop# mount /dev/sda2 /mnt/sda2 root@mx1:/home/demo/Desktop# btrfs send /mnt/sdb1/backup_4_11_21/root_bp | btrfs receive /mnt/sda2 At subvol /mnt/sdb1/backup_4_11_21/root_bp At subvol root_bp root@mx1:/home/demo/Desktop# btrfs send /mnt/sdb1/backup_4_11_21/home_bp | btrfs receive /mnt/sda2 At subvol /mnt/sdb1/backup_4_11_21/home_bp At subvol home_bp root@mx1:/home/demo/Desktop# ls /mnt/sda2 home_bp root_bp root@mx1:/home/demo/Desktop#
Так как мы работаем сейчас с btrfs, то самое время выполнить синхронизацию данных на диске с данными в памяти. При этом выполняется системный вызов sync, который вызывает запись всех буферизованных изменений метаданных файлов и данных в базовые файловые системы.
☯
Terminal:
⌕
≡
✕
root@mx1:/home/demo/Desktop# sync root@mx1:/home/demo/Desktop# root@mx1:/home/demo/Desktop# btrfs filesystem sync /mnt/sda2 root@mx1:/home/demo/Desktop#
Теперь востанавливаем загрузочный раздел целевого диска из образа утилитой dd со статусом progress, чтобы видеть процесс копирования.
☯
Terminal:
⌕
≡
✕
root@mx1:/home/demo/Desktop# ls /mnt/sda2/root_bp/backup_boot/
dd_sda1_boot_1024mb.iso file.mbr
root@mx1:/home/demo/Desktop# dd if=/mnt/sda2/root_bp/backup_boot/dd_sda1_boot_1024mb.iso of=/dev/sda1 status=progress
1015771648 bytes (1.0 GB, 969 MiB) copied, 25 s, 40.6 MB/s
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 25.981 s, 41.3 MB/s
root@mx1:/home/demo/Desktop#
Переводим subvolume в режим rw, т.е. убираем флаг только чтение, это обязательно нужно сделать иначе система не загрузится. Посмотреть флаг состояние подтома get, чтобы установить set. Если ro=true значит режим readonly. Нам нужно сделать ro=false.
btrfs property get /mnt/sda2/home_bp
btrfs property set /mnt/sda2/root_bp ro false
btrfs property set /mnt/sda2/home_bp ro false
btrfs property get /mnt/sda2/root_bp
btrfs property get /mnt/sda2/home_bp
☯
Terminal:
⌕
≡
✕
root@mx1:/home/demo/Desktop# btrfs property get /mnt/sda2/root_bp ro=true root@mx1:/home/demo/Desktop# btrfs property get /mnt/sda2/home_bp ro=true root@mx1:/home/demo/Desktop# btrfs property set /mnt/sda2/root_bp ro false root@mx1:/home/demo/Desktop# btrfs property set /mnt/sda2/home_bp ro false root@mx1:/home/demo/Desktop# btrfs property get /mnt/sda2/root_bp ro=false root@mx1:/home/demo/Desktop# btrfs property get /mnt/sda2/home_bp ro=false root@mx1:/home/demo/Desktop#
Теперь заключительный этап, переустановка grub2 и правка fstab. Запишем новые UUID и наши новые имена томов.
Смотрим какие у нас сейчас указаны записи в конфигурационном файле fstab.
Смотрим какие UUID сейчас у нас на новом диске командой lsblk -f. Причём UUID загрузочного раздела sda1 останется без изменений, ведь он скопировался полностью весь из образа, утилитой dd. Но UUID основного раздела sda2 у нас поменялся, укажем это изменение в fstab. И заодно запишем новые имена подтомов, которые теперь с префиксом _bp.
lsblk -f
ls /mnt/sda2
☯
Terminal:
⌕
≡
✕
root@mx1:/home/demo/Desktop# cat /mnt/sda2/root_bp/etc/fstab # # /etc/fstab # Created by anaconda on Fri Apr 16 15:13:25 2021 # # Accessible filesystems, by reference, are maintained under '/dev/disk/'. # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info. # # After editing this file, run 'systemctl daemon-reload' to update systemd # units generated from this file. # UUID=1246f778-7ba5-430d-809a-a80ea801f09a / btrfs subvol=root,compress=zstd:1 0 0 UUID=690c0d1a-43f3-4fe3-ae0d-b4dc3acad065 /boot ext4 defaults 1 2 UUID=1246f778-7ba5-430d-809a-a80ea801f09a /home btrfs subvol=home,compress=zstd:1 0 0 root@mx1:/home/demo/Desktop# root@mx1:/home/demo/Desktop# root@mx1:/home/demo/Desktop# lsblk -f NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINT loop0 squashfs 4.0 0 100% /live/linux sda ├─sda1 ext4 1.0 690c0d1a-43f3-4fe3-ae0d-b4dc3acad065 └─sda2 btrfs 941e22df-6b33-4a0c-ad2a-3311840464da 19G 37% /mnt/sda2 sdb └─sdb1 btrfs f7274863-edf2-44f1-b64d-7d2ce764f441 8.1G 53% /mnt/sdb1 sr0 iso9660 Joliet Extension MX-Live 2021-10-19-23-10-23-00 0 100% /live/boot-dev root@mx1:/home/demo/Desktop# root@mx1:/home/demo/Desktop# root@mx1:/home/demo/Desktop# ls /mnt/sda2 home_bp root_bp root@mx1:/home/demo/Desktop#
Теперь посмотрим на новый fstab который получится на основе этих данных, после редактирования в редакторе nano или vim, с новыми UUID и именами subvolume
nano /mnt/sda2/root_bp/etc/fstab
вставляем в первую и третью строку, и меняем имена подтомов
ctrl+o (сохранить в nano) ctrl+x (выйти)
☯
Terminal:
⌕
≡
✕
GNU nano 5.4 /mnt/sda2/root_bp/etc/fstab # # /etc/fstab # Created by anaconda on Fri Apr 16 15:13:25 2021 # # Accessible filesystems, by reference, are maintained under '/dev/disk/'. # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info. # # After editing this file, run 'systemctl daemon-reload' to update systemd # units generated from this file. # UUID=941e22df-6b33-4a0c-ad2a-3311840464da / btrfs subvol=root_bp,compress=zstd:1 0 0 UUID=690c0d1a-43f3-4fe3-ae0d-b4dc3acad065 /boot ext4 defaults 1 2 UUID=941e22df-6b33-4a0c-ad2a-3311840464da /home btrfs subvol=home_bp,compress=zstd:1 0 0
Теперь переустановим GRUB2, применив chroot. Отмонтируем всё смонтированное из подкаталогов в /mnt/. Эти точки нам дальше не пригодятся.
Теперь монтируем, корень будующей системы в подтом root_bp
и после подключаем к нему, текущие системные каталоги, из live системы, следующими командами
mount --rbind /proc /mnt/proc
mount --rbind /dev /mnt/dev
mount --rbind /run /mnt/run
☯
Terminal:
⌕
≡
✕
root@mx1:/home/demo/Desktop# umount -R -l /mnt/*
root@mx1:/home/demo/Desktop# mount -o subvol=root_bp -o compress=zstd:1 /dev/sda2 /mnt
root@mx1:/home/demo/Desktop# mount --rbind /sys /mnt/sys
root@mx1:/home/demo/Desktop# mount --rbind /proc /mnt/proc
root@mx1:/home/demo/Desktop# mount --rbind /dev /mnt/dev
root@mx1:/home/demo/Desktop# mount --rbind /run /mnt/run
root@mx1:/home/demo/Desktop#
переключаемся на созданную файловую систему командой
Теперь монтируем разделы boot и subvolume home_bp в соответствующие каталоги
mount -o subvol=home_bp -o compress=zstd:1 /dev/sda2 /home
☯
Terminal:
⌕
≡
✕
root@mx1:/home/demo/Desktop# chroot /mnt
[root@mx1 /]# mount /dev/sda1 /boot
[root@mx1 /]# mount -o subvol=home_bp -o compress=zstd:1 /dev/sda2 /home
[root@mx1 /]#
И только теперь переустановим grub2
☯
Terminal:
⌕
≡
✕
[root@mx1 /]# grub2-install /dev/sda Installing for i386-pc platform. Installation finished. No error reported. [root@mx1 /]#
И сразу сконфигурируем grub2 в этой системе, командой:
☯
Terminal:
⌕
≡
✕
[root@mx1 /]# grub2-mkconfig /boot/grub2/grub.cfg Generating grub configuration file ... # # DO NOT EDIT THIS FILE # # It is automatically generated by grub2-mkconfig using templates # from /etc/grub.d and settings from /etc/default/grub # ### BEGIN /etc/grub.d/00_header ### set pager=1 if [ -f ${config_directory}/grubenv ]; then load_env -f ${config_directory}/grubenv elif [ -s $prefix/grubenv ]; then load_env fi if [ "${next_entry}" ] ; then set default="${next_entry}" set next_entry= save_env next_entry set boot_once=true else set default="${saved_entry}" fi if [ x"${feature_menuentry_id}" = xy ]; then menuentry_id_option="--id" else menuentry_id_option="" fi export menuentry_id_option if [ "${prev_saved_entry}" ]; then set saved_entry="${prev_saved_entry}" save_env saved_entry set prev_saved_entry= save_env prev_saved_entry set boot_once=true fi function savedefault { if [ -z "${boot_once}" ]; then saved_entry="${chosen}" save_env saved_entry fi } function load_video { if [ x$feature_all_video_module = xy ]; then insmod all_video else insmod efi_gop insmod efi_uga insmod ieee1275_fb insmod vbe insmod vga insmod video_bochs insmod video_cirrus fi } terminal_output console if [ x$feature_timeout_style = xy ] ; then set timeout_style=menu set timeout=5 # Fallback normal timeout code in case the timeout_style feature is # unavailable. else set timeout=5 fi ### END /etc/grub.d/00_header ### ### BEGIN /etc/grub.d/01_users ### if [ -f ${prefix}/user.cfg ]; then source ${prefix}/user.cfg if [ -n "${GRUB2_PASSWORD}" ]; then set superusers="root" export superusers password_pbkdf2 root ${GRUB2_PASSWORD} fi fi ### END /etc/grub.d/01_users ### ### BEGIN /etc/grub.d/08_fallback_counting ### insmod increment # Check if boot_counter exists and boot_success=0 to activate this behaviour. if [ -n "${boot_counter}" -a "${boot_success}" = "0" ]; then # if countdown has ended, choose to boot rollback deployment, # i.e. default=1 on OSTree-based systems. if [ "${boot_counter}" = "0" -o "${boot_counter}" = "-1" ]; then set default=1 set boot_counter=-1 # otherwise decrement boot_counter else decrement boot_counter fi save_env boot_counter fi ### END /etc/grub.d/08_fallback_counting ### ### BEGIN /etc/grub.d/10_linux ### insmod part_msdos insmod ext2 set root='hd0,msdos1' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 690c0d1a-43f3-4fe3-ae0d-b4dc3acad065 else search --no-floppy --fs-uuid --set=root 690c0d1a-43f3-4fe3-ae0d-b4dc3acad065 fi insmod part_msdos insmod ext2 set boot='hd0,msdos1' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=boot --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 690c0d1a-43f3-4fe3-ae0d-b4dc3acad065 else search --no-floppy --fs-uuid --set=boot 690c0d1a-43f3-4fe3-ae0d-b4dc3acad065 fi # This section was generated by a script. Do not modify the generated file - all changes # will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files. # # The blscfg command parses the BootLoaderSpec files stored in /boot/loader/entries and # populates the boot menu. Please refer to the Boot Loader Specification documentation # for the files format: https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/. # The kernelopts variable should be defined in the grubenv file. But to ensure that menu # entries populated from BootLoaderSpec files that use this variable work correctly even # without a grubenv file, define a fallback kernelopts variable if this has not been set. # # The kernelopts variable in the grubenv file can be modified using the grubby tool or by # executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX # and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both # the kernelopts variable in the grubenv file and the fallback kernelopts variable. if [ -z "${kernelopts}" ]; then set kernelopts="root=UUID=941e22df-6b33-4a0c-ad2a-3311840464da ro rootflags=subvol=root_bp rhgb quiet " fi insmod blscfg blscfg ### END /etc/grub.d/10_linux ### ### BEGIN /etc/grub.d/10_reset_boot_success ### # Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry if [ "${boot_success}" = "1" -o "${boot_indeterminate}" = "1" ]; then set menu_hide_ok=1 else set menu_hide_ok=0 fi # Reset boot_indeterminate after a successful boot if [ "${boot_success}" = "1" ] ; then set boot_indeterminate=0 # Avoid boot_indeterminate causing the menu to be hidden more then once elif [ "${boot_indeterminate}" = "1" ]; then set boot_indeterminate=2 fi # Reset boot_success for current boot set boot_success=0 save_env boot_success boot_indeterminate ### END /etc/grub.d/10_reset_boot_success ### ### BEGIN /etc/grub.d/12_menu_auto_hide ### if [ x$feature_timeout_style = xy ] ; then if [ "${menu_show_once}" ]; then unset menu_show_once save_env menu_show_once set timeout_style=menu set timeout=60 elif [ "${menu_auto_hide}" -a "${menu_hide_ok}" = "1" ]; then set orig_timeout_style=${timeout_style} set orig_timeout=${timeout} if [ "${fastboot}" = "1" ]; then # timeout_style=menu + timeout=0 avoids the countdown code keypress check set timeout_style=menu set timeout=0 else set timeout_style=hidden set timeout=1 fi fi fi ### END /etc/grub.d/12_menu_auto_hide ### ### BEGIN /etc/grub.d/14_menu_show_once ### if [ x$feature_timeout_style = xy ]; then if [ "${menu_show_once_timeout}" ]; then set timeout_style=menu set timeout="${menu_show_once_timeout}" unset menu_show_once_timeout save_env menu_show_once_timeout fi fi ### END /etc/grub.d/14_menu_show_once ### ### BEGIN /etc/grub.d/20_linux_xen ### ### END /etc/grub.d/20_linux_xen ### ### BEGIN /etc/grub.d/20_ppc_terminfo ### ### END /etc/grub.d/20_ppc_terminfo ### ### BEGIN /etc/grub.d/30_os-prober ### ### END /etc/grub.d/30_os-prober ### ### BEGIN /etc/grub.d/30_uefi-firmware ### ### END /etc/grub.d/30_uefi-firmware ### ### BEGIN /etc/grub.d/40_custom ### # This file provides an easy way to add custom menu entries. Simply type the # menu entries you want to add after this comment. Be careful not to change # the 'exec tail' line above. ### END /etc/grub.d/40_custom ### ### BEGIN /etc/grub.d/41_custom ### if [ -f ${config_directory}/custom.cfg ]; then source ${config_directory}/custom.cfg elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then source $prefix/custom.cfg fi ### END /etc/grub.d/41_custom ### done [root@mx1 /]#
выходим из chroot
размонтировать всё и перезагрузиться
reboot
☯
Terminal:
⌕
≡
✕
[root@mx1 /]# exit exit root@mx1:/home/demo/Desktop# umount -R -l /mnt root@mx1:/home/demo/Desktop# reboot root@mx1:/home/demo/Desktop#
Вытаскиваем загрузочный образ Live DVD и загружаемся с нового диска, в результате получаем полностью востановленную систему на момент сделанного backup.
-
- Roman Sakhno
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.