目的
Raspberry Pi 3 ModelB で外付けHDDを停止してから終了(shutdownなど)させるようにしたい1
環境
Raspberry Pi 3 ModelB
作業メモ
外付けHDDの動作を止める
ちなみに外付けHDDのマウント方法については、こちらの投稿を参照
参考サイト
https://linux.die.net/man/8/sdparm
- コマンドのインストール
$ sudo apt-get install sdparm
- 外付けHDDを動作停止
fdisk
コマンドなどでHDDのブロックデバイスを調べて停止させてみる
$ sudo fdisk -l
(略)
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 1953520064 1953518017 931.5G 7 HPFS/NTFS/exFAT
$ sudo sdparm --command=stop /dev/sda1
- rebootしてみる
$ sudo reboot
効果なし・・。終了時に異音がする
USBポートの電源OFF
もっと根本的なところに立ち返って、USBポートの電源OFFを試してみる
参考サイト
http://s.webry.info/sp/vogel.at.webry.info/201711/article_2.html
-
hub-ctrl
のインストール
$ sudo apt-get install libusb-dev
$ wget http://www.gniibe.org/oitoite/ac-power-control-by-USB-hub/hub-ctrl.c
$ gcc -O2 hub-ctrl.c -o hub-ctrl-armhf-static -lusb -static
$ sudo mv hub-ctrl-armhf-static /usr/local/bin/hub-ctrl
- BUSやPORTの番号を調べる2
$ lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/5p, 480M
|__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=smsc95xx, 480M
|__ Port 5: Dev 4, If 0, Class=Mass Storage, Driver=usb-storage, 480M
分かりづらい場合はこちらで調べる
$ udevadm info --query=path --name=/dev/sda1
/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.5/1-1.5:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1
--name=path
のpath
は調べたいブロックデバイス名
1-1.5
が該当箇所になる
- デバイスの取り外しをする
$ echo -n "1-1.5" | sudo tee /sys/bus/usb/drivers/usb/unbind
確認すると、以下が無くなっており取り外されたことが分かる
Port 5: Dev 4, If 0, Class=Mass Storage, Driver=usb-storage, 480M
$ lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/5p, 480M
|__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=smsc95xx, 480M
- 該当ポートの電源OFF
$ sudo hub-ctrl -b 1 -d 2 -P 5 -p 0
-b
がBUS、-d
がDevice、-P
がPORTの数字を入れる
-p
は0がOFF、1がON
- rebootしてみる
$ sudo reboot
効果あり!終了時の異音がなくなった
Serviceとして登録する
これで目的達成でもいいが、このままだと毎回手動で処理しないといけないので、システムのサービスとして登録してみる
参考サイト
https://qiita.com/DQNEO/items/0b5d0bc5d3cf407cb7ff
-
init
がどの仕組みで動いているか確認
init
は起動/終了処理を司るプロセスで、ディストリビューションやバージョンによって使われている仕組みが違うらしい(あまり詳しくない)
そのため、どの仕組みで動いているか確認する
$ ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.6 27096 6128 ? Ss 4月20 0:03 /sbin/init splash
(略)
$ ls -l /sbin/init
lrwxrwxrwx 1 root root 20 7月 6 2017 /sbin/init -> /lib/systemd/systemd
どうやらsystemd
という仕組みで動いているらしい
- サービスの作成
参考サイトの内容を見ると、今回やりたいことからすると、**.serviceというサービスを作って、それが終了時に呼ばれるようにすればよさそうだと分かった
まず、hdd_off.service
については以下のようにした
[Unit]
Description=hdd off for shutdown and reboot
Before=shutdown.target
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/usr/bin/hdd_off.sh
RemainAfterExit=true
[Install]
WantedBy=shutdown.target
ざっくり説明すると、shutdown/reboot/halt時に1度だけ外付けHDDの電源をOFFする、ようにした
以下、ちゃんとした説明
shutdown.target
がshutdown/reboot/halt全てのタイミングで関連づけられているため、このtargetが呼ばれる時に実行する設定にした
Before=shutdown.target
WantedBy=shutdown.target
外付けHDDの電源をOFFするスクリプトを作り、サービス起動時に実行するようにする
ExecStart=/usr/bin/hdd_off.sh
ちなみにスクリプトhdd_off.sh
については長くなるので、内容の記載は割愛する
- 作成したファイルの配置
ファイルの権限などを変更して
$ sudo chown root:root hdd_off.sh
$ sudo chown root:root hdd_off.service
$ sudo chmod +x /usr/bin/hdd_off.sh
必要な場所に配置する
どうやらユーザー設定のサービスは/etc/systemd/system
に置くのがお作法らしい
$ sudo mv hdd_off.sh /usr/bin/
$ sudo mv hdd_off.service /etc/systemd/system/
- サービスとして認識されているか確認
$ sudo systemctl list-unit-files --type=service | grep hdd_off
hdd_off.service disabled
サービスとして認識されていればいいので、disabled
でOK
- 動作確認
$ sudo systemctl start hdd_off
$ sudo systemctl stop hdd_off
ちなみにサービスの動作確認だけが目的だったので、外付けHDD未接続の状態で試した
$ sudo systemctl status hdd_off
● hdd_off.service - hdd off for shutdown and reboot
Loaded: loaded (/etc/systemd/system/hdd_off.service; disabled; vendor preset: enabled)
Active: inactive (dead)
4月 21 10:44:26 raspberrypi systemd[1]: Starting hdd off for shutdown and reboot...
4月 21 10:44:26 raspberrypi sudo[1201]: root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/sbin/blkid
4月 21 10:44:26 raspberrypi sudo[1201]: pam_unix(sudo:session): session opened for user root by (uid=0)
4月 21 10:44:26 raspberrypi sudo[1201]: pam_unix(sudo:session): session closed for user root
4月 21 10:44:26 raspberrypi hdd_off.sh[1199]: HDD is nothing
4月 21 10:44:26 raspberrypi systemd[1]: Started hdd off for shutdown and reboot.
4月 21 10:44:29 raspberrypi systemd[1]: Stopped hdd off for shutdown and reboot.
ログを確認すると、hdd_off.sh
が実行され、HDD未接続時のログが出ているのでOK
4月 21 10:44:26 raspberrypi hdd_off.sh[1199]: HDD is nothing
- サービスの有効化
$ sudo systemctl enable hdd_off
Created symlink /etc/systemd/system/shutdown.target.wants/hdd_off.service → /etc/systemd/system/hdd_off.service.
- 自動で外付けHDDの電源がOFFになってくれるか確認
$ sudo reboot
いい感じで電源OFFでrebootしたように見える!
一応ログで確認したいので、syslog
の出力を確認してみる
$ less /var/log/messages
が、それとわかるようなログは見当たらなかった
どうやらsystemd
のログはsyslog
には出力されないらしい?
この辺はよく分からないので、調査が必要
まとめ
目的は達成!のはず
Raspberry Pi 3 ModelB で外付けHDDを停止してから終了(shutdownなど)させるようにしたい
終了時にHDDからの異音はなくなったが、ログでそれが確認できなかった。
その点は課題として残っている