RFC (Request for Comments, Запрос на комментарии) - серия документов, публикуемая сообществом исследователей и разработчиков, руководствующихся практическими интересами, в которой описывается набор протоколов и обобщается опыт функционирования Интернет.
Использование для загрузки FreeBSD сжатой файловой системы - geom_uzip [2008]
Данный текст появился из моих развлечений, по работе - надо было сделать загрузочную флэшку, которая после загрузки задавала пару тупых вопросов, после чего разбивала диск, разворачивала сервер филиала, втыкала в его в виндовый домен и меняла все данные в конфигах. Даннаязадача трудностей не вызывала, были одни крупные грабли - при разворачивании и генерации файла fstab, нужно было определить имя диска с которым работаем. Поэтому, пришлось изгаляться с запихиванием содержимого флэшки на диск в оперативке. Ну, а в процессе запихивания родилось пару хороших идей по применению сделанному. Одна из них - тонкие клиенты - когда-то я такое делал на FreeBSD4.11 - надо было по работе, ну а теперь для развлечения повторю на 6.2 - просто чтобы не забыть, что можно и как сделать.
Для начала, читаем man по mdconfig, и следуем последнему примеру, в этом мане. Делаем файлик состоящий из нулей:
/usr/home/lissyara/>dd if=/dev/zero of=mfs_root.md bs=1m count=512 512+0 records in 512+0 records out 536870912 bytes transferred in 14.831406 secs (36198248 bytes/sec) /usr/home/lissyara/>
Собираем и устанавливаем мир, с указанием директории назначения - наш диск в памяти:
[cpde=shell]make world DESTDIR=/usr/home/lissyara/mfs && \ ? cd /usr/src/etc && make distribution DESTDIR=/usr/home/lissyara/mfs [/code] После установки, смотрим чё получилось: ussr% df -h | grep md /dev/md4a 496M 150M 307M 33% /usr/home /lissyara/mfs ussr%
Занято 150 мегов. Неплохо - мы имеем полноценную систему, но ещё надо установить софт - иксы и прочия. Собирать на этом диске - нету никакого желания и времени, поэтому воспользуюсь софтом установленным на моей машине - благо, у меня всё что необходимо уже установлено. Для этого, создаём директорию, и в ней сохраняем все пакеты:
ussr% cd /usr/home/lissyara/ ussr% mkdir pkgs ussr% cd pkgs ussr% foreach pkg ( `ls /var/db/pkg/` ) foreach? pkg_create -b $pkg & foreach? end
Можно идти курить. На моём двухядрёном AMD, с гигом памяти, это заняло минут 20 (для 600 с копейками установленных пакетов). После создания всех пакетов, монтируем директорию с ними, в директорию внутри диска в файле. Для этого, юзаем nullfs:
После чего топаем внутрь диска в файле, как в jail - будем ставить пакеты:
ussr% jail /usr/home/lissyara/mfs ThinClients 1.1.1.1 /bin/csh ThinClients# ThinClients# df -h Filesystem Size Used Avail Capacity Mounted on /dev/md4a 496M 150M 307M 33% / ThinClients# cd /mnt/ ThinClients# ls | wc -l 601 ThinClients#
Ставим пакеты:
ThinClients# pkg_add rdesktop-1.5.0_2.tbz Running fc-cache to build fontconfig cache... /usr/local/lib/X11/fonts: caching, 0 fonts, 1 dirs /usr/local/lib/X11/fonts/local: caching, 0 fonts, 0 dirs /root/.fonts: skipping, no such directory /var/db/fontconfig: cleaning cache directory /root/.fontconfig: not cleaning unwritable cache directory fc-cache: succeeded Spamming files in /etc... ==> Removing /usr/X11R6/etc/periodic from periodic setup... ==> Removing /usr/X11R6/man from MANPATH... ==> Removing /usr/X11R6 from rc sequence... ThinClients# ThinClients# pkg_add xorg-server-1.2.0_2,1.tbz ThinClients# pkg_add xorg-drivers-7.2.tbz xorg-apps-7.2.tbz xorg-fonts-7.2.tbz ThinClients# df -h Filesystem Size Used Avail Capacity Mounted on /dev/md4a 496M 259M 197M 57% / ThinClients# pkg_info | wc -l 270 ThinClients# exit
Мдя... прилично... Однако, попробуем сжать всё это хозяйство, и посмотрим что будет на выходе. Ждя этого заюзаем утилиту mkuzip - она позволяет сжимать образы файловых систем, и, в дальнейшем, эти сжатые образы можно втюхать лоадеру, который их загрузит в память. Ну, а дальше - ядро будет использовать софт с этого диска. Сжимаем, предварительно отмонтировав, и отключив диск - при проблемах на отмонтировании/отключении - можно перезагрузиться:
Неплохо. Сжалось вдвое. Хотя, я рассчитывал на лучший результат - ибо в 128 мегов памяти, и тем более в 64 - ну никак не вписываемся. Поэтому, пробовать грузиться с этого я даже не стал, а полез изучать маны - с целью ужать всё что можно и удалить ненужное. Для начала, изучаем man make.conf, и добавляем в файл /etc/make.conf такие строки:
После чего повторяем набор действий по созданию диска в памяти, и инсталляции на него системы. Тока диск делаем вдвое меньше:
ussr% dd if=/dev/zero of=/usr/home/lissyara/mfs_root_v2.md bs=1m count=256 256+0 records in 256+0 records out 268435456 bytes transferred in 7.642607 secs (35123546 bytes/sec) ussr% mdconfig -a -t vnode -f mfs_root_v2.md -u 4 ussr% bsdlabel -w md4 auto ussr% newfs md4a /dev/md4a: 256.0MB (524272 sectors) block size 16384, fragment size 2048 using 4 cylinder groups of 64.00MB, 4096 blks, 8192 inodes. super-block backups (for fsck -b #) at: 160, 131232, 262304, 393376 ussr% mount /dev/md4a /usr/home/lissyara/mfs ussr% ussr% df -h | grep md /dev/md4a 248M 4.0K 228M 0% /usr/home/lissyara/mfs ussr% ussr% make world DESTDIR=/usr/home/lissyara/mfs && \ ? cd /usr/src/etc && make distribution DESTDIR=/usr/home/lissyara/mfs ......... skipped .......... ussr% df -h | grep md /dev/md4a 248M 43M 185M 19% /usr/home/lissyara/mfs ussr%
Результат неплох - меньше в 3.5 раза, и ещё ничё не пилили руками - тока штатные средства. Ну а дальше началось интересное, что я уже не документировал - ручная установка пакетов, доустановка файлов без которых не запускался rdesktop (NO_CRYPT=yes - оказалась плохая идея :)) удаление файлов, которые не нужны (почти всё в share и local/share), ненужных зависимостей и прочего. Честно говоря - сильно не изгалялся, но на выходе, уже к третьей версии, имел такое:
Осталось, рассмотреть запуск всего этого хозяйства. Вот тут меня ждали грабли - как загрузить образ, вопросов не возникало - в /boot/defaults/loader.conf есть примеры, и в моём случае это выглядело так:
ussr% more boot/loader.conf # uzip module geom_uzip_load="YES" # MFS image load mfsroot_load="YES" mfsroot_type="mfs_root" # file compressed file system mfsroot_name="/boot/mfs_root.md.uzip" # other boot options autoboot_delay="3" loader_logo="beastie"
Однако, даже определив имя устройства - /dev/md0.uzipa, мне не удалось его подмонтировать - точка, в fstab, считается спецсимволом. Экранировать тоже никак не удалось. Финиш...
Вначале я было потерялся, потом вспомнил, что когда перводил /boot/defaults/loader.conf, видел чё то на эту тему. Оказалось, да - есть опция:
# where root FS vfs.root.mountfrom="ufs:md0.uzipa"
С ней, удалось загрузиться с устройства. Однако, тут были новые грабли - ввиду того, что файловая система доступна только для чтения, фряха вываливалась в однопользовательский режим. Порывшись в ещё одном дефолтовом конфигурационном файле - /etc/defaults/rc.conf - нашёл соответстствующую опцию, и на выходе получил /etc/rc.conf такого состава:
ussr% more etc/rc.conf # added by xorg-libraries port local_startup="/usr/local/etc/rc.d" #moused_enable="YES" #moused_port="/dev/ums0"
# filesystems in memory varmfs="YES" varsize="4m" tmpmfs="YES" tmpsize="2m"
# for root_fs read-only mount root_rw_mount="NO"
# list network interfaces # ls /boot/kernel/ | grep if | awk -F '.' '{print $1}' | awk -F '_' '{print $2}' interface_array="an ar arl ath aue awi axe bce bfe bge \ cdce ce cm cp cs ct cue cx dc de disc \ ed ef el em en ep ex faith fatm fe \ fwip fxp gif gre harp hatm hme ic ie \ ipw iwi ixgb kue le lge lnc my ndis nge \ nve oltr patm pcn ppp ral ray re rl rue \ sbni sbsh sf sis sk sl sn sr ste stf \ stge tap ti tl tun tx txp udav ural vge \ vlan vr vx wb wi xe xl ifoff atmpif nfe" for simple_iface in ${interface_array} do # first export ifconfig_${simple_iface}0="DHCP" # second export ifconfig_${simple_iface}1="DHCP" done
Про интерфейсы - умнее не придумал :). В дополнение, был написан простенький стартовый скрипт, такого составу:
IP вполне реальный - у меня винды нет, поэтому я отсканил произвольную сеть nmap`om на предмет машин с открытым RDP-портом, первую попавшуюся и взял :). Далее, на машине с FreeBSD надо расшарить по NFS диск:
Ну и всё. Пока, всё. Если надо будет, по работе например, или для души, то допилю до окончательного варианта - в частности, можно удалить 2/3 системных приложений, да и портов много лишних получилось - тоже мона погрохать. Надо допилить скрипт из предыдущей статьи, и найти как выцепить в уже запускающейся с диска в памяти системе - откуда она загрузилась - ибо этих данных нигде нет. На эту тему есть одна идея - надо добавить запрос опции "root-path" в /etc/dhclient.conf, после чего она появится в /var/db/dhclient.leases.${interface_name}, откуда её и можно будет вытащить, распарсив этот файл. Ну а дальше всё просто - монтируем указанный в ней путь, и с него запускаем скрипты и вытаскиваем персональные конфиги клиентов - если необходимо.
P.S. Ядро, с лоадером, т.е. всё содержимое /boot - берётся с любой машины, лучше GENERIC - тупо копируется.