組込みLinux開発するとき、特定のアプリケーションを自動起動できると便利ですよね。
そんなときSystemdを活用するのがもはやセオリーになっています。

今回のブログでは、Systemdについての基本的な説明と、業務の効率化に役立つSystemdを活用したアプリの自動起動サービスの作成方法について、ハートランド・データのエンジニアに紹介してもらいます。
みなさまの参考になれば幸いです。

CONTENTS
  1. Systemdってなに?
  2. どのようなServiceが裏で動いている?
  3. Systemdで何ができるの?
  4. SystemdでServiceを作ってみる
    1. VNCサービス自動起動
    2. ホスト名・IPアドレスの自動ポスト
  5. まとめ
 

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でも動作可能なので実際に使ってみると非常に便利です!
是非この記事を参考にしていただき、システム管理や開発の現場での業務の時間短縮・効率化にお役立てください!

【 無料セミナー 】
デバドラ作成に疲れたエンジニアのための『Linuxカーネルとアプリの挙動トレース』

組込みLinuxシステムの挙動解析には、ログの収集やあらゆるデバッグ情報を得ることが重要。
しかし現場では「原因の切り分けが困難」「print文で力業」なんて事態も。
そこで、デバドラやprint文に依存しないLinuxシステムのより効率的な挙動解析をご紹介します。

お申し込みはこちら!