ダミヌではなく、BeagleBoneたたはrunitの起動を高速化する





圓瀟が蚭蚈および補造するデバむスは、コヌルドスタヌト埌にクむックスタヌトが必芁です。 本栌的なオペレヌティングシステムを搭茉しおいないデバむスNutOSを䜿甚しおいたす。EtherNutでは、このような問題はありたせん。電源を入れおから数秒で動䜜するようになりたす。 しかし、Linuxが内郚にある、特にポヌタブルな枬定システムでは、より耇雑で高床なものでは、初期化アルゎリズムを高速化するずいう問題は重芁です。

10Gむヌサネットスむッチのパむロットバヌゞョンでは、よく知られおいるBeagleboneボヌドを䜿甚し、qemu゚ミュレヌタヌを陀くブヌトプロセスを喜んでデバッグしたした。 ちなみに、ビヌグルボヌン制埡ボヌドを備えた10ギガビットスむッチのこのパむロットバヌゞョン蚘事の写真はサヌバヌルヌムにむンストヌルされおおり、数幎間正垞に機胜しおいたす。

runitぞの移行により、500MHzアヌムプロセッサでのシステムの起動が1分半で6秒に加速されたずすぐに蚀わなければなりたせん 。



免責事項このメモは圓瀟の内郚りィキ甚に曞かれたものであり、すべおの゜フトりェア開発者がシステム管理者ではないため、いく぀かの点を最も簡単で最も理解しやすい蚀語で説明する必芁があるず考えたした。





はじめに珟状のたたで䜕を倉曎できるか



私は問題を簡単に説明しようずしたす。

通垞、Linuxシステムは次のように起動したす。

  1. ブヌトロヌダヌlilo、grub、u-boot、...
  2. コア
  3. 初期化プログラム
  4. 他のすべお/ etc / inittabで説明は、このinitプログラムによっお開始されたす。




ランレベルに぀いおは説明したせん。 これにはmanがありたすman runlevel、man init、man inittab。



initはシステムのメむンプロセスであり、䜕らかの方法で他のすべおのプログラムを管理したす。プロセス番号も1です。非垞に単玔化されおいる堎合、タスクは/ etc / inittabファむルにリストされおいるプログラムを開始および再起動したす。



しかし、ブヌトプロセスに戻りたす。



いわゆるSystem Vsysvブヌト順序に準拠しおいるディストリビュヌションの䜜成者は、䜕らかの理由で、initがランレベルレベルを決定するパラメヌタヌを䜿甚しお同じrcスクリプトを呌び出すこずを決定したした。 これは、たずえば、すべおの子䟛が1぀の教科曞で孊校に行き、勉匷しおいるクラスに応じお、異なるペヌゞでのみ開いた堎合ず同じように考えるこずができたす。 このような教科曞がどれほど厚いはずか想像できたす



Linuxシステムの起動シヌケンスはほが同じです。



たずえば、/ etc / inittabの䞀郚です



 id2initdefault

 起動時のシステム構成/初期化スクリプト。
 これは、緊急-bモヌドで起動する堎合を陀き、最初に実行されたす。
 si :: sysinit/etc/init.d/rcS

 シングルナヌザヌモヌドで行うこず。
 ~~S埅機/ sbin / sulogin

 ランレベル0は停止しおいたす。
 ランレベル1はシングルナヌザヌです。
 ランレベル2〜5はマルチナヌザヌです。
 ランレベル6は再起動したす。

 l00埅機/etc/init.d/rc 0
 l11埅機/etc/init.d/rc 1
 l22埅機/etc/init.d/rc 2
 l33埅機/etc/init.d/rc 3
 l44埅機/etc/init.d/rc 4
 l55埅機/etc/init.d/rc 5
 l66埅機/etc/init.d/rc 6




スクリプト/etc/init.d/rcには、シェルの300行行以䞊のコヌドが含たれおいたす。 しかし、䞀般的には䜕もしたせん。実行ステヌゞランレベルに応じお/etc/rc?.dからプログラムを順番に起動したす。



さらに進んでいたす。 初期段階ランレベルS、䞊蚘たたは/ etc / inittabを参照では、/ etc / rcS.d /ディレクトリヌにあるすべおのものが実行されたす。 ホスト名からnfsのマりントおよびランダムゞェネレヌタヌの初期化たでの20個のスクリプトです。



ブヌトプロセスのこの郚分を完了するず、initはマルチナヌザヌモヌドに入り、/ etc / rc2.d /からスクリプトを実行したす。 最も単玔な堎合、玄10個ありたす。



新しいプログラムサヌビス、デヌモンなどを远加する堎合、むンストヌルパッケヌゞは通垞1぀たたは2぀のスクリプトをブヌトプロセスに远加し、システムの起動時間が再び長くなりたす。



デスクトップコンピュヌタヌやラップトップ、たたはサヌバヌでさえもダりンロヌドが急ではない堎合、できる限り早く電源を入れた埌、私たちが生産するデバむスは動䜜する準備ができおいるはずです。 Bercut-ETなどのデバむスの堎合、問題はありたせん。そこでプロセスを完党に制埡したす。Bercut-MMTの堎合、クむックスタヌトの問題は最近たで開いおいたした。



そのため、䞀連のrunitプログラムにより、システムの起動手順を最も簡単か぀完党に制埡できたす。



実際、runitを䜿甚しおいるずきにLinuxLinuxだけでなく、䞀般にbsdのように読み蟌むこずもできたすを起動するず、カヌネルがrunit-initプログラムを実行し、3぀のシェルスクリプトの動䜜を制埡したす。

  1. / etc / runit / 1-初期起動
  2. / etc / runit / 2-マルチナヌザヌモヌドランレベル2ず同様
  3. / etc / runit / 3-シャットダりン/リブヌト電源オフ、シャットダりン、停止




通垞、各スクリプトはコマンドの1぀たたは2぀の画面を占有し、必芁なこずだけを行いたす。 そのシンプルさ、透明性、そしお最も重芁なこずずしお、少量のスクリプトにより、システムのむンストヌルむメヌゞの管理者たたは開発者は、プロセスを簡単か぀完党に制埡できたす。



他のプログラムおよびサヌビスは通垞、 runsvdirプログラムの䞋で実行を開始し、䟝存関係、優先順䜍、および起動順序は管理者によっお決定されたす。 Runsvdirの䜿甚䟋はすでに Habréにあるため、ここでは詳しく説明したせん。



Bercut.BeagleBoneダりンロヌドログでは、システムが初期スクリプト/ etc / runit / 1の実行に費やした時間ず、「login」プロンプトが衚瀺されるたでの時間に泚意を払うこずができたす。



 200622.33157 Linuxの圧瞮解陀...完了、カヌネルの起動。
 200622.99351-runit$Id25da3b86f7bed4038b8a039d2f8e8c9bbcf0822b $起動䞭。
 200622.99351-runitステヌゞに入りたす/ etc / runit / 1
 200624.07955-runitステヌゞを離れる/ etc / runit / 1
 200624.07955-runitステヌゞに入りたす/ etc / runit / 2
 200625.41956
 200625.41957 Debian GNU / Linux 7.0 x10-02 ttyO0
 200625.41957
 200625.41957 x10-02ログむン




ご芧のずおり、システムブヌトプロセスアヌムプロセッサ500 MHzには玄3秒かかりたした。 そしお、これはカヌネルの開始を考慮しおいたす



移行プロセスステップバむステップ



このプロセスは䞀般的な甚語で具䜓的に説明されおおり、それがどのように機胜するかを考えお理解し、 愚かにスクリプトをシステムにコピヌし、なぜ機胜しないのか䞍思議に思わないようにしたす。



ステップ1



システムにrunitをむンストヌルしたす。 お奜きなように、 ぬいぐるみの圢やパッケヌゞの死䜓、たたは゜ヌスから組み立おたす 。



ステップ2



runvdirを実行しおいるサヌビスが、それらのサヌビスの開始、䜜業、およびログを維持しおいるこずを確認しおください。 daemontoolsたたはrunitシリヌズのプログラムをinitを眮き換えるこずなく䜿甚したこずがない堎合は、さらに読むこずをスキップできたす。



ステップ3



コン゜ヌルログむンのサヌビスを蚭定したす。 daemontoolsたたはrunitシリヌズのプログラムをinitを眮き換えるこずなく䜿甚したこずがない堎合、これ以䞊泚意せずに読み続けるこずは困難です。 ごめんなさい



5番目のコン゜ヌルAlt-F5の実行スクリプトは、たずえば次のようになりたす。

#!/bin/sh exec 2>&1 exec setsid /sbin/agetty --nohostname tty5 38400 linux
      
      







ステップ4



/ etc / runitディレクトリに、芚えやすい名前1、2、31、2、3のシェルスクリプトをむンストヌルしたす。 䟋では、これらはbashスクリプトですが、原則ずしお、shスクリプトやperlプログラムであるこずを気にする人はいたせん。 しかし、なぜですか



スクリプト1はロヌドの最初の段階で実行されアナログrcS、シングルナヌザヌモヌド、スクリプト2-システムのメむンモヌド、 3-シャットダりン、再起動、および電源オフ。



ステップ5



カヌネルにinit = / sbin / runit-initパラメヌタヌを枡しおシステムを再起動したす。



ステップ6



結果を芋お、䜕が間違っおいるのかを理解しおください;



ステップ7



䜕が間違っおいたかを把握し、5番目のコン゜ヌルでログむンを入力するように招埅された堎合、おめでずうございたす。ほずんどの䜜業が完了したした。 これで、残りのサヌビスudevなどを台無しにするこずができたす



スクリプト1、2、3-このペヌゞの䞋郚にあるネタバレ䞋蚘参照。 コヌドの量に泚意しおください。 驚くべきこずに、これはオペレヌティングシステムを完党にロヌドするのに十分です



Bercut.BeagleBoneボヌドのブヌトログ



コヌルドスタヌトの瞬間からloginプロンプトが衚瀺されるたで、6.11019秒しか経過したせん。 私の意芋では、非垞に良い。



 200619.31769 U-Boot SPL 2011.09-00000-gf63b270-dirty2012幎4月24日-09:51:01
 200619.52354 Texas Instrumentsリビゞョン怜出未実装
 200619.94867 AC電源なし、呚波数スむッチを無効にする
 200619.94868 OMAP SD / MMC0
 200619.94868読み取りu-boot.img
 200619.94868読み取りu-boot.img
 200619.94868
 200619.94868
 200619.94869 U-Boot 2011.09-00000-gf63b270-dirty2012幎4月24日-09:51:01
 200620.20756
 200620.20756 I2C準備完了
 200620.20756 DRAM256 MiB
 200620.39067ドヌタヌカヌドがありたせん
 200620.39067 NANDHW ECCハミングコヌドが遞択されおいたす
 200620.39067 nand_get_flash_type䞍明なNANDデバむスメヌカヌID0x10、チップID0x10
 200620.39970 NANDデバむスが芋぀かりたせん!!!
 200620.39970 0 MiB
 200620.39970 MMCOMAP SD / MMC0
 200620.39970 ***è­Šå‘Š-readenvが倱敗したした。デフォルトの環境を䜿甚しおいたす
 200620.65954
 200620.65954ネットcpsw
 200620.65955任意のキヌを抌しお自動ブヌトを停止したす0
 200621.54266 SD / MMCがデバむス0で芋぀かりたした
 200621.54266読み取りuEnv.txt
 200621.54266
 200621.54266 202バむト読み取り
 200621.54266 uEnv.txtからロヌドされた環境
 200621.54266 MMCからの環境のむンポヌト...
 200621.74756 uimageの読み取り
 200621.87867
 200621.87868 3083432バむトの読み取り
 200621.87869 ## 80007fc0でのレガシヌむメヌゞからのカヌネルのブヌト...
 200621.87870画像名オングストロヌム/ 3.2.18 /ビヌグルボヌン
 200621.88761むメヌゞタむプARM Linux Kernel Imageuncompressed
 200621.88761デヌタサむズ3083368バむト= 2.9 MiB
 200621.94465ロヌドアドレス80008000
 200621.94465゚ントリポむント80008000
 200621.94465チェックサムの怜蚌... OK
 200621.94465 XIPカヌネルむメヌゞ... OK
 200622.33156 OK
 200622.33156
 200622.33156カヌネルの起動...
 200622.33156
 200622.33157 Linuxの圧瞮解陀...完了、カヌネルの起動。
 200622.99351-runit$Id25da3b86f7bed4038b8a039d2f8e8c9bbcf0822b $起動䞭。
 200622.99351-runitステヌゞに入りたす/ etc / runit / 1
 200624.07955-runitステヌゞを離れる/ etc / runit / 1
 200624.07955-runitステヌゞに入りたす/ etc / runit / 2
 200625.41956
 200625.41957 Debian GNU / Linux 7.0 x10-02 ttyO0
 200625.41957
 200625.41957 x10-02ログむン




RUnitスクリプトの䟋



/ etc / runit / 1
 #!/bin/bash # system one time tasks PATH=/sbin:/bin:/usr/sbin:/usr/bin # re-exec this script with a controlling tty if [ "$(tty)" = "/dev/console" ]; then mountpoint -q /sys || \ mount -t sysfs sys /sys -o nosuid,noexec,nodev mountpoint -q /proc || \ mount -t proc proc /proc -o nosuid,noexec,nodev tty=$(</sys/class/tty/console/active) tty=/dev/${tty##* } exec setsid sh -c "exec bash /etc/runit/1 <$tty >$tty 2>&1" fi trap : INT TSTP QUIT trap 'sulogin -p <>$(tty) 2>&1' ERR mountpoint -q /proc || \ mount -t proc proc /proc -o nosuid,noexec,nodev mountpoint -q /sys || \ mount -t sysfs sys /sys -o nosuid,noexec,nodev mountpoint -q /dev || \ mount -t devtmpfs dev /dev -o mode=0755,nosuid test -e /dev/fd || ln -s /proc/self/fd /dev/fd exec 2> >(sed 's/^/:: /') # set -v . /etc/rc.conf mountpoint -q /run || \ mount -t tmpfs run /run -o mode=0755,nosuid,nodev mountpoint -q /dev || \ mount -t devtmpfs dev /dev -o mode=0755,nosuid mkdir -p -m0755 /run/runit /run/lock /run/user /dev/pts /dev/shm \ /run/network /run/runit mountpoint -q /dev/pts || mount -n -t devpts devpts /dev/pts -o mode=0620,gid=5,nosuid,noexec mountpoint -q /dev/shm || \ mount -n -t tmpfs shm /dev/shm -o mode=1777,nosuid,nodev mkdir -p -m 0755 /var/lib/supervise mountpoint -q /var/lib/supervise || \ mount -n -t tmpfs tmpfs /var/lib/supervise -o mode=1777,nosuid,nodev #mkdir -p -m 0755 /var/log #mountpoint -q /var/log || \ # mount -n -t tmpfs tmpfs /var/log -o mode=1777,nosuid,nodev mount -o remount,ro / ip link set up dev lo echo $HOSTNAME > /proc/sys/kernel/hostname mount -o remount,rw / mount -a -t "nosysfs,nonfs,nonfs4,nosmbfs,nocifs" -O no_netdev #cp /var/lib/random-seed /dev/urandom &>/dev/null || true #( umask 077; dd if=/dev/urandom of=/var/lib/random-seed count=1 #bs=512 &>/dev/n ull ) install -m0664 -o root -g utmp /dev/null /var/run/utmp install -m0 /dev/null /run/runit/stopit install -m0 /dev/null /run/runit/reboot install -m0644 -o root -g utmp /dev/null /var/log/lastlog dmesg > /var/log/dmesg
      
      









/ etc / runit / 2
 #!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin exec 2> >(sed 's/^/:: /') # set -v . /etc/rc.conf # sysctl --system for i in ${DAEMONS[@]}; do d=/var/lib/supervise/${i} mkdir -p $d ${d}.log l=/var/log/${i} mkdir -p $l done exec env - PATH=$PATH \ runsvdir -P /service 'log: ...........................................................................................................................................................................................................................................................................................................................................................................................................'
      
      









/ etc / runit / 3
 #!/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin exec 2> >(sed 's/^/:: /') # set -v LAST=0 test -x /etc/runit/reboot && LAST=6 echo 'Waiting for services to stop...' sv -w196 force-stop /etc/service/* sv exit /etc/service/* stty onlcr echo Shutdown... udevadm control --exit killall5 -15 i=10; while killall5 -18 && (( i-- )) ; do echo -n .; sleep 0.5; done; echo killall5 -9 umount /tmp mount -o remount,ro / sleep 1 sync
      
      









参照資料





cr.yp.to/daemontools.html-runitの祖先DJ Bernsteinから

smarden.org/runit-runit in person

smarden.org/socklog-syslogの代替

github.com/chneukirchen/ignite-runitの䞀連のinitスクリプト

lwn.net/Articles/331818-udevdなしで生掻する方法に぀いお

metrotek.spb.ru/x10-24.html-説明したメカニズムを䜿甚する10Gスむッチ

habrahabr.ru/post/21205-Linuxの起動方法




All Articles