понедельник, 22 августа 2011 г.

Не нужно апгрейдить ZFS root pool!

Недавно мне довелось нарваться на совершенно феерическую засаду с обновлениями Solaris. История вышла более, чем поучительная. Как известно, я люблю ставить сервера в режим необслуживания. То есть вывешивать все рутинные задачи в cron и спокойно заниматься своими делами, время от времени получая по почте уведомления о выполнении этих самых рутинных задач.

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

Один из серверов обновлялся по регулярному графику, раз в месяц. Прошла группа обновлений. И тут мне пришло в голову заглянуть на его дисковую систему. Первое, что кинулось в глаза:

root @ hostname / # zpool status rpool
pool: rpool
state: ONLINE
status: The pool is formatted using an older on-disk format. The pool can
still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'. Once this is done, the
pool will no longer be accessible on older software versions.
scan: scrub repaired 0 in 0h5m with 0 errors on Sat Aug 20 06:05:03 2011
config:

NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
c1t0d0s0 ONLINE 0 0 0
c1t1d0s0 ONLINE 0 0 0

errors: No known data errors


"Ого!" - сказали мужики. Непорядок. Надо обновить. Сделал, как сказано. И оставил все на своих местах.

И тут, пару недель спустя, пришла пора другого обновления. Обновление прошло, надо перезагрузиться. Перезагружаю сервер. Упс! Не стартует. Вылетает в меню GRUB и ни шагу дальше. Нет кернела. То есть как нет кернела?!

Первое и естественное действие - взять дистрибутивный DVD и стартовать с него в single user shell. Опачки - не видит установленной ОС. Совсем.

Хорошо, импортирую пулы. Пулы не импортируются. Сообщение об ошибке - "Файловая система слишком новой версии и не может быть импортирована".

Все страньше и страньше. Окей, беру LiveUSB Solaris 11. Гружусь. Импортирую пулы. Пулы импортируются. Однако теперь формат ZFS слишком старый. Заглядываю в импортированный корневой пул. Вижу только /boot и /etc. Причем /etc какой-то не полный. zfs list показывает все компоненты корневого пула, заполнение правильное, все на месте - swap, dump, var. Но в точке монтирования кроме двух указанных директорий ничего.

Смотрю версии пулов. Версия пула на дисках 29. Версия пула Solaris 11 - 31я. Версия пулов в дистрибутиве (9/10) - 22. В голову приходит, что апгрейд до 31 версии приведет к тому, что ни туда ни сюда - диски уже не увидятся системой. В дистрибутиве версия пулов уже слишком старая. В 11й - слишком новая. Файлсэйф тоже, разумеется, не стартует. 

Приходит мысль, что при обновлении каким-то образом потерялся загрузчик. Записываю GRUB заново на оба диска с Solaris 11. Перезагрузка. Система наконец выводит меню загрузки..... стартует ядро.... паника, рестарт. Снова загрузка, старт ядра, паника, рестарт.

"Ага!" - сказали мужики. Выхода нет, надо восстанавливаться. Бэкап, восстановление, разбор полетов.

Итак, обновление ядра 144501-19. Меняется on-disk format ZFS. Первое и естественное желание - воспользоваться новыми фишками и апгрейдить ФС. Так вот, делать этого на корневом пуле НЕ НУЖНО.

Первое. В ZFS не существует даунгрейда.
Второе. В ZFS нет обратной совместимости дисковых форматов.
Третье. Корневой пул апгрейдить нельзя. После перезапуска в данной версии ядра слетает загрузчик, кроме того, дистрибутив новый пул уже не увидит и восстановить загрузку не получится никак. Только физический бэкап спасет гигантов мысли.

Как было сказано в одном саппортном документе, не обновляйте корневой пул - пусть это сделает Oracle (вольный перевод). Лучше всего выполнять обновление корневого пула - с выходом нового релиза ОС, и не раньше. Дабы можно было его увидеть в случае чего, стартовав с дистрибутивного образа.

Мораль этой истории проста. Don't be in such a hurry - Горячки не порите.