Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Nerves tips, /bin/sh & nerves_heart

Nerves tips, /bin/sh & nerves_heart

pojiro

June 16, 2022
Tweet

More Decks by pojiro

Other Decks in Technology

Transcript

  1. Nerves tips,
    /bin/sh & nerves_heart
    2022/06/16 NervesJP #26

    View Slide

  2. /bin/sh
    ● erlinit.config を使用することで、
    Erlang VM の起動前後等で linux コマンド(ex. /bin/sh)を実行できる
    ● What’s erlinit ?
    ○ This is a replacement for /sbin/init that launches an Erlang/OTP release.
    ■ /sbin/init ?
    ● 他のプロセスを起動・管理する役割を持つ PID 1 の特別なプロセス
    ● What’s erlinit.config ?
    ○ erlinit の config
    ○ Where is erlinit.config on Nerves?
    ■ /etc/erlinit.config
    ● Let’s 論よりRUN
    ○ iex) cmd “ps -wlT”
    ○ iex) cmd “cat /etc/erlinit.config”

    View Slide

  3. erlinit.config でできること
    ● ドキュメントを読もう!
    ○ https://github.com/nerves-project/erlinit#configuration-and-command-line-options
    ● Shell を起動するには? 以下が使えそう!
    ○ --pre-run-exec
    Run the specified command before Erlang starts
    ○ --run-on-exit
    Run the specified command on exit.

    View Slide

  4. erlinit.config の設定方法は二通り
    1. Overriding erlinit.config from Mix Config
    ○ config :nerves, erlinit: [hostname_pattern: "nerves-%s"] のリストに設定を追加
    ○ This can be helpful when you want to alter a couple options without having to maintain a copy
    of the entire erlinit.config from the system.
    2. Overwriting Files in the Root Filesystem
    ○ rootfs_overlay で、/etc/erlinit.config をまるっと上書きする
    ○ コピー元: deps/nerves_system_rpi4/rootfs_overlay/etc/erlinit.config
    ● 注意点: 両方同時には使えない!
    理由は、やれば分かるので Let’s 論よりRUN

    View Slide

  5. --pre-run-exec で /bin/sh を起動する
    ● rootfs_overlay/etc/erlinit.config の --pre-run-exec を
    ○ 変更前) --pre-run-exec /usr/sbin/rngd
    ○ 変更後) --pre-run-exec /bin/sh ; /usr/sbin/rngd
    ここからは、Linux の起動ログが見れたほうが状況が分かりやすいので、
    Overwriting Files in the Boot Partition を利用して cmdline の quiet を外します。

    View Slide

  6. --run-on-exit で /bin/sh を起動する(?
    ● rootfs_overlay/etc/erlinit.config の --run-on-exit を
    ○ 変更前) #--run-on-exit /bin/sh
    ○ 変更後) --run-on-exit /bin/sh
    そもそも --run-on-exit の “exit” ってどうする?
    ● :init.stop()
    ● exit() からの JCL Mode の quit

    View Slide

  7. tty iex を “exit” する
    ● :init.stop(), same as :init.stop(0)
    ○ All applications are taken down smoothly, all code is unloaded, and all ports are closed before
    the system terminates by calling halt(Status). If command-line flag -heart was specified, the
    heart program is terminated before the Erlang node terminates.
    ● exit()
    ○ Exit the current IEx session
    ● Let’s 論よりRUN

    View Slide

  8. tty iex で exit/0 すると
    Erlang の JCL Mode(Job Control Mode) に入る
    ● https://www.erlang.org/doc/man/shell.html#jcl-mode
    ● https://www.ymotongpoo.com/works/lyse-ja/ja/02_starting_out.html#id2
    “quit erlang” すると Erlang VM が終了する。

    View Slide

  9. どうなった?
    ● :init.stop すると
    ○ heart プロセスも terminate するので、ハードウェアウォッチドッグが Linux を reboot する
    ■ nerves_heart は nerves_system_br で Buildroot のパッケージとして取り込まれている の
    で、HW ウォッチドッグがあれば動作している(はず
    ● 使用されるHW ウォッチドッグ のデフォルトパスは /dev/watchdog0
    ● exit から の JCL の quitをすると
    ○ heart プロセスが Erlang VM の 終了を検知してリブートする
    ■ see.
    https://github.com/nerves-project/nerves_heart/blob/ef5c20d7e939d52c1e81a0cd4
    dfdfcf88515a961/src/heart.c#L444-L451
    ● case では R_CLOSED が該当する
    heart プロセスとHW ウォッチドッグを止めることができれば、
    --run-on-exit でも /bin/sh を起動できそう?

    View Slide

  10. watchdog? heart?

    View Slide

  11. watchdog
    ● Linux の仕組み
    ○ https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html#the-linux-watchdog
    -driver-api
    ○ A Watchdog Timer (WDT) is a hardware circuit that can reset the computer system in case of a
    software fault. You probably knew that already.
    ○ ソフトウェアの死活監視(?)検知(?)機能
    ● 試してみよう!!
    ○ echo ‘’ > /dev/watchdog0 で起こす
    ■ 起こした後は定期的(タイムアウトする前に)になでてやらないとブチギレ発生
    ■ タイムアウトは
    ○ echo ‘V’ > /dev/watchdog0 で寝かす

    View Slide

  12. watchdog が寝かせられない!!
    ● Watchdog には Magic Close feature があり、
    echo ‘V’ > [watchdog path]で止めることができます。
    ● が、Nerves では無理です。
    ○ > [ 180.633094] watchdog: watchdog0: nowayout prevents watchdog being stopped!
    ○ > [ 180.640316] watchdog: watchdog0: watchdog did not stop!
    これは CONFIG_WATCHDOG_NOWAYOUT=y としているから。

    View Slide

  13. Erlang heart
    This modules contains the interface to
    the heart process. heart sends periodic
    heartbeats to an external port
    program, which is also named heart.
    The purpose of the heart port program
    is to check that the Erlang runtime
    system it is supervising is still running.
    If the port program has not received
    any heartbeats within
    HEART_BEAT_TIMEOUT seconds
    (defaults to 60 seconds), the system
    can be rebooted.
    Erlang VM
    Linux
    heart
    heartbeats
    生きてる?もし、死んだ
    ら cmd しよう!
    Erlang VM の死活監視の仕組み
    $ erl -heart
    #別シェルで、確認できる
    $ ps auxw | grep heart

    View Slide

  14. nerves_heart
    This is a replacement for Erlang's heart
    port process specifically for
    Nerves-based devices.
    Erlang VM
    Linux
    heart
    heartbeats
    heart と watchdog による二重の死活監視
    Erlang VM と heart が同時にイカれても最後はワンワンがなんとかしてくれる
    watchdog
    pets
    If Erlang VM stopped its heartbeats,
    ● HEARTBEAT_TIMEOUT < WATCHDOG_TIMEOUT
    heart reboots the OS
    ● HEARTBEAT_TIMEOUT > WATCHDOG_TIMEOUT
    watchdog reboots the OS
    heartbeat が 来たら pet する

    View Slide

  15. 結局、--run-on-exit でも /bin/sh を起動できるの?
    ● 結論:できる!
    ○ heart プロセスが watchdog を起こすので、 heart を使わなければよい
    ■ 方法
    ● rel/vm.args.eex の以下をコメントアウトする
    -heart -env HEART_BEAT_TIMEOUT 30
    ● けど、開発中デバッグで必要になったら使うに留めるべし!!

    View Slide

  16. まとめ
    ● erlinit.config のオプション、--pre-run-exec, --run-on-exit を利用することで、
    /bin/sh を実行できることを紹介しました。
    ● --run-on-exit では、 nerves_heart を無効化しないと /bin/sh/ を実行できないこ
    とを、 heart, nerves_heart の機能から説明しました。
    Have nice Nerves days!!!
    Thank you!!

    View Slide