Создание "правильной" геометрии диска.
В результате чтения, экспериментов, проб и ошибок "родился" скрипт bsdinstall.sh, который привожу без комментариев, и только потому, что на нем основано восстановление и на него идут ссылки.
Используемое "железо".
оборудование
|
характеристика
|
CPU
|
DualCore Intel Celeron G540; 2500 MHz (25 x 100)
|
MB
|
Asus P8H61-M LX (3 PCI-E x1; 1 PCI-E x16; 2 DDR3 DIMM; Audio; Video; Gigabit LAN) (Intel Cougar Point H61; Intel Sandy Bridge)
|
VIDEO
|
Intel(R) HD Graphics 2500
|
RAM
|
2G (DDR3-1333 DDR3 SDRAM Kingston 9905474-012.A00LF)
|
HDD
|
WDC WD5000AAKX-001CA0 (500 Гб; SATA II)
|
LAN
|
Realtek PCIe GBE Family Controller (Onboard) (Realtek RTL8111E chip)
|
|
Подготовка загрузочного носителя.
Для установки системы и для восстановления использовалась флешка (на самом деле картридер и карта microSD). На Windows XP делаем загрузочную флешку из img образа FreeBSD-9.1-RELEASE-amd64-memstick.img при помощи dd for windows.
Вставляем флешку в компьютер, определяем диск с флешкой командой:
У меня это был диск 2:
...
\\?\Device\Harddisk2\Partition0
link to \\?\Device\Harddisk2\DR74
Removable media other than floppy. Block size = 512
size is 15808331776 bytes
...
|
Выполняем, соответственно, команду создания флешки, указав нужный диск:
>dd if=FreeBSD-9.1-RELEASE-amd64-memstick.img \
of=\\?\Device\Harddisk2\Partition0 bs=2M --progress
^
|
Естественно, все это можно сделать той же dd из под любой *nix системы.
Естественно, можно пойти по классическому пути, затянув ISO образ и закатав его на DVD (или даже CD) матрицу и использовать этот диск при установке и/или восстановлении системы.
Процедура резервного копирования.
По мотивам: Full system backups for FreeBSD systems using ZFS и dump/restore.
Обеспечиваем доступ к ftp серверу. В моем случае по адресу 192.168.1.19 на сервере под управлением MS Windows 2003 R2 создан в IIS узел ftp на порту 8022 с полным доступом для учетной записи proxy3 c паролем proxy3 и резервом дискового пространства порядка 50G.
Создаем на резервируемой системе каталог, например "\usr\home\teg\CONFIG\BACKUP\" и в нем файлы "backup_restore_910.txt" (с этим руководством по восстановлению) и выполняемый файл скрипта "backup.sh".
#!/bin/sh
# резервное копирование
#имя пула
poolname='tank'
#дата и время
DATE=`date +%Y.%m.%d_%H%M`
#Делаем рекурсивный снапшот пула с корня
zfs snapshot -r ${poolname}@${DATE}
#рисуем результат
zfs list -t snapshot
ftpkeys="-i -a -A -P 8022"
usr="proxy3"
pass=${usr}
ftpsrv="192.168.1.19"
#отправляем руководство по восстановлению на сервер
cp backup_restore_910.txt fb910.${poolname}.${DATE}.backup.txt
ftp -i -A -P 8022 -u ftp://${usr}:${pass}@${ftpsrv}/ \
fb910.${poolname}.${DATE}.backup.txt
rm fb910.${poolname}.${DATE}.backup.txt
#отправляем загрузчик и загрузочную область на сервер
cp /boot/pmbr fb910.${poolname}.${DATE}.pmbr
cp /boot/gptzfsboot fb910.${poolname}.${DATE}.gptzfsboot
ftp -i -A -P 8022 -u ftp://${usr}:${pass}@${ftpsrv}/ \
fb910.${poolname}.${DATE}.pmbr
ftp -i -A -P 8022 -u ftp://${usr}:${pass}@${ftpsrv}/ \
fb910.${poolname}.${DATE}.gptzfsboot
rm fb910.${poolname}.${DATE}.pmbr
rm fb910.${poolname}.${DATE}.gptzfsboot
#Вариант полный, с запаковкой, медленный
#1160334296 bytes sent in 18:26 (1.00 MiB/s)
#Тут узкое место по времени - процесс сжатия,
#можно попробовать сжимать с меньшей эффективностью,
#но не вижу пока необходимости.
zfs send -R ${poolname}@${DATE} | gzip -9 | ftp ${ftpkeys} -u \
ftp://${usr}:${pass}@${ftpsrv}/fb910.${poolname}.${DATE}.img.gz -
echo "------- end send snapshot '${poolname}.${DATE}', sleep 4c ----"
#Вариант полный, без запаковки, быстрый
#4814869016 bytes sent in 01:07 (68.14 MiB/s)
#zfs send -R ${poolname}@${DATE} | ftp ${ftpkeys} -u \
# ftp://${usr}:${pass}@${ftpsrv}/fb910.${poolname}.${DATE}.img -
#echo "------- end send snapshot '${poolname}.${DATE}', sleep 4c ----"
sleep 4
echo ' '
#удаляем снапшот
zfs destroy -r ${poolname}@${DATE}
|
Запуск скрипта позволяет создать файлы резервной копии сразу на другом компьютере.
Естественно, никто не запрещает Вам выполнять резервное копирование не на ftp, а, на другой жесткий диск, или, скажем, на флешку.
Процедура тестового восстановления.
По тем же мотивам: Full system backups for FreeBSD systems using ZFS и dump/restore.
1 Делаем флешку для загрузки.
2 Выполняем бакап системы. Получаем файлы:
ftp://proxy3@192.168.1.19:8022/fb910.tank.2012.11.01_1735.img.gz
ftp://proxy3@192.168.1.19:8022/fb910.tank.2012.11.01_1735.pmbr
ftp://proxy3@192.168.1.19:8022/fb910.tank.2012.11.01_1735.gptzfsboot
|
3 Гасим восстанавливаемый компьютер:
4 Берем другой компьютер, поддерживающий 64 битные инструкции (amd64). У меня была машина в следующей конфигурации:
оборудование
|
характеристика
|
CPU
|
DualCore Intel Pentium E2180; 2017 MHz (10 x 202)
|
MB
|
MSI 945GCM7 (MS-7507) (2 PCI; 1 PCI-E x1; 1 PCI-E x16; 2 DDR2 DIMM; Audio; Videol; LAN) (Intel Lakeport-G i945GC)
|
VIDEO
|
Intel(R) 82945G Express Chipset Family (128 Мб) Intel GMA 950
|
RAM
|
1G (2x512 Мб DDR2-667 DDR2 SDRAM)
|
HDD
|
ST330013A (30 Гб; 7200 RPM; Ultra-ATA/100)
|
LAN
|
Realtek RTL8168C(P)/8111C(P) PCI-E Gigabit Ethernet NIC
|
|
Небольшое лирическое отступление или как избежать ловушек.
Конфигурация оригинального компьютера, на котором я разворачивал систему,
описана выше, в разделе Используемое "железо".
При установке системы сетевой контроллер с чипом "Realtek RTL8111E" не корректно работал, хоть и идентифицировался системой. Помогла замена драйвера на "родной" от Realtek для Freebsd. На сайте Realtek, точнее HOME > Downloads > Communications Network ICs > Network Interface Controllers > 10/100/1000M Gigabit Ethernet > PCI Express > Software забрал архив для "FreeBSD 7.x and 8.0 1.81 2012/11/16 56k". Установку провел в соответствии с рекомендациями файла "rtl_bsd_drv\Readme.txt" из этого архива по "Методу 2" с последующим переходом к "Методу 1".
После замены драйвера сеть заработала. Мне нужны были два разных сетевых интерфейса в системе. Сетевых карт разных у меня есть в запасе, но ни одной для шины PCI-E, а других интерфейсов в бюджетной материнской плате "Asus P8H61-M LX" не предусмотрено. Поэтому я прикупил сетевую карту с шиной PCI-E "TP-Link TG-3468" на чипе "Realtek RTL8168E". Она обнаружилась в системе как устройство re и была подхвачена и корректно работала, и только благодаря обновленному драйверу.
Теперь представьте ситуацию, на оригинальном компьютере "умер" HDD. Берем другой HDD, подключаем в тот же компьютер, и, если выполнять восстановление через сеть, то, естественно, ничего не получиться. Потому что грузимся мы с флешки, а там драйвер от Freebsd, он не поймет ни первую ни вторю сетевую. Поэтому - либо вручную подменять драйвер (честно говоря я пока не заню как это корректно сделать), либо восстанавливаться не по сети а с флешки или другого носителя (HDD), Соответственно, необходимо внести изменения в скрипт "bsdrestor.sh". Еще как вариант, найти внешнюю сетевую карту PCI-E, которая поддерживается "голой" системой Freebsd c флешки.
5 Грузимся с флешки. Заходим в "Shell", смотрим, если ли на новом винте разделы:
Если есть, то все разделы удаляем, например на ada0:
Если диск ранее использовался, то, как пишут, имеет смысл затереть несколько первых мегабайт диска, например:
# dd if=/dev/zero of=/dev/ada0 bs=1M count=2048
|
6 Подготавливаем скрипт формирования файловой системы после бакапа на другом компьютере. Можно сделать и на восстанавливаемом. Готовый вариант скрипта в файле bsdrestor.sh. Этот файл необходимо отредактировать, в начале, в части переменных. Фактически это адаптация скрипта разметки диска под ZFS и установки системы. Этот скрипт обрезан до строки
zfs set checksum=fletcher4 $tank"
|
Вместо группы команд "zfs create ..." введены команды настройки сети и восстановления пула из архива. Расширены возможности настройки, в начале, в заголовке. Наиболее важные:
Имя устройства:
Строка даты и времени резервной копии, необходима для определения имен файлов для восстановления:
backup_f="2012.11.01_1735"
|
Имя сетевого интерфейса:
И еще другие, достаточно, на мой взгляд, прокомментированные параметры-переменные.
По окончании редактирования необходимо скопировать подготовленный скрипт на ДРУГУЮ флешку, в корень.
Привожу весь тест скрипта. А вот для работы файл bsdrestor.sh лучше затянуть, т.к. эта "экранная" версия, она снабжена переводами строк, для читабельности.
#!/bin/sh
# Переменные
# Перед выполнением проверить и отредактировать!
# Имя диска (устройства)
dev=ada0
# Имя создаваемого пула
tank=tank
# имя сетевого интерфейса
if_lan=re0
# адрес хоста на момент восстановления
ip_host="192.168.1.79"
# адрес шлюза
ip_gw="192.168.1.1"
# адрес ftp сервера c файлами восстановления
ip_ftp="192.168.1.19"
# порт ftp сервера c файлами восстановления
port_ftp="8022"
# логин и пароль ftp сервера c файлами восстановления
usr="proxy3"
pass=${usr}
# Строка даты и времени резервной копии
backup_data="2012.11.01_1735"
# ================= Расcчитываемыt занчения, для, справки =====================
# имя файла-архива с запакованным пулом
backup_f="fb910.tank.${backup_data}.img.gz"
# имя резервных копий файлов загрузчиков
backup_gptzfsboot="fb910.tank.${backup_data}.gptzfsboot"
backup_pmbr="fb910.tank.${backup_data}.pmbr"
### =============== Разбивка диска, для, справки ==============================
# Два примера рачета длинны 3-го оновного раздела, ZFS
# Cам расчет проводится автоматически самим скриптом
###
# скрипт делает такую разметку:
# 34 - 6 - free -
# 40 - 1024 1 freebsd-boot boot0
# 1064 - 984 - free -
# 2048 - 8388608 2 freebsd-swap
# 8390656 - xxxxxxxxx 3 freebsd-zfs
# xxxxxxxxx - xx - free -
# Пример 1
# 80G винт, блоков 156299308, начиная с 34.
# т.е. всего 156299308+34=156299342 блоков
# на раздел freebsd-zfs можно выделить
# 156299342-8390656=147908686 блоков,
# 147908686/8=18488585.75, т.е. 6 блоков в конце лишние,
# итого длинна "основного", 3-го, раздела,
# c учетом выравнивания по 4К (8 блоков)
# составит 147908686-6=147908680 блоков
#blk_long=147908680
# Пример 2
# 500G винт, блоков 976770988, начиная с 34.
# т.е. всего 976770988+34=976771022 блоков
# на раздел freebsd-zfs можно выделить
# 976771022-8390656=968380366 блоков,
# 968380366/8=121047545.75, т.е. 6 блоков в конце лишние,
# итого длинна "основного", 3-го, раздела,
# c учетом выравнивания по 4К (8 блоков)
# составит 968380366-6=968380360 блоков
#blk_long=968380360
# =========== Тело скрипта ===================================================
echo "script: Create GPT, add partitions..."
gpart create -s gpt $dev
echo "script: add freebsd-boot partition boot0"
gpart add -b 40 -s 1024 -t freebsd-boot -l boot0 ${dev}
echo "script: add freebsd-swap partition swap0"
gpart add -b 2048 -s 4G -t freebsd-swap -l swap0 ${dev}
####
# Рассчет длинны 3 го, основного раздела, ZFS
####
# Начальный блок и длинна в блоках всего устройства (диска)
blk_begin=`gpart show ${dev} | grep '=>' | awk '{a = $2; print a}'`
echo "script: blk_begin=${blk_begin}"
blk_end=`gpart show ${dev} | grep '=>' | awk '{a = $3; print a}'`
echo "script: blk_end=${blk_end}"
# Начальный блок и длинна в блоках раздела (freebsd-swap)
blk_swop_begin=`gpart show ${dev} | grep 'freebsd-swap' | \
awk '{a = $1; print a}'`
echo "script: blk_swop_begin=${blk_swop_begin}"
blk_swop_end=`gpart show ${dev} | grep 'freebsd-swap' | \
awk '{a = $2; print a}'`
echo "script: blk_swop_end=${blk_swop_end}"
# Начальный блок раздела ZFS
blk_zfs_begin=$((${blk_swop_begin} + ${blk_swop_end}))
echo "script: blk_zfs_begin=${blk_zfs_begin}"
# Искомая длинна в блоках раздела ZFS с учетом кратности 8 блокам (4K)
blk_long=$(( (((${blk_begin}+${blk_end})-${blk_zfs_begin})/8)*8 ))
echo "script: blk_long=${blk_long}"
echo "script: add freebsd-zfs partition data0, long is ${blk_long} blocks"
gpart add -s ${blk_long} -t freebsd-zfs -l data0 ${dev}
echo " "
echo "script: GPT on $dev created, partitions added."
echo " "
sleep 5
# Настраиваем сеть
ifconfig ${if_lan} inet ${ip_host} netmask 255.255.255.0
# Пропишем шлюз по умолчанию команда route:
route add default ${ip_gw}
#Обязательно задержка, а то сразу сеть не поднимается!
sleep 10
#Загружаем с FTP серевера резервные копии загрузчиков
# /boot/pmbr и /boot/gptzfsboot
#ftp -i -A -P 8022 -o /tmp/gptzfsboot \
# ftp://proxy3:proxy3@192.168.1.19/fb910.tank.2012.11.01_1735.gptzfsboot
#ftp -i -A -P 8022 -o /tmp/pmbr \
# ftp://proxy3:proxy3@192.168.1.19/fb910.tank.2012.11.01_1735.pmbr
echo "script: Download backup boot records from ftp start...."
ftp -i -A -P ${port_ftp} -o /tmp/gptzfsboot \
ftp://${usr}:${pass}@${ip_ftp}/${backup_gptzfsboot}
ftp -i -A -P ${port_ftp} -o /tmp/pmbr \
ftp://${usr}:${pass}@${ip_ftp}/${backup_pmbr}
# Записываем загрузчик в загрузочную область.
# Корректно делать резервную копию /boot/pmbr и /boot/gptzfsboot
# с последующим восстанавлением из нее, а не а не с того,
# что подвернеться на загрузочной флешке.
# Это нужно, чтобы загрузчик совпадал с загрузчиком исходной системы
# Поэтому вместо
#gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ${dev}
# пишем:
gpart bootcode -b /tmp/pmbr -p /tmp/gptzfsboot -i 1 ${dev}
gpart show ${dev}
sleep 3
gpart show -l ${dev}
sleep 5
# Create ZFS pool
echo "script: Create ZFS pool..."
# Работаем над обеспечением геометрии с 4K
gnop create -S 4096 /dev/gpt/data0
zpool create -f -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache ${tank} \
/dev/gpt/data0.nop
zpool export ${tank}
gnop destroy /dev/gpt/data0.nop
mkdir /tmp/${tank}
zpool import -o altroot=/tmp/${tank} -o cachefile=/var/tmp/zpool.cache ${tank}
# указываем, что пул загрузочный
zpool set bootfs=${tank} ${tank}
sleep 3
# Create ZFS-filesystem
echo "script: Create filesystem..."
# ну зачем же? для быстродействия синтетического теста? За уши?
#zfs set atime=off ${tank}
# Включаем контрольные суммы посерьезнее.
zfs set checksum=fletcher4 $tank
########################
# А так получаем нужный нам поток:
# ftp -i -A -P 8022 -o - \
# ftp://proxy3:proxy3@192.168.1.19/fb910.tank.2012.11.01_1735.img.gz
# С распаковкой и передачей на вход zfs:
# ftp -i -A -P 8022 -o - \
# ftp://proxy3:proxy3@192.168.1.19/fb910.tank.2012.11.01_1735.img.gz | \
# gzip -d -с | zfs receive -vF -d tank
# итого с учетом переменных для возможности настройки:
echo "script: Receive system from ftp start...."
ftp -i -A -P ${port_ftp} -o - ftp://${usr}:${pass}@${ip_ftp}/${backup_f} | \
gzip -d -c | zfs receive -vF -d ${tank}
echo "script: Receive system from ftp finish"
sleep 5
# вообще это лишнее, но не мешает
mkdir /tmp/root
# что бы добраться до результирующего "/boot/zfs/zpool.cache"
# приходится стучать в бубен
zfs set mountpoint=/tmp/root ${tank}
# то же лишнее
cd /tmp
zpool export ${tank}
zpool import -o altroot=/tmp/${tank} -o cachefile=/var/tmp/zpool.cache ${tank}
echo "script: Copy zpool cache..."
# Копируем zpool.cache на своё место.
# Только не пропустите этот шаг, были случаи )
# Сей чудовый путь забавен, но логически верен. Проверено.
# И запись выше "mkdir /tmp/root" вообще лишняя
cp /var/tmp/zpool.cache /tmp/tank/tmp/root/boot/zfs/zpool.cache
# отмотируем все это безобразие
zfs unmount -af
# вернем пул в корень
zfs set mountpoint=legacy ${tank}
echo "script: done!"
echo "enter please command 'reboot'"
|
7 Смотрим список устройств:
Вставляем вторую флешку, со скриптом, в восстанавливаемый компьютер. По сообщениям на консоли определяем устройство флешки, уточняем раздел устройства для монтирования:
Монтируем раздел флешки, например:
# mount_msdosfs /dev/da1s1 /mnt
|
У меня вторая флешка была размечена в NTFS, а не в FAT, поэтому вместо "mount_msdosfs" я писал "mount_ntfs". У вас может быть не "/dev/da1s1", а, например, "/dev/da0s1", если вы грузитесь не с флешки, а с DVD/CD. Или другое имя устройства. Копируем файл скрипта в "/tmp":
# cp /mnt/bsdrestor.sh /tmp
|
Обязательно отмонтируем флешку, т.к. скрипт использует точку монтирования "/mnt":
Выполняем скрипт:
Процедура восстановления, на гигабитной сети, бакапа почти голой системы, которая в запакованном виде "весит" 1.2G (в распакованном - 4.7G), длиться около 5 минут. По окончании работы скрипт просит ввести "Reboot". Но, перед перезагрузкой, следует внимательно просмотреть вывод сообщений на предмет ошибок. Если ничего не нашли, то перегружаемся, заходим под пользователем с группой whell или под root и смотрим файловую систему:
Видим - остался тот самый снапшот "tank@2012.11.01_1735", с которого мы делали бакап. Удаляем его за ненадобностью:
% sudo zfs destroy -r tank@2012.11.01_1735
|
Для проверки целостности системы я еще выполнил команду
и через какое то время в ответ на команду
получил "хороший" ответ:
pool: tank
state: ONLINE
scan: scrub repaired 0 in 0h7m with 0 errors on Fri Dec 21 14:03:06 2012
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
gpt/data0 ONLINE 0 0 0
errors: No known data errors
|
Будем считать задачу выполненной.
Окончание или история болезни.
Комментарии пользователей [1 шт.]