Об преимуществах BTRFS известно многое: это встроенные возможности RAID и адресация какого-то безумного объема информации, но для автора решающей стала возможность сохранения моментальных снимков (snapshot) на лету. Ведь вируталку - раз, и готова резервная копия. С нее можно восстановить, можно отправить в архив, а можно стартануть с нее новую. Хотелось похожей легкости и для железки. А вот специфика того, что снимок можно сохранить только на раздел BTRFS, заставила решиться меня на рисковое предприятие.
OpenMediaVault — это сетевое хранилище (NAS) следующего поколения на базе Debian Linux. Оно содержит готовые к использованию службы: SSH, (S)FTP, SMB/CIFS, RSync и другие. Благодаря модульной конструкции его можно расширить с помощью плагинов, так же можно использовать и обычные сервисы операционной системы. Openmediavault в первую очередь предназначен для использования в небольших офисах или домашних офисах, но не ограничивается этим. Это простое и удобное в использовании готовое решение, которое позволит каждому сделать свое сетевое хранилище.
Спойлер. Оказалось не сложно.
Будем использовать утилиту btrfs-convert из состава btrfs-tools. Возможна конвертация из ext4 (и младше), reiserfs.
Как водится в ИТ, декомпозируем задачу.
- Проверяем возможность.
- Определение объекта.
- Резервируем особо ценную информацию.
- Останавливаем сервисы.
- Конвертируем.
- Перенастраиваем OpenMediaVault и другие сервисы.
- Запускаем сервисы и проверяем.
- А если что-то пошло не так?
Определение возможности
Запас пространства
При конвертации для создания управляющих блоков (inodes) используется свободное пространство конвертируемого раздела. Сама информация (содержание файлов) не копируется, а в свободном пространстве создаются:
- файл служебной информации ФС ext4;
- служебная информация ФС BTRFS.
На моем 2 TB хранилище свободно было меньше 38%, но хватило.
Точный объем свободного пространства заранее неизвестен, так как зависит от количества и размера файлов, опций и прочего.
Наличие инструмента
Понадобится утилита btrfs-convert из пакета btrfs-progs
Если нету, установить командой:
sudo apt-get install btrfs-progs
Определение объекта
Смотрим таблицу монтирования:
root@poplar:~# cat /etc/fstab
UUID=ac564369-ee4e-4ec7-a212-c0c90a3314e9 / ext4 defaults,noatime,commit=600,errors=remount-ro 0 1
UUID=55C0-8FCE /boot/efi vfat defaults 0 2
tmpfs /tmp tmpfs defaults,nosuid 0 0
# >>> [openmediavault]
/dev/disk/by-uuid/76f440f3-0562-48e6-b8dc-ae5d7ff6c621 /srv/dev-disk-by-uuid-76f440f3-0562-48e6-b8dc-ae5d7ff6c621 btrfs defaults,nofail 0 2
# <<< [openmediavault]
root@poplar:~#
Мой RIAD имел UUID 76f440f3-0562-48e6-b8dc-ae5d7ff6c621 и был блочным устройством /dev/md0:
root@poplar:~# mount
...
/dev/md0 on /var/lib/transmission-daemon type ext4 (rw,noatime,errors=remount-ro,commit=600)
...
root@poplar:~#
Резервирование
Шансов, что что-то пойдет не так не много, операция конвертирования обратима на любом этапе, но шанс что произойдет ошибка всегда есть.
Призываю сохранить все чувствительные данные на внешний носитель информации любым способом.
Ремарка. Вообще надеяться на NAS можно лишь в ограниченном смысле, и дело не только в технической надежности, но и в том простом факте, что NAS это работающая динамическая система, и можно что-то "грохнуть" по ошибке есть всегда. Человеческий фактор.
Если уверены, что данные в безопасности, идем дальше.
Останавливаем сервисы
Мы конвертируем файловую систему хранилища, но не самой операционной системы, а значит необходимости в загрузке иной (внешней) копии ОС нет, можно работать на загруженном ядре.
Зато нужно предотвратить вмешательство сервисов OpenMediaVault в наши процессы и отключить раздел.
У меня кроме самой еще крутится:
- minidlna;
- transmission-daemon.
И я сообщу что с ними делать дополнительно.
А OpenMediaVault содержит сервисы:
- nginx;
- openmediavault-engined;
- openmediavault-issue;
- php7.4-fpm.
"Гасим" все это хозяйство по шаблону:
systemctl stop <something>
systemctl disable <something>
systemctl mask <something>
Пример.
systemctl stop nginx
systemctl disable nginx
systemctl mask nginx
systemctl stop openmediavault-engined
systemctl disable openmediavault-engined
systemctl mask openmediavault-engined
systemctl stop openmediavault-issue
systemctl disable openmediavault-issue
systemctl mask openmediavault-issue
systemctl stop php7.4-fpm
systemctl disable php7.4-fpm
systemctl mask php7.4-fpm
Про systemctl mask. Уж пока не не разобрался, но если просто остановить любую из этих служб, какая-то... запускает обратно. Поэтому отрубаем от слова совсем. Как найду откуда ноги растут, будет ссылка under construction.
Если все хорошо, то раздел с хранилищем отключается командой:
root@poplar:~# umount /dev/md0
Если ж сработало, то lsof в помощь:
root@poplar:~# lsof /srv/dev-disk-by-uuid-76f440f3-0562-48e6-b8dc-ae5d7ff6c621 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME transmiss 868 debian-transmission 20r REG 0,39 734257152 36831488 /srv/dev-disk-by-uuid-8a50587d-4bf3-4 efb-b514-e80b1dce4730/Download/transmission-daemon/downloads/17_mgnoveniy_vesny/9.avi
Отмонтировался? Тогда идем дальше.
Конвертация
Дошли до самого главного. Сначала проверим состояние носителя:
root@poplar:~# umount /dev/md0
umount: /dev/md0: not mounted.
root@poplar:~# fsck.ext4 /dev/md0
e2fsck 1.46.2 (28-Feb-2021)
/dev/md0: clean, 106755/122093568 files, 266017568/488345616 blocks
Процесс конвертации может занимать несколько часов и состоит из следующих этапов:
создание файла образа существующей файловой системы;
создание самой новой файловой системы BTRFS;
перенос узлов (inode) файлов из существующей в новую.
Тела самих файлов остаются в прежних местах, на их переразмещение не требуется места, а вот на файл отката и образ новой ФС - да, требуется.
Все операции обратимы, вдыхаем и действуем:
root@poplar:~# btrfs-convert /dev/md0
create btrfs filesystem:
blocksize: 4096
nodesize: 16384
features: extref, skinny-metadata (default)
checksum: crc32c
free space report:
total: 2000263643136
free: 775100289024 (38.75%)
creating ext2 image file
creating btrfs metadata
copy inodes [o] [ 115308/ 106755]
conversion complete
"complete" - значит, готово. Я ждал ночь на одноядерном AMD и программном RAID Linux.
Монтируем результат:
root@poplar:~# mount -t btrfs /dev/md0 /mnt
root@poplar:~# mount
...
/dev/sdf3 on / type ext4 (rw,noatime,errors=remount-ro,commit=600)
...
/dev/md0 on /mnt type btrfs (rw,relatime,space_cache,subvolid=5,subvol=/)
Любуемся содержанием:
root@poplar:~# ls /mnt/
AutosyncPublic Download aquota.group aquota.user archive ext2_saved homes lost+found media postgresql sharkhan
root@poplar:~#
Ищем откатной раздел:
root@poplar:~# btrfs subvolume list /mnt
ID 256 gen 3 top level 5 path ext2_saved
root@poplar:~#
И прощаемся с ним:
root@poplar:~# btrfs subvolume delete -i 256 /mnt
Delete subvolume (no-commit): '/mnt/ext2_saved'
root@poplar:~# btrfs subvolume list /mnt
root@poplar:~#
Теперь назад пути нет и не надо.
Перенастраиваем OpenMediaVault и другие сервисы
На моем опыте произошла ситуация с OpenMediaVault такая, что сервис openmediavault-engined.service запускался автоматически, и это привело к тому, что в интерфейсе OMV в разделе "File Systems" новосозданный раздел появился "сам", а вот убиенный так же остался висеть и мешать всему. Записи ФС "прилипли" к старому разделу UUID и поменять их сложно.
Пришлось все же остановить и замаскировать службу openmediavault-engined.service и приступить к правке конфига. Оказалось не слишком сложно.
Конфиг лежит по адресу "/etc/openmediavault/config.xml". Действовать будем аккуратно:
Копируем конфиг к себе:
cp -r /etc/openmediavault/ .
любым редактором открываем и смотрим записи "mtent" в разделе "fstab".
Вообще рекомендую скачать файл конфига (например, по sftp) на локальный ПЭВМ, чтобы редактировать удобным редактором - оперировать нужно большими строками.
Из config.xml нужно отметить:
- UUID старого убиенного раздела.
- UUID новоиспеченного раздела.
- UUID записи mtent старого убиенного раздела.
- UUID записи mtent новоиспеченного раздела.
Операция сводится к простому:
- Убедиться в наличии UUID новоиспеченного раздела.
- Убрать запись со UUID старого раздела.
- Заменить вхождения UUID записи mtent старого убиенного раздела на UUID записи mtent новоиспеченного раздела.
В сравнении командой diff разница у меня получилась такой:
root@poplar:/home/zoo# diff config.xml /root/openmediavault/config.xml
485a486,497
> <uuid>79922d23-12f5-4b9a-a92f-6bdf3f14b654</uuid>
> <fsname>/dev/disk/by-uuid/76f440f3-0562-48e6-b8dc-ae5d7ff6c621</fsname>
> <dir>/srv/dev-disk-by-uuid-76f440f3-0562-48e6-b8dc-ae5d7ff6c621</dir>
> <type>ext4</type>
> <opts>defaults,nofail,user_xattr,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0,acl</opts>
> <freq>0</freq>
> <passno>2</passno>
> <hidden>0</hidden>
> <usagewarnthreshold>85</usagewarnthreshold>
> <comment>Primary</comment>
> </mntent>
> <mntent>
497c509
< <fsname>/dev/disk/by-uuid/8a50587d-4bf3-4efb-b514-e80b1dce4730/media/</fsname>
---
> <fsname>/srv/dev-disk-by-uuid-76f440f3-0562-48e6-b8dc-ae5d7ff6c621/media/</fsname>
541c553
< <mntentref>3dc8144e-98af-417d-a8da-29c8d3e77232</mntentref>
---
> <mntentref>79922d23-12f5-4b9a-a92f-6bdf3f14b654</mntentref>
560c572
< <mntentref>3dc8144e-98af-417d-a8da-29c8d3e77232</mntentref>
---
> <mntentref>79922d23-12f5-4b9a-a92f-6bdf3f14b654</mntentref>
579c591
< <mntentref>3dc8144e-98af-417d-a8da-29c8d3e77232</mntentref>
---
> <mntentref>79922d23-12f5-4b9a-a92f-6bdf3f14b654</mntentref>
587c599
< <mntentref>3dc8144e-98af-417d-a8da-29c8d3e77232</mntentref>
---
> <mntentref>79922d23-12f5-4b9a-a92f-6bdf3f14b654</mntentref>
595c607
< <mntentref>3dc8144e-98af-417d-a8da-29c8d3e77232</mntentref>
---
> <mntentref>79922d23-12f5-4b9a-a92f-6bdf3f14b654</mntentref>
603c615
< <mntentref>3dc8144e-98af-417d-a8da-29c8d3e77232</mntentref>
---
> <mntentref>79922d23-12f5-4b9a-a92f-6bdf3f14b654</mntentref>
611c623
< <mntentref>3dc8144e-98af-417d-a8da-29c8d3e77232</mntentref>
---
> <mntentref>79922d23-12f5-4b9a-a92f-6bdf3f14b654</mntentref>
root@poplar:/home/zoo#
После запуска служб:
systemctl unmask nginx
systemctl enable nginx
systemctl start nginx
systemctl unmask openmediavault-engined
systemctl enable openmediavault-engined
systemctl start openmediavault-engined
systemctl unmask openmediavault-issue
systemctl enable openmediavault-issue
systemctl start openmediavault-issue
systemctl unmask php7.4-fpm
systemctl enable php7.4-fpm
systemctl start php7.4-fpm
OpenMediaVault забудет о прошлом и хорошо поймет жизнь с новым. На BTRFS.
А если что-то пошло не так?
# Монтирование снапшота ext4
mount -t btrfs -o subvol=ext2_saved /dev/sdX /ext2_saved
# Обратное преобразование
btrfs-convert -r /dev/sdX
# Монтирование исходной файловой системы
mount -t ext4 /dev/sdX /ext4
# Монтирование файла образа как loopback-устройства
mount -t ext4 -o loop,ro /ext2_saved/image /ext3