組込みLinux開発するとき、特定のアプリケーションを自動起動できると便利ですよね。
そんなときSystemdを活用するのがもはやセオリーになっています。
今回のブログでは、Systemdについての基本的な説明と、業務の効率化に役立つSystemdを活用したアプリの自動起動サービスの作成方法について、ハートランド・データのエンジニアに紹介してもらいます。
みなさまの参考になれば幸いです。
CONTENTS
Systemdってなに?
Systemdとは
Linuxシステムの起動処理やシステム管理を行う仕組みです。
“systemctl”するやつですね。
2010年に最初のバージョンがリリースされたので、比較的新しい技術です。(といっても古いよね…)
Systemdは現在のLinuxでは標準のinitシステムとなっており、従来のinitシステムに対して、起動を高速にし設定をシンプルにすることを狙っています。
Linux起動処理
以下の手順でLinux PCを起動します。
1. 電源投入によりBIOS起動
2. BIOSからブートローダ呼出
3. ブートローダから Linux kernel起動
4. Linux kernel が initプロセスを起動
※Systemdは”initプロセス”になります。
余談 ―Systemdより前の旧タイプの場合―
弊社内でも使用しているOpenWrtは、仕立てが古いので”systemctl”は存在しません。
初期化などの処理は”/etc/init.d”へ記述を行う旧タイプです。
“init.d”にて管理されている旧システムは、起動後 “/etc/inittab”が呼び出されます。
弊社のOpenWrtの場合は以下のような感じ。特別何かをしているわけではない。
起動したらloginします。 loginしちゃうので、コンソール接続すると誰でも中身を見ることが可能。
root@xxx:/# cat /etc/inittab ::sysinit:/etc/init.d/rcS S boot ::shutdown:/etc/init.d/rcS K shutdown ::askconsole:/bin/ash --login
sysinit : ブート時に実行するプロセス
shutdown : シャットダウン時に実行するプロセス
askconsole : 実行するヤツ ※この場合はログイン
どのようなServiceが裏で動いている?
Linux の場合、以下のコマンドを打つことでSystemdのもとで動いているServiceを確認することができます。
$ systemctl list-units --type service UNIT LOAD ACTIVE SUB DESCRIPTION kmod-static-nodes.service loaded active exited Create list of required st lightdm.service loaded active running Light Display Manager ModemManager.service loaded active running Modem Manager networkd-dispatcher.service loaded active running Dispatcher daemon for syst networking.service loaded active exited Raise network interfaces NetworkManager-wait-online.service loaded active exited Network Manager Wait Onlin NetworkManager.service loaded active running Network Manager nmbd.service loaded active running Samba NMB Daemon
※抜粋
Systemdで何ができるの?
SystemdはLinuxカーネルが起動する際(ログイン前)に動作します。これにより、特定のアプリケーションの起動などが可能になります。
応答がない場合など”service”の設定に従い、自動的に再呼び出しなどが行われます。
※デフォルト5回。デフォルト設定値は “/etc/systemd/system.conf”に記載されています。
起動したserviceがクラッシュした場合なども、Systemdは自動的に再起動を試みます。 便利ですよね。
SystemdでServiceを作ってみる
それでは、Systemdで以下の2つのServiceを作ってみたいと思います。
1.PCの起動タイミングでVNCサービスを起動する
2.PC起動時にホスト名・IPアドレスを取得し、Microsoft Teamsなどへ自動POSTする
ⅰ.VNCサービス自動起動
LinuxPCに対しリモートデスクトップ接続を試みる際は、ログインを行わないとVNC接続を行うことができません。
でもPC起動時に自動でVNCサービスを起動することが可能になれば、幸せになれます。
例)”x11vnc”を用いた場合
①まずはサービス定義用のファイルを作ります
ファイル名は何でもOKですが、わかりやすいのが良いです。
②拡張子には”.service”をつけるのがお約束
sudo gedit /etc/systemd/system/x11vnc.service
③ファイルに以下の内容を記述して保存
[Unit] Description=x11vnc (Remote access) After=network-online.target [Service] Type=simple ExecStart=/usr/bin/x11vnc -auth guess -display :0 -rfbauth /etc/x11vnc.passwd -rfbport 5900 -forever -loop -xkb -noxdamage -repeat -shared ExecStop=/bin/kill -TERM $MAINPID ExecReload=/bin/kill -HUP $MAINPID KillMode=control-group Restart=on-failure [Install] WantedBy=graphical.target
[Unit]
Description : 説明文
After : 記述されているサービスの後に実行する。この場合 “network-online.target”実行後。
[Service]
ExecStart : 起動させるアプリなどになります。
Restart : 正常起動を行わなかった場合の挙動を記述します。
一般的なサービスは死んでしまうと困るので”always”を設定しますが、この場合は “on-failure”設定。
・always : サービスが正常終了しても異常終了しても、サービスを再起動する。
・no : プロセスが終了してもプロセスを再起動しません。
・on-success : プロセスが正常終了したときにプロセスを再起動します。
・on-failure : プロセスが異常終了したときにプロセスを再起動します。
・on-abnormal : on-failure と似ていますが、終了コードによるプロセスの再起動はしません。
・on-abort : プロセスが上記4つ以外のシグナルで終了したときにプロセスを再起動します。
・on-watchdog : watchdogがタイムアウトしたときにプロセスを再起動します。
なお、短い時間で何回も再起動が発生すると再起動を諦める機能があります。
具体的には StartLimitInterval の間に StartLimitBurst の回数だけ再起動が起きると、systemd は自動的に再起動するのを止めます。
デフォルトでは 10 秒の間に 5 回まで再起動が行われ、それを超えると再起動を諦めます。
[Install]
WantedBy : リンクを張ったりする。
④Service実行できるように権限を変更する
実行権限を与えておかないと実行できないので重要です。
ファイルを読むだけなので、”644″とします。
sudo chmod 644 /etc/systemd/system/x11vnc.service
⑤systemdへ登録&起動
以下のコマンドを実行し”systemd”へ登録及び起動を行います。
sudo systemctl daemon-reload sudo systemctl enable x11vnc sudo systemctl start x11vnc
これでログオフしている状態でもVNCにて接続が可能となります!!
再起動が必要な場合やログオフしてもリモートで接続できるので、非常に便利!!しあわせ!!
ⅱ.PC起動時のホスト名・IPアドレスをMicrosoft Teamsなどへ自動POST
Wake on LAN (WoL)を使用し遠隔にてPC起動を行った場合、ホスト名やIPアドレスが分からないと接続できませんね。
PC起動時に自動的にホスト名・IPアドレスがPOSTされると、PCが起動したことを確認できると共にIPアドレスが分かるので、VNC等にて接続する際に超便利!!!
※Windowsでも起動時にPOSTできれば同様のことは可能です。
①起動時に実行されるシェルスクリプトを準備
ファイル名などは何でもOK。ひとまず “webhook.sh”を作成します。
※使えれば良いという考えのもと、お気楽にシェルスクリプトとしました。
sudo gedit /etc/webhook.sh
以下の内容を記載。
curlを用いて Teamsのチャネルにて準備しているWebhookへ通知を行う仕立て。
※WEBHOOK_URLには先に取得したhookのurlを記載すること。
シェルスクリプト内にて使用している下記変数を記載するだけで、ホスト名などを取得できるのでお手軽です。
・$(host) : ホスト名
・$(host -I) : IPアドレス
#!/bin/bash WEBHOOK_URL='[取得したhookのURL]' curl -H "Content-Type: application/json" -d "{\"title\": \"PC起動 '$(hostname)'\",\"text\": \"IP Address :'$(hostname -I)'\"}" $WEBHOOK_URL
単純にcurlでTeamsのwebhookへメッセージを飛ばしています。
POSTするだけなので、curlでなくても何でもよいです。
Teamsへの通知に関してどんなことができるのかは、Microsoftのページを参照してください。
メッセージを作成して送信する – Teams|Microsoft Learn
実行できるようにファイルの権限を変更(重要)。
ファイル実行するし面倒なので “755” !!!
sudo chmod 755 /etc/webhook.sh
②Serviceを記述
PC起動時に動作するサービスを作ります。
/etc/systemd/system/フォルダへ “rc-local.service”を作ります。
sudo gedit /etc/systemd/system/rc-local.service
以下の内容を記載。
“Restart”の設定は 1回のみPOSTするだけなので、”no-abnomal”としました。
[Unit] Description=/etc/webhook.sh [Service] ExecStart=/etc/webhook.sh Restart=no-abnormal Type=simple [Install] WantedBy=multi-user.target
サービスを有効にする。
systemctl enable rc-local.service
これで準備完了です!!
PC起動を行うと、自動的に TeamsのチャネルにPOSTされるようになりました!!
↓新規導入した AI学習モデル作成マシンの例
※ちなみに社内同一ネットワークセグメントにてRDPする場合は、”ホスト名.local”とすることでIPアドレスを指定しなくても接続可能です。
※Avahiが標準で動いているため。
まとめ
いかがでしょうか。
ご紹介したSystemdで作るホスト名・IPアドレスの自動ポストは、MacやRaspberryPiでも動作可能なので実際に使ってみると非常に便利です!
是非この記事を参考にしていただき、システム管理や開発の現場での業務の時間短縮・効率化にお役立てください!
組込みソフトのバグを解析する「動的テストツールDT+」
【 無料でみれる! 】
動的テストツールDT+ デモ動画
ソフトウェア開発者のための動的テストツール「DT+」をご紹介する動画です。
ソースコードの実行によりログを収集し、多彩な解析機能によりソフトウェアの動作をこまかく見える化。たった数クリックの解析で、関数遷移や変数の変動、カバレッジをグラフィカルに表示します。本動画では、そんなDT+の導入手法から実際の解析の様子まで、基本的な使い方をデモンストレーションいたします。