はじめに
Armadillo-X1,Armadillo-IoT G3/G3L(以降Armadilloと記載)で、USBメモリが接続された時のイベントを検知する方法を紹介します。
Linuxではデバイスの状態変化があった時、カーネルからイベント通知(uevent)が送信されます。USBメモリが接続された時のイベントを検知するには、このueventを取得する方法が一般的です。今回は例として、Armadilloに接続したUSBメモリのデバイス名が、udevのrulesファイルに設定したデバイス名と一致した時に、USBメモリデバイスを/mntにマウントさせます。
USBメモリのデバイス名を取得する方法
まず、ArmadilloにUSBメモリを接続してください。接続完了後、lsコマンドを用いてUSBメモリのデバイス名を確認します。
root@armadillo:~# ls /dev/sd[a-z] /dev/sda root@armadillo:~#
lsコマンドの実行結果より、USBメモリのデバイス名がsdaであることがわかります。
udevのrulesファイルを作成する
udevのrulesファイルを作成します。これは、udevdに送信されたueventに対して、対象のUSBデバイスの識別方法等を記述するものです。
rulesファイルを作成します。
root@armadillo:~# vi /etc/udev/rules.d/10-device-connect-test.rules
rulesファイルは、先程取得したデバイス名を元に以下のように記述して下さい。
ACTION=="add", \ SUBSYSTEMS=="usb", \ KERNEL=="sda", \ RUN:="/etc/udev/device-connect-test.sh"
rulesファイルに記載された各キーの役割について、以下に説明を記載します。
・ACTION:イベントを発生させたアクションの名前を照合します。今回はUSBメモリ接続時にアプリを実行するためaddを設定します。
・SUBSYSTEMS:一致するデバイスサブシステム名を検索します。今回はUSBメモリのデバイスサブシステム名であるusbを設定します。
・KERNEL:イベントによって影響を受けるデバイス名を照合します。今回は先程取得したsdaを設定します。
・RUN:実行するコマンドを設定します。今回は後述する/etc/udev/device-connect-test.shの実行を設定します。
追加したrulesファイルを適応させます。
root@armadillo:~# udevadm control --reload
実行するシェルスクリプトの作成
USBメモリが接続された時に、実行するテストアプリを作成します。今回は以下のシェルスクリプトで試します。
このシェルスクリプトは、USBメモリデバイスが接続された際にmountを行う単純な処理となります。
root@armadillo:~# vi /etc/udev/device-connect-test.sh
シェルスクリプトは以下のように実装します。
#!/bin/bash mount /dev/sd[a-z][0-9] /mnt
作成したシェルスクリプトに実行権限を与えます。
root@armadillo:~# chmod +x /etc/udev/device-connect-test.sh
systemd-udevd.service 設定変更
使用しているLinuxのバージョンが「Linux-4.9: Debian GNU/Linux 9 (stretch) 」である場合、systemd-udevd.serviceの設定を変更する必要があります。
以下のようにMountFlags=slaveをMountFlags=sharedに変更してください。
root@armadillo:~# vi /lib/systemd/system/systemd-udevd.service # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=udev Kernel Device Manager Documentation=man:systemd-udevd.service(8) man:udev(7) DefaultDependencies=no Wants=systemd-udevd-control.socket systemd-udevd-kernel.socket After=systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-sysusers.service Before=sysinit.target ConditionPathIsReadWrite=/sys [Service] Type=notify OOMScoreAdjust=-1000 Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket Restart=always RestartSec=0 ExecStart=/lib/systemd/systemd-udevd KillMode=mixed WatchdogSec=3min TasksMax=infinity MountFlags=shared MemoryDenyWriteExecute=yes RestrictRealtime=yes RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
設定変更後、systemd-udevd.serviceの再起動を行います。
root@armadillo:~# systemctl restart systemd-udevd
詳細は以下のmanページをご確認ください。
・systemd.exec manページ
http://man7.org/linux/man-pages/man5/systemd.exec.5.html
・mount manページ
http://man7.org/linux/man-pages/man2/mount.2.html
動作確認
USBメモリをArmadilloに接続して下さい。USBメモリ接続後、/tmpにUSBメモリがmountされていることを確認して下さい。
root@armadillo:~# mount | grep sda /dev/sda1 on /mnt type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)