Сервер NAS обновился по кнопке в веб-панели или через штатный менеджер пакетов, перезагрузился - и тишина: шар не видно, SSH не отвечает, а экран через IPMI показывает зависшую загрузку. Первый порыв - переустановка и неделя ручного восстановления конфигов Samba, монтирований и crontab. Но если корень NAS стоит на btrfs и перед обновлением существовал снимок, возврат к рабочему состоянию занимает минут десять. Ниже рабочая процедура отката через snapper rollback, ручное переключение корня через btrfs subvolume set-default, разбор типичных ошибок и шаги, которые превращают следующий откат из аврала в рутину.
Почему после обновления NAS перестаёт отвечать и что проверить перед откатом
Причин обычно три. Первая - ядро: свежий kernel не стартовал на этом железе, отпал модуль сетевой карты или контроллера дисков. Вторая - сервисы: обновились Samba или NFS-сервер, и новая версия не поднимается из-за несовместимого конфига. Третья - каскад: обновление тронуло systemd и юниты, и после перезагрузки сеть просто не поднялась.
До отката соберите факты. Если есть консоль - через IPMI, iLO или физический монитор с клавиатурой - посмотрите, на чём именно споткнулась загрузка. Иногда причина видна сразу: паника ядра на строке с именем модуля или failed у юнита сети. Проверьте, отвечает ли машина на ping, открыта ли веб-панель NAS, мигают ли индикаторы дисков.
Когда до консоли добраться нельзя, грузитесь с live-носителя и смотрите журнал упавшей загрузки и состояние служб из смонтированного корня:
mount /dev/sda2 /mnt/root
journalctl -b -1 -p err --no-pager -D /mnt/root/var/log/journal
systemctl --failed --root /mnt/root
Практическое правило: если причина видна и чинится одной правкой конфига за пятнадцать минут, чините. Если же сервер не грузится вовсе, а версия ядра или десятка пакетов поменялась - откат быстрее и надёжнее косметического ремонта, после которого система останется в невоспроизводимом состоянии наполовину старых, наполовину новых файлов.
И не приписывайте обновлению то, что к нему отношения не имеет. Если в журнале видны I/O error и сбойные секторы, а NAS тормозил ещё до обновления, дело скорее в диске, чем в пакете. Быстрая проверка из live-сессии: smartctl -H /dev/sda покажет общий вердикт SMART, а smartctl -A перечислит атрибуты Reallocated_Sector_Ct и Current_Pending_Sector. Откат на снимок такой диск не починит, зато сэкономит часы, которые иначе уйдут на поиск виновного пакета.
Перед любым откатом зафиксируйте минимум сведений о состоянии сервера:
- снимите карту дисков командой lsblk -f, чтобы не перепутать устройства при ручных операциях;
- сохраните вывод dmesg и список сломанных юнитов из live-сессии, они пригодятся для разбора;
- найдите номер снимка, соответствующего последнему рабочему состоянию, и запишите его;
- проверьте свободное место на пуле, снимки тоже расходуют гигабайты.
Как устроены снимки btrfs и где Snapper хранит историю обновлений
Снимок в btrfs это не копия файлов, а новый subvolume с дубликатом метаданных. Изменённые блоки пишутся по механизму copy-on-write, поэтому снимок занимает место только под реально изменившиеся данные. На openSUSE и SLES корень живёт в subvolume @, рядом лежат @/home, @/var и @/srv, а снимки хранятся в @/.snapshots: каждый номер снимка это каталог вида /.snapshots/42/snapshot, внутри которого лежит корень на момент создания. Снимки Snapper по умолчанию создаются в режиме только для чтения, случайно испортить их содержимое через штатные программы нельзя.
Snapper автоматизирует эту кухню. Конфиг root описан в /etc/snapper/configs/root, таймлайн снимков управляется переменными TIMELINE_CREATE и TIMELINE_LIMIT_HOURLY, а пары pre и post создаёт сам пакетный менеджер при каждой транзакции. История выглядит так:
snapper -c root list
Колонка Date подскажет, какой снимок сделан перед неудачным обновлением, Description привяжет пару к транзакции вида "zypper(1042)", а Type покажет, одиночный это снимок или часть пары. Очисткой управляют флаги в конфиге: NUMBER_CLEANUP с NUMBER_LIMIT задаёт, сколько снапшотов хранить, TIMELINE_LIMIT_DAILY и TIMELINE_LIMIT_MONTHLY ограничивают таймлайн, EMPTY_PRE_POST удаляет пары без изменений. Полезны и две уточняющие команды: snapper diff 41..42 выводит список изменённых файлов между соседними снимками, а snapper undo-change 41..42 откатывает отдельные файлы без перестройки корня - удобный путь, когда сломан один конфиг, а не вся система.
Отдельный вопрос - какие именно конфиги уезжают в откат. Откат корня трогает только subvolume корня; файлы на @/home, @/srv и отдельных томах остаются в актуальном состоянии, пользователи ничего не потеряют. Посмотреть, какие конфиги заведены, можно командой snapper list-configs: если рядом с root есть конфиг home с собственным таймлайном, у него будет своя история и своя точка возврата. На самосборных NAS с одним разделом и без subvolume делений снимок корня захватывает всё, включая домашние каталоги, и это надо учитывать, выбирая снимок для отката: между двумя датами могли измениться файлы пользователей.
Быстрый откат через snapper rollback и загрузку снимка из меню GRUB
Если сервер доходит до меню GRUB, дорога короткая. У openSUSE и SLES в меню есть пункт "Start from a read-only snapshot", его добавляет пакет grub2-snapper-plugin. Загрузитесь в ближайший снимок, убедитесь, что сеть и диски живы, затем выполните:
snapper rollback 42
reboot
Команда сохраняет текущее сломанное состояние в снимок, создаёт новый корневой subvolume на базе номера 42 и назначает его корнем по умолчанию. Ничего не теряется: если и снимок 42 окажется неидеальным, откат повторяют на другой номер, полный список доступен всё в том же snapper list. Загрузка прямо в снимок - это пробный прогон: система стартует с корнем тридцатиминутной давности, и до выполнения rollback есть время проверить, тот ли это момент. Заодно спланируйте порядок включения сервисов: Samba, NFS и планировщики поднимутся со старыми конфигами, и их поведение стоит проверить до возвращения пользователей.
После rollback сделайте одну чистую перезагрузку перед тем, как считать работу завершённой. Процессы, стартовавшие из сломанного корня, после отката продолжают держать в памяти библиотеки и файлы старых версий, и работающий сервис может вести себя непредсказуемо. На openSUSE полезна команда zypper ps: она перечисляет процессы, использующие файлы, удалённые или заменённые последней транзакцией. То же касается веб-панели NAS - перезапустите её службу, иначе интерфейс продолжит показывать состояние до отката.
Если же загрузка не доходит до GRUB, откат выполняют из rescue-окружения: грузитесь с live-носителя, монтируете пул и запускаете snapper --root=/mnt rollback 42, где /mnt это точка монтирования корня. Тот же приём работает, когда NAS вообще грузится только в emergency mode из-за упавшего fsck или проблем с LUKS.
Ручной откат через btrfs subvolume и смену корневого тома когда Snapper не настроен
Debian, Ubuntu и самосборные NAS нередко живут без Snapper, но с ручными снимками. Если перед обновлением был снят снимок командой btrfs subvolume snapshot -r / /snapshots/root-20260510, корень переключается вручную:
mount -o subvolid=5 /dev/sda2 /mnt/btrfs-top
btrfs subvolume get-default /mnt/btrfs-top
btrfs subvolume list /mnt/btrfs-top
btrfs subvolume set-default /mnt/btrfs-top/snapshots/root-20260510
umount /mnt/btrfs-top
reboot
Первая команда монтирует верхний уровень пула, subvolid=5 это его постоянный идентификатор. Вторая показывает, какой subvolume считается корнем сейчас, третья выводит список всех снимков с их ID, четвёртая меняет корень. Никакие файлы при этом не копируются, меняется только указатель, поэтому операция мгновенная. После загрузки проверьте результат командой btrfs subvolume get-default / и только потом удаляйте сломанный subvolume через btrfs subvolume delete, иначе место так и останется занятым.
Если снимка перед обновлением не было, остаётся точечный ремонт: подмонтировать корень из live-системы и вернуть пару сломанных файлов, например конфиг сети, из более старого снимка или из внешнего архива. Каталог /boot с ядром на таких системах обычно лежит внутри корневого subvolume, поэтому вместе с корнем откатывается и ядро. Исключение - отдельный раздел /boot: тогда ядро живёт вне снимка, и ручной откат корня вернёт конфиги, но не вернёт старое ядро, проверьте это по выводу lsblk заранее.
Что пересобрать после отката корня на старый снимок
Откат возвращает файлы, но загрузчик и initramfs работают в связке с ядром, и их пересобирают руками. После загрузки в восстановленный корень выполните:
grub2-mkconfig -o /boot/grub2/grub.cfg
dracut --regenerate-all -f
На системах семейства Debian то же самое делают команды update-grub и update-initramfs -u. Дальше зафиксируйте виновное обновление, чтобы оно не приехало обратно со следующим zypper dup или apt upgrade: удержать пакеты можно через zypper al kernel-default либо apt-mark hold. Проверьте fstab, экспорты Samba и NFS: после отката конфиги станут старыми, а часть пакетов останется обновлённой, расхождение версий библиотек лечится повторным аккуратным обновлением либо переходом на снимок, точно совпадающий с рабочим состоянием.
Отдельный риск - место. Снимки копятся, и после пары неудачных обновлений пул окажется забит старыми состояниями. Команда snapper delete 30-38 уберёт диапазон, а snapper list покажет, кто съел гигабайты. Полезно сразу поднять лимиты очистки в конфиге, например NUMBER_LIMIT="8", чтобы система сама держала историю в разумных рамках. Перед большой чисткой загляните в реальное использование пула: btrfs filesystem df / показывает распределение по типам данных и честнее, чем одна цифра df.
Типичные ошибки при откате NAS на btrfs и как их не повторить
Первая и самая частая ошибка - откат на post-снимок вместо pre. Снимок pre создаётся до транзакции пакетного менеджера, post после неё; возвращать нужно pre, а Description подскажет, какая пара к какому обновлению относится. Вторая - редактирование файлов прямо внутри /.snapshots/42/snapshot: на первый взгляд это быстрый способ подправить конфиг перед откатом, но такие правки теряются при очистке снимка и не попадают в откаченную систему, меняйте файлы в живом корне.
Третья - свободное место. Переполненный btrfs сам по себе капризен: записи падают, снимки не создаются. Перед откатом убедитесь, что на пуле есть хотя бы несколько гигабайт, иначе новая корневая структура не развернётся. Четвёртая - слепая вера в balance: команда btrfs balance без фильтров перетряхивает весь пул и может идти часами, для освобождения места достаточно balance с фильтром -dusage=50. Пятая - забытый второй диск: если /boot зеркалируется или живёт на внешнем носителе, GRUB после отката нужно переустановить на все загрузочные диски, иначе загрузка с запасного диска уедет в старое меню.
Как подготовить NAS к следующему обновлению чтобы откат занимал пять минут
Хороший откат начинается до обновления. Первый шаг - снять снимок вручную, не полагаясь на автоматику:
snapper create -d "snapshot before zypper dup"
btrfs subvolume snapshot -r / /snapshots/root-20260510
Второй шаг - увести копию снимка с самого NAS. Первый раз полный снимок уезжает целиком, дальше достаточно инкрементальных потоков:
btrfs send -p /snapshots/root-20260503 /snapshots/root-20260510 | btrfs receive /mnt/backup
Тогда отказ самого железа не оставит без точки возврата. Третий шаг - обновлять по одному: сначала ядро и перезагрузка, потом сервисы, между шагами проверка шар. Четвёртый - live-носитель с консольными утилитами и записка с командами отката рядом с паролем от IPMI. Раз в месяц полезен btrfs scrub со сверкой результата через btrfs scrub status /: scrub ловит битые блоки, которые в самый неподходящий момент превращают лёгкий откат в долгое восстановление из архива.
Наконец, репетиция. Раз в квартал полезно прогнать откат на копии NAS в виртуальной машине: снять снимок, накатить обновление, откатиться и записать, сколько времени занял каждый шаг. Такая репетиция вскрывает мелочи, о которых в момент аварии вспоминать некогда: отсутствующий live-образ, пароль от IPMI в голове у уволившегося администратора, снимки, отключённые ради экономии места. Пятнадцать минут плановой тренировки стоят дешевле ночи в режиме бедствия: это единственный способ заранее узнать, что копия снимков разворачивается.