LoginSignup
12

More than 5 years have passed since last update.

Raspberry Pi 3 のshutdown時に自動で外付けHDDを停止させる

Last updated at Posted at 2018-04-30

目的

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=pathpathは調べたいブロックデバイス名
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については以下のようにした

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からの異音はなくなったが、ログでそれが確認できなかった。
その点は課題として残っている



  1. ぶっちゃけるとumountしてshutdownすればいいだろうと思っていたのだが、そんな簡単じゃなかったので、まじめに方法を考える羽目になりました 

  2. udevadmで調べたときに、1-1.2に接続されているとうまく電源OFFできなかった。理由は不明 

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12