2015年11月10日火曜日

スタンドアロンになってしまった RaspberryPi を救う方法

概要

想定ケースとしては

  • RaspberryPi (RPi) は常に無線 LAN に接続しており他のマシンから SSH でログインして操作していた

という状況で突如無線 LAN が停止してログインできなくなったときに救うケースを考えてみます

環境

  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)

最終手段

いきなりですが、最終手段です
どうしても RPi を操作できる状況にできない場合は、ネットワークが復旧したあとで電源プラグを引っこ抜いて再起動するしかないと思います

電源を直接抜いてシャットダウンすると SD カードが破損して最悪 OS 起動しなくなったりデータが正確に保存されないなどのリスクがあります
自分は一度だけ OS が起動しなくなり SD カードをフォーマットしなおしたことがありますが、ほぼ遭遇したことはありません
なので「どうしても」というケースでは実施して問題ないと思います

今回は上記を最終手段として、それまでに救えるいくつかの方法を検討していきます

キーボードおよびディスプレイを使って救出する

おそらくこれが一番メジャーだと思います
キーボードしかない場合も想定して復旧方法を検討します

有線のキーボードおよびディスプレイに接続できる状況

この状況があれば一番救える確率が高いです
キーボードは USB でディスプレイは HDMI とします

この場合はまずそのままキーボードとディスプレイを RPi に接続します
で、キーボードから何かしらの信号を送れば HDMI 側にも信号が飛んで RPi の CUI が表示されればそのまま救出完了になります
( RPi の OS のバージョンが Raspbian Jessie だった場合はデフォルトが GUI なのでキーボードの Tab や Alt 十字キーを使ってターミナルを起動するなりして救う必要があります、キーボードが HHK で十字キーボードがないとか OS のキーボード配列の設定が違うとか問題に遭遇する可能性もありますが、そうなったら頑張るしかないです )

ですが、キーボードとディスプレイを接続して信号を送ってみたのにディスプレイ側に信号が来ないなんてことに遭遇すると思います
RPi は起動時にディスプレイが繋がっていれば HDMI の出力を ON にするのですが、HDMI が繋がっていない状態で電源を ON にすると HDMI の出力が行われません
( 自分の場合は上記に該当しており、デフォルト GUI だった OS を CUI の状態にしたら発生しました )
その場合は画面が見えない状態でキーボードで HDMI の出力を ON にするコマンドを実行しなければいけません
コマンドは以下の通り

  • tvservice -o
  • tvservice -p
  • fbset -depth 8
  • fbset -depth 24

簡単に説明するとディスプレイの出力を OFF -> ON して画面のフレームバッファの設定を 8 -> 24 に変更します
このコマンドを画面が真っ暗な状態で、想像しながらタイプする必要があります
間違ってタイプした場合は Ctrl + e -> Ctrl + u を駆使して一旦クリアした後で再度冷静にタイプしましょう
タイプが成功して HDMI への信号が ON になれば画面が表示されて救出完了になります

あとコマンドをいきなり実行できる状態で RPi が起動していればいいのですが、pi ユーザで一度ログインしないとダメな場合には、そこから想像しながらタイプする必要があるので若干難易度があがります

どうしても画面が表示されない場合は「sudo reboot」もありです
もしくは「sudo shutdown -h now」でシャットダウンして RPi 上の LED が点滅しないことを確認して電源を抜いてから再起動でも問題ないと思います

有線のキーボードはあるがディスプレイがない

これは、上記の通り想像しながらキーをタイプするしかないと思います
ディスプレイがないのでディスプレイに出力してもしょうがないのでこの場合は

  • sudo reboot

or

  • sudo shutdown -h now

のどちらかを頑張ってタイプして復旧させるしかないと思います
そしてこの場合は GUI だと終わります
さすがに GUI をキーボード Only で想像しながらタイプするのは無理があります

頑張ってタイプしても再起動しない、停止しないという場合は、キーボード自体の信号が送信されていない可能性があるかもしれません
例えば PPi を電池やモバイルバッテリーで動かしている場合に充電が足りずに RPi に十分な電圧が加わらず USB ポートが正常に動作しないなどが考えられます
RPi は通常 5V (家庭用の電源コンセント) の電圧がかかることを想定しています

ディスプレイはあるが無線キーボードしかない

例えば Bluetooth の無線キーボードだけある状況です
基本は有線と変わらず接続できたら停止 or 再起動コマンドを想像しながら発行するということしかできません

ただ、無線の場合は有線に比べて信号を送るまでの難易度があがります
まず RPi に Bluetooth レシーバが接続されていることが絶対条件です
これがないと終了です
レシーバがあり無線キーボードがアドバタイズできる状況であるならば救える可能性はあります

が、ここからもハードルが高いです
RPi の場合 Bluetooth キーボードと接続するにはキーボードとペアリングするためのコマンドを発行する必要があります
(参考 : RaspberryPi で Bluetooth キーボードを接続する方法, RaspberryPi の bluetoothctl で無線キーボードに接続 )
一度接続したキーボードは trust することで自動で再接続してくれるオプションがあるのですが、このオプションは RPi が起動する場合でないと使えません
なので RPi が起動中に Bluetooth キーボードが接続できる範囲にきても自動で接続してくれません

ではどうするか、ですが自分は以下のスクリプトを cron で回す設定を事前に行っています
bluetoothctl と expect で無線キーボードに定期的に接続するスクリプト

ここまで事前に用意できていて初めて無線キーボードが使えるようになります
有線に比べてかなりハードルが高いので、緊急時はできれば有線キーボードを準備してください

キーボードもディスプレイもない

これは相当厳しいです
最悪 PC があればなんとかなります (後述) が、この場合は電源 OFF をするしかないです

PC を持っている場合

一台 PC を持っている場合に救出できる方法がないか検討します

シリアル通信を使う

RPi の GPIO を使って RPi 上の信号を PC に表示します
ただ、シリアル通信をするのであれば PC 以外に以下の機材が必要になります

  • ジャンパケーブル
  • FTDI シリアル - USB 変換アダプタ
  • USB ケーブル

やり方や機材等の詳細はこちらを御覧ください
シリアル通信に必要な機材はこれ以外のパターンもたくさんあります
が、とりあえず PC だけでは無理です

そしてシリアル通信の最大の弱点は PC を停止した状態で配線しないと信号が受け取れない点にあります
・・・そう、起動している RPi だと結局シリアル信号をモニタすることができないのです

じゃあなんで紹介したんだとなりますが、1 つは電源での OFF -> ON 後にとりあえず正常に動作しているか確認したい場合に使えます
もう 1 つは実は起動した状態でシリアル通信できる方法があると誰かが教えてくれのではと、思ったからです
もしかしたら、あとで調べたらあっさり方法がわかるかもしれませんが

最後に

RPi は一度セットアップしてサーバとして動かすのであれば電源だけあれば OK で省スペースなのですが、いざぶっ壊れて対応しなければいけないときに、とたんにハードルと必要になる機材が増えるようなイメージがあります

しょうがないと言えば確かにしょうがないですが、もっとスマートな方法はないものだろうかと思いました

0 件のコメント:

コメントを投稿