среда, 12 марта 2008 г.

unionfs как элемент распределённой FS

Unionfs — это стэковая файловая система. Может сливать содержимое нескольких каталогов, оставляя их физическое содержание обособленным. Возможно любое сочетание ветвей только-для-чтения (ro) и перезаписываемых ветвей (rw), а также вставку и удаление веток на лету.


Задача

Имеем NFS-доступный каталог с дистфайлами (архивами исходников) портов на сервере (обновляется редко). На одной из сетевых машин также имеется каталог /usr/ports/distfiles, в котором находятся более новые версии дистфайлов. Проблема в том, что в серверном NFS-хранилище находится очень много файлов, нужных для сборки всего и вся, они редко изменяют свои версии. А на сетевой машине только то, что она скачала сама из Сети.
Как бы сделать так, чтобы сетевая машина могла использовать не только свои дистфайлы, но и дистфайлы сервера?


Решение

На сетевой машине делаем:

% mount_nfs -o ro server:/usr/ports/distfiles /mnt/server/distfiles
% mount_unionfs -o below /mnt/server/distfiles /usr/ports/distfiles



Таким образом, на сетевой машине мы получили полное дерево портов со всеми дистфайлами. Новые файлы будут сохранятся локально (удобно, если NFS-каталог для нас read-only). Любые изменившиеся файлы в NFS-каталоге будут скопированы в локальное хранилище (/usr/ports/distfiles сетевой машины) с последующим применением изменений. Эти исключения описаны параграфом в mount_unionfs(8).

Стратегия обработки файлов в unionfs такая: сначала поиск ведётся в upper layer (это первый параметр), затем в lower layer (это второй параметр). При удачном поиске в lower layer идёт "теневое зеркалирование" файла на upper layer (без копирования), затем проведение операций открытия файлов и работы с ними. Ключ -o below приводит к инверсии lower layer и upper layer.


Ссылки

"Реализация UnionFS под FreeBSD стала более стабильной"

воскресенье, 2 марта 2008 г.

FreeBSD на USB-флэшке

Сделал загрузочную 1 гиговую USB-флэшку с FreeBSD 7.0, как описано здесь:
http://dreamcatcher.ru/docs/freebsd_stick.html

Материалы

  • Собственно, нужна сама флэшка достаточного объёма.

  • Необходимо переписать ISO-образ (первого) инсталляционного диска FreeBSD.



Подготовка рабочего места

% mkdir -p /mnt/iso9660
% mdconfig -a -f /home/archive/ISO/FreeBSD/7.0-RELEASE-i386-disc1.iso
md0
% mount_cd9660 /dev/md0 /mnt/iso9660
% mkdir -p /media


Подготовка флэшки
Подключенная флэшка определилась как устройство /dev/da0 (это также видно по результату выполнения команды dmesg). Её необходимо разметить и отформатировать.

Разметка выполняется командой:

% fdisk -BI /dev/da0

Но часто приходится использовать диалоговый режим работы fdisk:

% fdisk -i /dev/da0

Дальнейшие действия заключаются в присвоении метки разделу с системой и в проведении форматирования его в UFS2:

% bsdlabel -B -w da0s1
% newfs -U -L FBSDUSB /dev/da0s1a


Установка операционной системы

% mount /dev/da0s1a /media
% set DESTDIR=/media
% cd /mnt/iso9660/7.0-RELEASE/base/
% ./install.sh
% rm /media/boot/kernel
% mv /media/boot/GENERIC /media/boot/kernel


Установка загрузчика операционной системы

% boot0cfg -v -B -o noupdate da0


Конфигурирование
Операционная система на флэшке должна по возможности редко перезаписывать свои файлы, чтобы исключить преждевременное "старение" флэш-памяти. Поэтому временные файлы должны помещаться в оперативной памяти, а не на флэшке.

Файл /media/etc/fstab:

# Device Mountpoint FStype Options Dump Pass#
/dev/ufs/FBSDUSB / ufs rw,noatime 1 1
md /tmp mfs rw,-s160M,nosuid,noatime 0 0
md /var/run mfs rw,-s14M,nosuid,noatime 0 0
md /var/log mfs rw,-s26M,nosuid,noatime 0 0
md /usr/obj mfs rw,-s760M,noatime 0 0
/dev/acd0 /cdrom cd9660 ro,noauto,nosuid 0 0
/proc /proc procfs rw,noauto 0 0
/tmp /var/tmp nullfs rw 0 0


Файл /media/boot/loader.conf:

geom_label_load="YES"

— это форсирует запуск класса GEOM для корректного определения корневой файловой системы на флэшке.

Скрипт восстановления vi
Лично я не пользуюсь vi, но может это кому-то поможет.

% mkdir -p /media/usr/local/etc/rc.d
% cd /media/usr/local/etc/rc.d
% fetch http://people.freebsd.org/~ceri/FreeBSDonUSB/scripts/mkvirecover
% chmod 555 ./mkvirecover

Если возможности загрузить этот скрипт нет, то вот его код (файл mkvirecover):

#!/bin/sh

# PROVIDE: mkvirecover
# REQUIRE: mountcritremote
# BEFORE: DAEMON virecover

. /etc/rc.subr

name="mkvirecover"
stop_cmd=":"
start_cmd="mkvirecover_start"

mkvirecover_start()
{
[ -d /var/tmp/vi.recover ] || mkdir -m 1777 /var/tmp/vi.recover
echo '.'
}

load_rc_config $name
run_rc_command "$1"


В файле /media/etc/newsyslog.conf необходимо отредактировать следующую строчку:

/var/log/wtmp 644 3 * @01T05 BC


Настройка опций системы
Файл /media/etc/rc.conf:

...
ifconfig_DEFAULT="DHCP"
ifconfig_fwe0="NOAUTO"
ifconfig_plip0="NOAUTO"
...
— сетевая операционная система получает свой IP-адрес от внешнего DHCP-сервера.

Для уменьшения числа операций записи на USB, нужно создать локальную базу данных и запретить еженедельное обновление:

% chroot /media /bin/sh
# mount_devfs devfs /dev
# /etc/periodic/weekly/310.locate
# cat >> /etc/periodic.conf << EOF
weekly_locate_enable="NO"
weekly_whatis_enable="NO"
EOF

Задание пароля root и установка прикладного ПО из бинарных пакетов и т.д.:

# passwd root
...
# pkg_add -r unzip unrar xorg...
...
# umount devfs
# exit
% cd /root
% umount /media
% umount /mnt/iso9660


В общем, система подготовлена для работы с флэшки.

Для установки прикладного ПО из портов, а не из бинарных пакетов необходимо выделить достаточно места на флэшке: возможно придётся удалить каталог /usr/src; отказаться от размещения локальной копии дерева портов — вместо этого подключить расшаренный в NFS каталог /usr/ports другой машины и/или использовать технологию unionfs с внешним носителем. Необходимо также предварительно определить переменную WRKDIRPREFIX=/usr/obj в файле /etc/make.conf при достаточном объёме RAM-диска, выделенного под /usr/obj (осторожно: некоторые порты для своей компиляции требуют более 2ГБ свободного пространства).