2018-04-22

Замена диска FreeNAS

Имеем: FreeNAS 9.0 + raidz / zfs + geli шифрование.
Один из дисков массива начал серьёзно сбоить.
Ещё один на очереди - но пока тфу-тфу-тфу.
Потребовалось заменить диск с пониманием того, что вводится и зачем это делается.
Из коробки через веб интерфейс не получилось правильно добавить новый диск в массив.
Может оно и можно, но как-то страшненько стало потерять весь массив.
Пошаговая инструкция для себя - ну может кому ещё понадобится.

Итак.

1. Находим отказавший винт и заменяем его новым.
Оказалось не так просто - WD Green просто не имеют лампочки активности (внезапно).
Решение: Получил через smartctl -a /dev/{ada3} серийный номер и вытаскивая винты один за другим искал его по этикеткам.
Предложение: записать сразу серийные номера дисков в корзине до их монтажа и прилепить на бумажке. Индикация активности есть в разъёме питания (pin 11) но нужно тоже как-то дорабатывать.

2. Логинимся на сервер и размечаем диск в GPT.
Этот этап сделался "сам" через графический интерфейс пока ковырялся с попытками замены через gui.
Делается элементарно командой:
gpart create -s GPT {ada1}
3. Разбираемся с шифрованием.
Надо зашифровать новый диск в системе geli теми же ключами и паролем, что и остальной массив.
Тут нужно понимать следующие вещи.
Основные настройки FreeNAS лежат в sqlite3 базе данных /data/freenas-v1.db
Посмотрите из консоли содержимое таблиц:
sqlite3 /data/freenas-v1.db .dump storage_%
Файлы ключей защищены паролем и лежат в папке: /data/geli/{KEY-GUID}.key
{KEY-GUID} можно посмотреть в табличке: storage_volume

Системное шифрование FreeBSD управляется утилитой geli
Диски для монтирования берут в папке: /dev/gptid/{GUID}
И перечислены в табличке: storage_encrypteddisk

3.1. Создаём файлик {passfile} например в папке /tmp с паролем на массив (иначе придётся вводить его много-много раз).
Заходим в папку /dev (чтобы автодополнение GUID работало).
3.2. Для нового диска инициализируем:
geli init -K /data/geli/{KEY-GUID}.key -J {pass-file} gptid/{GUID}

PS: Ключ -b указывать не нужно, иначе у раздела появится флаг BOOT и он будет требовать ввода пароля при загрузке. Чтобы снять флаг, если его поставили: geli config -B gptid/{GUID}
3.2. Подключаем все шифрованные диски, последовательно для всех имеющихся:
geli attach -k /data/geli/{KEY-GUID}.key -j {pass-file} gptid/{GUID}
Появятся расшифрованные диски: /dev/gptid/{GUID}.eli

4. Добавляем в таблицу настроек (см. п.3) упоминания о шифровании диска:
sqlite3 /data/freenas-v1.db
INSERT INTO "storage_encrypteddisk" VALUES(1,{seq-num},'gptid/{guid}',{disk-id});
{disk-id} можно посмотреть в таблице storage_disk

5. Запускаем zpool:
zpool import {poolname}
Если сбоит монтирование из-за readonly файловой системы:
zfs set mountpoint=/mnt/Pool Pool
zfs mount -a
6. Добавляем запасной диск:
zpool add spare {Pool} gptid/{newgid}.eli
(PS: не нужно, можно сразу делать replace)
Смотрим состояние массива:
zpool status
и заменяем отказавший:
zpool replace {Pool} {dead-id} gptid/{newgid}.eli
Ждём окончания ресильверинга (можно сразу после загрузки zpool в п. 5) удаляем ненужное:
zpool detach {Pool} {dead-id}