dadv: (Default)
[personal profile] dadv

В продолжение темы. Дальше только для пользователей FreeBSD.

1. Для демонстрации идеи начнем с "Hello, World!"

#include <sys/syscall.h>

#define MESG    "Hello, world!\n"
#define MESG_SZ (sizeof(MESG)-1)

int syscall(const int n, ...);

#define _exit(a)       syscall(SYS_exit, a)
#define write(a, b, c) syscall(SYS_write, a, b, c)

int errno;

int main() {
  write(1, MESG, MESG_SZ);
  _exit(0);
  return 0; /* make compiler happy */
}
Написанная в таком стиле программа является строгим кодом на C (собирается gcc -ansi -pedantic -Wall без замечаний), не использует и не требует сервиса libc, общаясь с ядром FreeBSD непосредственно через системные вызовы и под FreeBSD 8.0/i386 компилируется в статический бинарник размером в 512 байт:

gcc -Os -ansi -pedantic -Wall -I/usr/src/lib/libc/i386 -nostartfiles -nodefaultlibs -nostdlib -s -static -O99 -fomit-frame-pointer -Wl,--entry=main,--gc-section -o hello hello.c /usr/src/lib/libc/i386/sys/syscall.S /usr/src/lib/libc/i386/sys/cerror.S /usr/src/lib/libc/sys/__error.c

Цена - отсутствие переносимости на другие OS.

2. FreeBSD, как и другие OS, наравне с "традиционными" файловыми системами на разделах дисков умеет использовать заранее подготовленные файл-образы файловых систем, сначала "подключая" (attach) образы, что создает в каталоге /dev новое "устройство", соответствующее файл-образу, а затем монтируя его как любое другое устройство. К сожалению, система загрузки FreeBSD пока не предоставляет готового сервиса по "подключению" произвольного количества образов средствами loader без загрузки их полностью в память (есть штатный метод с загрузкой - директивами mfsroot_* в /boot/loader.conf).

А всего-навсего надо-то один системный вызов (MDIOCATTACH) на образ, а дальше монтировать можно уже штатно через /etc/fstab. Актуальность такого сервиса проявляется при создании "встроенных" решений для аппаратных систем с небольшим размером носителя (флеша) и RAM (необязательно на архитектуре i386). Можно было бы сжать файловую систему при помощи geom_uzip, "аттачить" её перед стартом /sbin/init как /dev/md0.uzip и прописать в /etc/fstab монтирование /dev/md0.uzip в качестве корня вместо действительного носителя. И не читать только для этого весь образ в дефицитную память.

Если быть педантичным, то есть способ обойтись штатными средствами: использовать /rescue/sh для запуска shell-скрипта перед вызовом /sbin/initloader есть и такая возможность), он подробно описан в статье http://wiki.freebsd.org/AvgLiveCD. Но для встроенных решений у него есть очевидный недостаток - он зависит от наличия /rescue/sh на загрузочном носителе, а этот файл (crunched binary) в FreeBSD 8.0 занимает чуть больше 4Mb. Для LiveCD это ничто, но встроенные системы могут иметь ненамного больше флеша. И ради одного системного вызова для них это может быть слишком большим оверхедом.

3. Наилучшим решением было бы расширить функциональность загрузчика и обучить его передавать в ядро информацию о необходимости подключать указанные в loader.conf файл-образы перед запуском /sbin/init, а также научить ядро использовать эту информацию и следовать её инструкциям. Но это относительно крупные изменения в системе.

Более легковесным (и полностью рабочим) решением будет маленький статический бинарник mdtab, созданный по описанной в пункте 1 технологии. Бинарник умеет прочитать свой конфиг /boot/mdtab.conf, в котором каждая строка описывает один файл-образ и состоит из двух полей, разделенных пробельными символами: имени сжатого geom_uzip-образа и точки монтирования. Затем он подключает и сразу монтирует (r/o) образ файловой системы. Размер бинарника для 8.0 получается менее 3Kb. Его можно запускать и в multiuser как любое другое приложение, а кроме того, можно использовать директиву init_path="/boot/mdtab" в loader.conf. В этом случае mdtab запускается ядром вместо /sbin/init с PID=1 и тогда он при окончании работы вместо _exit() запускает /sbin/init через execve, прозрачно передавая ему аргументы и environment.

Исходный код mdtab и Makefile для сборки доступны тут: http://www.grosbein.net/freebsd/mdtab-0.1.tgz

Пример /boot/mdtab.conf для одного образа на всю систему:
# Монтировать образ поверх корневой fs
/root.uzip      /
В образ надо убрать все файлы и каталоги, кроме /boot и /dev. При таком варианте после загрузки ядра (и монтирования им корневой файловой системы и devfs) mdtab смонтирует образ "поверх" рута и скроет доступ к /boot и /dev. При этом devfs будет автоматически повторно смонтирована одним из системных rcNG-скриптов при загрузке.

Можно сделать чуть иначе, монтируя образ не напрямую поверх рута, а в каталог /tree. В этом варианте нужно в корне наделать симлинков типа /usr -> /tree/usr (и так далее для всех подкаталогов корня, кроме /boot и /dev). При такой настройке остается доступ к /boot и /dev тоже не будет монтироваться дважды.

Date: 2010-06-27 06:52 (UTC)
From: [identity profile] blacklion.livejournal.com
gcc -ansi -pedantic -Wall
-Wall это, увы, мало. В зависимости от версии gcc он будет или не будет давать предупреждение вот на таком коде:

double d = 123567.89;
char c = d;

IMHO, не предупреждать тут — преступление, но — факт

Date: 2010-06-27 06:58 (UTC)
From: [identity profile] blacklion.livejournal.com
Но это я так, ворчу просто по мотивам вот этого.

Date: 2010-06-27 07:38 (UTC)
From: [identity profile] blacklion.livejournal.com
А в порты положишь, по-английски попиаришь? :)

Date: 2010-06-27 08:38 (UTC)
From: [identity profile] dadv.livejournal.com
У меня сложилось ощущение, что тем, кому это может быть актуально, оно не надо (сами как-то уже обошлись), а остальным неактуально. Поэтому в ближайшее время не буду, за недостатком времени.

Date: 2010-06-27 10:03 (UTC)
From: [identity profile] dmarck.livejournal.com
Пиарить не надо, а вот порт таки сделай.

Date: 2010-06-27 10:10 (UTC)
From: [identity profile] dadv.livejournal.com
На самом деле, я не вполне уверен, что оно реально понадобится, потому что NanoBSD без crunch всё-таки слишком большое получается для DIR-320 ;-)

Плюс фиксированный путь к /sbin/init это неправильно, а усложнять парсер конфига лениво. Равно как и лезть в kenv и писать новый парсер для решения типа init_path="/sbin/mdtab:/path/to/init"

Date: 2010-06-28 08:41 (UTC)
From: [identity profile] orao.livejournal.com
я не вполне уверен, что оно реально понадобится
Лучше пусть будет ИМХО.

Date: 2010-06-27 08:49 (UTC)
From: [identity profile] dadv.livejournal.com
Но в своих LiveCD/LiveUSB таки использую :-) Такая пожатая NanoBSD/i386 влезла в 10Mb и внутри VirtualBox грузится и работает на 16Mb памяти, об этом уже писал в ru.unix.bsd

Date: 2010-06-27 09:45 (UTC)
From: [identity profile] blacklion.livejournal.com
А куда ты такое ставишь? 16Mb памяти — это что-то совесем не сообразное с x86, а на MIPS/ARM оно ещё как-то вроде бы не совсем что бы готово.

Надо или искать ньюс-сервер или получать айпи-ноду… Скучаю без ru.unix[.bsd] с тех пор как хаб остановил :(

Date: 2010-06-27 10:00 (UTC)
From: [identity profile] dadv.livejournal.com
Пока никуда не ставлю, пока это всё научные изыскания ;-)
Для реальных железок с MIPS больше подойдет подход PicoBSD с crunch, да... Я собирал PicoBSD на восьмерке размером в 1.7Mb, влезало на флопик, отформатированный с нестандартной плотностью - только реальный BIOS с такого флопика грузиться не захотел :-)

Date: 2010-06-27 10:06 (UTC)
From: [identity profile] blacklion.livejournal.com
Офигеть, да. А я на soekris 5501 держу полную инсталляцию 7-STABLE… На 1Gb CF…

Date: 2010-06-27 10:14 (UTC)
From: [identity profile] dadv.livejournal.com
Ну, дома у меня тоже роутингом занимается безвинтиляторный промписи с 256CF, побитой на две части (NanoBSD):

df -h
Filesystem             Size    Used   Avail Capacity  Mounted on
/dev/ad0s2a            121M    101M     10M    91%    /
devfs                  1.0K    1.0K      0B   100%    /dev
/dev/md0               4.4M    2.3M    1.8M    55%    /etc
/dev/md1               9.1M    6.2M    2.2M    73%    /var
devfs                  1.0K    1.0K      0B   100%    /var/named/dev
/dev/da0s1a.journal    459G    213G    209G    51%    /mnt/usbtor


Через USB подоткнут 500G-вый винт для торрентов :-) Памяти 512M, свободно больше 300. Восьмерка.

Date: 2010-06-27 10:28 (UTC)
From: [identity profile] blacklion.livejournal.com
А чем торренты? У меня памяти 512 но свободной ноль — rTorrent жрёт её тоннами. Торренты я, правда, качаю прямо на NFS…

Date: 2010-06-27 10:42 (UTC)
From: [identity profile] dadv.livejournal.com
transmission

Date: 2010-06-27 10:29 (UTC)
From: [identity profile] blacklion.livejournal.com
Mem: 343M Active, 36M Inact, 97M Wired, 9972K Cache, 60M Buf, 7652K Free

Вот такая грусть.

Date: 2010-06-27 10:43 (UTC)
From: [identity profile] dadv.livejournal.com
last pid: 41621;  load averages:  0.05,  0.12,  0.08   up 14+22:02:52  17:42:37
31 processes:  1 running, 30 sleeping
CPU:     % user,     % nice,     % system,     % interrupt,     % idle
Mem: 65M Active, 307M Inact, 95M Wired, 11M Cache, 59M Buf, 7524K Free
Swap: 

  PID USERNAME      THR PRI NICE   SIZE    RES STATE    TIME   WCPU COMMAND
35178 transmission    2  54    0 33632K 24928K kqread 115:33 15.87% transmissio
41617 root            1  50    0  3620K  1384K wait     0:00  0.20% login
 1071 root            4  44    0  3224K   200K rpcsvc  13:30  0.00% nfsd
  922 bind            4  44    0 35748K 25692K kqread   6:11  0.00% named
 1272 root            1  44    0  4740K  1340K select   2:14  0.00% ntpd
 1100 root            1  44    0  9972K  3836K select   1:46  0.00% mpd5
 1327 root            1  50    0  5144K  1236K select   1:01  0.00% sshd
 1337 root            1  44    0  5928K  1732K select   0:41  0.00% sendmail
  830 root            1  44    0  3280K   648K select   0:16  0.00% syslogd
 1350 root            1  44    0  3308K   520K nanslp   0:07  0.00% cron
  941 root            1  44    0  3308K  1016K select   0:03  0.00% rpcbind
 1342 smmsp           1  44    0  5928K  1212K pause    0:01  0.00% sendmail
 1069 root            1  44    0  3224K   536K select   0:00  0.00% nfsd
41538 eugen           1  44    0  4600K  2036K ttyin    0:00  0.00% tcsh
41618 eugen           1  46    0  4600K  2076K pause    0:00  0.00% tcsh
 1059 root            1  44    0  3280K  1108K select   0:00  0.00% mountd

Date: 2010-06-27 10:47 (UTC)
From: [identity profile] blacklion.livejournal.com
last pid: 79559;  load averages:  0.59,  0.61,  0.63 up 47+14:58:49  14:45:14
36 processes:  1 running, 35 sleeping
CPU: 13.6% user,  0.0% nice, 18.3% system, 10.5% interrupt, 57.6% idle
Mem: 328M Active, 53M Inact, 96M Wired, 9012K Cache, 60M Buf, 7652K Free
Swap:

  PID USERNAME  THR PRI NICE   SIZE    RES STATE    TIME   WCPU COMMAND
26058 rtorrent    1 100    0   398M   118M select 113.1H 16.31% rtorrent
  888 root        1  98    0  3372K   688K select  74.1H  6.05% natd
 1020 bind        4   4    0 40812K 10080K kqread   7:30  0.15% named
58795 rtorrent    1  96    0  3536K   904K select  18:03  0.00% screen
 1153 root        1   8   r0  3268K   260K nanslp  13:04  0.00% watchdogd
 1104 root        1  96    0  7964K  1052K select  11:31  0.00% nmbd
 1195 root        1  96    0  4672K   692K select   6:48  0.00% ntpd
 1144 dhcpd       1  96    0  3128K   336K select   5:08  0.00% dhcpd
 1126 www         1   4    0  5068K   876K kqread   3:18  0.00% lighttpd
 1220 root        1  96    0  5876K   768K select   2:46  0.00% sendmail
 1214 root        1  96    0  5752K   656K select   2:20  0.00% sshd
 1119 nutmon      1   8    0  4792K   508K nanslp   2:05  0.00% upsmon
  955 root        1  96    0  3184K   512K select   0:54  0.00% syslogd
 1264 root        1  96    0  3288K   404K select   0:50  0.00% hostapd
 1232 root        1   8    0  3212K   452K nanslp   0:25  0.00% cron
 1108 root        1  96    0 10160K   432K select   0:19  0.00% smbd
  379 _dhcp       1  96    0  3128K   412K select   0:16  0.00% dhclient
 1030 root        1  96    0  3212K   308K select   0:06  0.00% rpcbind
 1226 smmsp       1  20    0  5876K   576K pause    0:05  0.00% sendmail
79457 rtorrent    1  96    0  3496K  1228K RUN      0:03  0.00% top
  363 root        1  96    0  3128K   268K select   0:01  0.00% dhclient
79445 rtorrent    1  96    0  8428K  2188K select   0:00  0.00% sshd
79443 root        1   4    0  8428K  2052K sbwait   0:00  0.00% sshd
58798 rtorrent    1  20    0  5500K   220K pause    0:00  0.00% tcsh
79447 rtorrent    1  20    0  5500K  1160K pause    0:00  0.00% tcsh
79454 rtorrent    1  20    0  5500K  1184K pause    0:00  0.00% tcsh
79450 rtorrent    1  20    0  3536K  1004K pause    0:00  0.00% screen
  772 root        1  96    0  1888K    16K select   0:00  0.00% devd
 1282 root        1   5    0  3184K   180K ttyin    0:00  0.00% getty
 1258 root        1  96    0  3240K   224K select   0:00  0.00% inetd
 1117 root        1  -8    0  4792K   240K piperd   0:00  0.00% upsmon
  113 root        1  20    0  1380K   136K pause    0:00  0.00% adjkerntz
 1129 root        1  20    0 10160K   224K pause    0:00  0.00% smbd

Date: 2010-06-27 10:54 (UTC)
From: [identity profile] dadv.livejournal.com
60M свободно (Inact+Free), вполне можно жить и не заморачиваться - если конечно rtorrent не жалуется на недостаток памяти. Лично я ограничиваю скорость раздачи на 2 мегабита, чтобы не устраивать себе DDoS :-) Рейтинга больше семи мне вполне хватает.

Date: 2010-06-27 11:15 (UTC)
From: [identity profile] blacklion.livejournal.com
rTorrent работает через mmap() он регшулярно жалуется что ему 32-х битного адресного пространства не хватает :)
А вот скорость отдачи на это не влияет (влияет на процессор)...

Date: 2010-07-02 19:44 (UTC)
From: [identity profile] http://users.livejournal.com/_slw/
возьми ip-поинта

Похоже на велосипед...

Date: 2010-10-18 12:00 (UTC)
From: [identity profile] bu7cher.blogspot.com (from livejournal.com)
Если я правильно понимаю идею, то сегодня marcel@ закоммитил альтернативную реализацию, рещающую вашу проблему..

Re: Похоже на велосипед...

Date: 2010-10-18 12:03 (UTC)
From: [identity profile] dadv.livejournal.com
Это прекрасно, только когда оно появится в STABLE? Мне завтра две железки в "тестовый production" ставить :-)

Profile

dadv: (Default)
Choose your future

July 2024

M T W T F S S
12 34567
891011121314
15161718192021
22232425262728
293031    

Tags

Style Credit

Powered by Dreamwidth Studios