Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> Мелочи —> geom_uzip

Использование для загрузки сжатой файловой системы - geom_uzip

Автор: lissyara.


    Данный текст появился из моих развлечений, по работе - надо было сделать загрузочную флэшку, которая после загрузки задавала пару тупых вопросов, после чего разбивала диск, разворачивала сервер филиала, втыкала в его в виндовый домен и меняла все данные в конфигах. Данная задача трудностей не вызывала, были одни крупные грабли - при разворачивании и генерации файла 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/>

   Делаем виртуальный диск:
/usr/home/lissyara/>mdconfig -a -t vnode -f mfs_root.md  -u 4
mdconfig: open(/dev/mdctl): Permission denied
/usr/home/lissyara/>su
ussr% mdconfig -a -t vnode -f mfs_root.md  -u 4

   Создаём директорию, куда будем монтировать диск:
ussr% mkdir mfs

   Записываем на диск метку:
ussr% bsdlabel -w md4 auto

   Создаём файловую систему:
ussr% newfs md4a
/dev/md4a: 512.0MB (1048560 sectors) block size 16384, fragment size 2048
        using 4 cylinder groups of 128.00MB, 8192 blks, 16384 inodes.
super-block backups (for fsck -b #) at:
 160, 262304, 524448, 786592

   Монтируем:
ussr% mount /dev/md4a /usr/home/lissyara/mfs
ussr% df -h | grep md
/dev/md4a    496M    4.0K    456M     0%    /usr/home/lissyara/mfs
ussr% 

   Собираем и устанавливаем мир, с указанием директории назначения - наш диск в памяти:
make world DESTDIR=/usr/home/lissyara/mfs && \
? cd /usr/src/etc && make distribution DESTDIR=/usr/home/lissyara/mfs

   После установки, смотрим чё получилось:
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:
ussr% mount_nullfs /usr/home/lissyara/pkgs /usr/home/lissyara/mfs/mnt
ussr% df -h | grep lissyara
/dev/md4a                  496M   150M   307M   33%   /usr/home/lissyara/mfs
/usr/home/lissyara/pkgs     72G   7.0G    59G   11%   /usr/home/lissyara/mfs/mnt
ussr% 

   После чего топаем внутрь диска в файле, как в 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 - она позволяет сжимать образы файловых систем, и, в дальнейшем, эти сжатые образы можно втюхать лоадеру, который их загрузит в память. Ну, а дальше - ядро будет использовать софт с этого диска. Сжимаем, предварительно отмонтировав, и отключив диск - при проблемах на отмонтировании/отключении - можно перезагрузиться:
ussr% umount /usr/home/lissyara/mfs
ussr% mdconfig -d -u 4
ussr% mkuzip -v mfs_root.md 

padding data with 40 bytes so that file size is multiple of 512
compressed data to 124328448 bytes, saved 412542464 bytes, 76.84% decrease.

ussr% ls -alh | grep md
-rw-r--r--   1 lissyara  wheel   512M 11 июл 00:11 mfs_root.md
-rwxr-xr-x   1 lissyara  wheel   119M 11 июл 19:55 mfs_root.md.uzip

   Неплохо. Сжалось вдвое. Хотя, я рассчитывал на лучший результат - ибо в 128 мегов памяти, и тем более в 64 - ну никак не вписываемся. Поэтому, пробовать грузиться с этого я даже не стал, а полез изучать маны - с целью ужать всё что можно и удалить ненужное. Для начала, изучаем man make.conf, и добавляем в файл /etc/make.conf такие строки:
# temporary - for thin clients
NO_KERBEROS=                    YES
NO_WPA_SUPPLICANT_EAPOL=        YES
NO_BLUETOOTH=                   YES
NO_CVS=                         YES
NO_CXX=                         YES
NO_DICT=                        YES
NO_FORTRAN=                     YES
NO_GDB=                         YES
NO_GPIB=                        YES
NO_I4B=                         YES
NO_IPFILTER=                    YES
NO_PF=                          YES
NO_AUDIT=                       YES
NO_AUTHPF=                      YES
NO_TOOLCHAIN=                   YES
NO_INET6=                       YES
NO_ATM=                         YES
NO_USB=                         YES
NO_LPR=                         YES
NO_ACPI=                        YES
NO_MAILWRAPPER=                 YES
NO_MAN=                         YES
NO_NETCAT=                      YES
NO_NIS=                         YES
NO_NLS_CATALOGS=                YES
NO_OBJC=                        YES
NO_OPENSSH=                     YES
NO_OPENSSL=                     YES
NO_SENDMAIL=                    YES
NO_SHAREDOCS=                   YES
NO_CRYPT=                       YES
NO_GAMES=                       YES
NO_INFO=                        YES
NO_LIBC_R=                      YES
NO_PROFILE=                     YES
NO_SHARE=                       YES
NO_BIND=                        YES
PPP_NO_NAT=                     YES
PPP_NO_NETGRAPH=                YES
PPP_NO_RADIUS=                  YES
NO_RCMDS=                       YES

   После чего повторяем набор действий по созданию диска в памяти, и инсталляции на него системы. Тока диск делаем вдвое меньше:
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), ненужных зависимостей и прочего. Честно говоря - сильно не изгалялся, но на выходе, уже к третьей версии, имел такое:
ussr% df -h | grep md
/dev/md4a     248M     88M    140M    39%    /usr/home/lissyara/mfs

   После сжатия, соответствено:
ussr% ls -alh mfs_root.md.uzip
-rwxr-xr-x  1 root  wheel    42M 13 июл 00:24 mfs_root.md.uzip
ussr% 

   Осталось, рассмотреть запуск всего этого хозяйства. Вот тут меня ждали грабли - как загрузить образ, вопросов не возникало - в /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

   Про интерфейсы - умнее не придумал :). Докучи, был написан простенький стартовый скрипт, такого составу:
ussr% more usr/local/etc/rc.d/startx.sh
#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
export PATH

# moused's
/etc/rc.d/moused forcestart ums0 &
/etc/rc.d/moused forcestart psm0 &
# X
sleep 5 && /usr/local/bin/startx &

ussr% 

   Ну и создан файлик для указания иксам - чё и с какими параметрами запускать:
ussr% more root/.xinitrc
exec /usr/local/bin/rdesktop -k en-us -f -b -N -z 77.73.24.66
ussr% 

   IP вполне реальный - у меня винды нет, поэтому я отсканил произвольную сеть nmap`om на предмет машин с открытым RDP-портом, первую попавшуюся и взял :). Далее, на машине с FreeBSD надо расшарить по NFS диск:
more /etc/exports
# NFS filesystems
/shares/diskless -maproot=root -network 192.168 -mask 255.255.0.0

и настроить DHCP - я использую isc-dhcp3-server-3.0.5_2, получилось примерно так:
more /usr/local/etc/dhcpd.conf
# main DHCP
subnet 192.168.254.0 netmask 255.255.255.0 {
        range 192.168.254.1 192.168.254.199;
        option routers 192.168.254.254;
        option subnet-mask 255.255.255.0;
        # DNS
        option netbios-name-servers 192.168.254.254;
        option netbios-dd-server 192.168.254.254;
        option netbios-node-type 8;
        option broadcast-address 192.168.254.255;
        option ntp-servers 192.168.254.254;
        option root-path "192.168.254.254:/shares/diskless";
        next-server 192.168.254.254;
        filename "/boot/pxeboot";
        option domain-name "lissyara.int.otradno.ru";
        option domain-name-servers 192.168.254.254;
        }

   Ну и всё. Пока, всё. Если надо будет, по работе например, или для души, то допилю до окончательного варианта - в частности, можно удалить 2/3 системных приложений, да и портов много лишних получилось - тоже мона погрохать. Надо допилить скрипт из предыдущей статьи, и найти как выцепить в уже запускающейся с диска в памяти системе - откуда она загрузилась - ибо этих данных нигде нет. На эту тему есть одна идея - надо добавить запрос опции "root-path" в /etc/dhclient.conf, после чего она появится в /var/db/dhclient.leases.${interface_name}, откуда её и можно будет вытащить, распарсив этот файл. Ну а дальше всё просто - монтируем указанный в ней путь, и с него запускаем скрипты и вытаскиваем персональные конфиги клиентов - если необходимо.

   P.S. Ядро, с лоадером, т.е. всё содержимое /boot - берётся с любой машины, лучше GENERIC - тупо копируется.



размещено: 2007-07-15,
последнее обновление: 2007-08-20,
автор: lissyara


Cka3o4Huk, 2007-07-16 в 12:57:29

Отличная статья! +++ Давно искал подобного рода материал!
Большое спасибо!

Jay, 2007-07-16 в 14:21:29

Рекомендую изучить внутренне устройство Frenzy. Я на ее основе свои роутерные прошивки делал.

lissyara, 2007-07-16 в 14:23:36

хватило man man и далее по ссылкам :)
Собственно - это единственное что использовалось при написании данного текста...
А френзи - надо посмотреть... Юзал, но внутрь не лазил.

dennis, 2007-07-16 в 17:55:47

Конструкции в /etc/make.conf вида

"NO_BLUETOOTH=                   YES"

устарели.

Пишут просто
NO_BLUETOOTH=  
NO_KERBEROS=      

и т.д.

YES не нужно

lissyara, 2007-07-16 в 18:09:03

А я не всегда делаю как правильно... Хотя и знаю как правильно.
Иногда, как красивей. А ведь так красивей - согласись? :)

Авось, 2007-07-17 в 16:26:41

Хорошая статья. Спасибо!

Вася, 2007-07-18 в 1:07:04

Лисяра да ты просто аццкий сотона!
Так держать !
Пеши есчо, твои статьи просто супер !

weec, 2007-09-24 в 14:27:31

что-то не могу найти в статье сборку и инсталяцию ядра

weec, 2007-09-24 в 14:38:25

извиняюсь
упустил  PS

MarchCat, 2008-07-30 в 13:55:08

Чтобы не перечислять все возможные и невозможные типы сетевых интерфейсов, установите в rc.conf
ifconfig_DEFAULT="DHCP"



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.059 секунд
Из них PHP: 42%; SQL: 58%; Число SQL-запросов: 77 шт.
Исходный размер: 52820; Сжатая: 11764