Ubuntu Weekly Recipe

第639回 Ubuntuに「トラブル時に」ログインするいろいろな方法

この記事を読むのに必要な時間:およそ 10 分

ディスクをマウントせずにログインする

ストレージは消耗品です。近い将来,必ず壊れます。一番壊れてほしくないタイミングで壊れます。それはUbuntuがインストールされているHDD/SSD/eMMC/microSDであっても例外ではありません。

しかしながら前述のシングルユーザーモードでログインする方法は,必ずルートファイルシステムをマウントする必要があります。たとえストレージが壊れていなかったとしてもマウントできなければ,やはりシステムは起動できません。

そこでストレージ上のルートファイルシステムをマウントせずにシステムにログインする方法を考えてみましょう。

Initramfsに「ログイン」する

第384回でも紹介したように,Ubuntuは最初にブートローダーであるGRUBが,ストレージからカーネルと「Initramfs」を探しだし,そのふたつをメモリー上にロードした上で,システムを起動します。Initramfsにはストレージやネットワークのドライバーが同梱されているため,カーネルはこれらのドライバーをロードしつつ,システムがインストールされているストレージデバイスをマウントします。

Initramfsは「小さなUbuntu」とも言うべき簡易的なシステムです。サイズを小さく保つためにaptコマンドなどは使えませんがそれでも必要最低限のUnixライクな環境として使えます。

なお,Initramfsは一般的にカーネルと一緒に起動ディレクトリに保存されています。UEFI対応マシンならESP(EFI System Partition)と呼ばれるFAT領域となります。よってストレージそのものが動かない場合は,この方法は使えません。そもそもGRUBも起動しない状態なので注意してください。本項の手順では,あくまでESPは見えている状態(ストレージが完全に壊れているわけではない状態)を想定しています。

Initramfsは大抵の場合,なんらかの理由でルートファイルシステムをマウントできなかったときに表示されます。また,それとは別にGRUBのメニュー画面でカーネルの起動パラメーターを変更すると,InitramfsはルートファイルシステムをマウントすることなくBusyBox環境に「ログイン」します。具体的にはGRUBメニューの一番上のメニュー上で「e」を押します。

図6 起動オプションの編集画面(breakキーワード追加済み)

画像

上記のようにメニューエントリの編集画面になるので,画像のように「linux」で始まる行の最後に「break」を追加してください。基本はカーソルキーで該当する行に移動し,⁠Ctrl-e」で行末にジャンプ,その後にスペース+「break」と入力すれば良いはずです。

編集できたら,⁠Ctrl-x」でこのメニューエントリを実行します。なお,この編集結果は保存されませんので安心してください。キャンセルしたい場合は,Ctrl-c」を押します。

図7 Initramfs上のBusyBoxのプロンプト

画像

前述のとおり,このプロンプトはルートファイルシステムをマウントできなかったときにも表示されるため,過去に遭遇した人もいるかもしれません。特にRAIDを組んでいたり,特殊なドライバーが必要なストレージデバイスを使っている人は遭遇しやすいかもしれません。

さて,このBusyBoxは組み込み向けにも使われる一般的なユーティリティコマンド群をひとつのバイナリファイルにまとめたものです。端末ソフトウェアで使うコマンドのうち,一般的に頻度の高いコマンドはひととおり存在するものの,サポートしているオプション等は通常のUbuntu環境における同名のコマンドと大きく異なります。とりあえずコマンド一覧を知りたい場合はhelpと入力してください。

試しにルートファイルシステムをマウントしてみましょう。

図8 Initramfsでルートファイルシステムをマウントする例

画像

上図ではルートファイルシステムのマウントに成功していますが,意図せずInitramfs環境にログインするということは,ルートファイルシステムをマウントできないケースが大半です。実際に手作業でマウントし,出てきたエラーメッセージから原因を推測する流れになるでしょう。もし運が良ければ,fsckするだけで解決する場合もあります。blkidfdisk -lでストレージデバイスの名前を推量し,fsck デバイスファイル名してみるだけでも良いかもしれません。

ただしfsckコマンドの実行が瀕死のルートファイルシステムにとどめを刺すという可能性も否めません。どうしても重要な情報が含まれるストレージデバイスだということであれば,先にddコマンドなどでディスクイメージ化し,適当な別のストレージにバックアップを取るべきです。

一応udevが動いているので,上記のようなストレージデバイスや,他にもUSBストレージなどを接続してマウントすることも可能です。ただしInitramfsに含まれているカーネルモジュールはルートファイルシステムのそれに比べて少なめになっているので注意してください。可能であれば簡単なファイルシステム経由でコピーすれば,modprobeでロードすることも可能です。

ストレージのバックアップを取る

バックアップ用の別のストレージを用意できるなら,次の手順でルートファイルシステムがインストールされたストレージを保存できます。一般的にバックアップ用にはルートファイルシステムと同サイズのストレージを接続するのが理想的ではありますが,必ずしも準備できるとは限りません。そこである程度圧縮すれば収まることを期待して,次のように実行すると良いでしょう。

# mount /dev/sdb1 /mnt
# dd if=/dev/sda conv=sync,noerror bs=65536 | gzip -c > /mnt/host-sda.img.gz
327600+0 records in
327600+0 records out
21474836480 bytes (21 GB, 20 GiB) copied, 373.366 s 57.5 MB/s

# file /mnt/host-sdaimg.gz
/mnt/host-sda.img.gz: gzip compressed data, from Unix, original size module 2^32 0
# ls -sh /mnt/host-sda.img.gz
4.4G /mnt/host-sda.img.gz

# umount /mnt

まず/dev/sdb1は十分に容量があり,きちんと動くストレージデバイスのパーティションのファイル名です。環境によって異なるので注意してください。USBストレージなら接続した直後にdmesg | tailすれば,デバイスファイル名がわかるはずです。前述のとおりblkidを実行し,ディスクラベルから推定するという方法もあります。

/dev/sdaがバックアップを取りたいストレージデバイスそのものです。/dev/sda2のようにパーティション単位で保存しても良いですし,/dev/sdaと全体を取ってしまうという方法もあるでしょう。ddコマンドではconv=sync,noerrorによりディスクキャッシュを使わずにきちんと保存しつつ,読み込みエラーに遭遇しても継続して読み出すようにしています。

gzipコマンドによってイメージを圧縮しています。ゼロで埋められた空き領域が多いと圧縮率はあがるものの,空き領域にランダムな値が入っているとするとそこまで圧縮されません。結果的に保存先は保存元と同程度の容量のものを選んでおいたほうが安全ではあります。

ライブラリも最低限のものは用意されているので,例えばGo言語のプログラムであればバイナリ一個持ってきて実行することは可能ですし,ルートファイルシステムをマウントできるなら環境変数LD_LIBRARY_PATHにマウントしたディレクトリの共有ライブラリが存在するディレクトリを指定する方法も使えるでしょう。

ネットワークへの接続も,リカバリーモードと異なりひと手間必要です。具体的にはip linkコマンドを使ってインターフェイスをupし,dhclientコマンドを使ってIPアドレスを取得します。

図9 ipコマンドとdhclientを使ってネットワーク接続する方法

画像

wgetコマンドがあるのでネットワーク越しのファイルの取得ぐらいならできるはずです。またNFSマウントするという手もあります。固定IPアドレスを割り当てたいなら,dhclientの代わりに次のコマンドを実行することになるでしょう。

# ip addr add <IPアドレス> dev <ネットワークインターフェース>

ここでの<IPアドレス>CIDR形式で記述可能です。その他の詳細はip -hを実行してください。残念ながらUbuntu標準のInitramfsでは,WiFiに接続する簡単な方法は用意されていません。どうしても必要ならwpa_supplicantなどをInitramfsに用意する必要があります。

exitコマンドを実行すると,Initramfs環境を抜けて通常の起動を行います。単に電源を切りたいだけならpoweroffコマンドを使ってください。

Initramfs環境は上記で指定した「break」以外にもさまざまなカーネルの起動パラメーターを設定することで挙動を変更できます。詳しいことはman initramfs-toolsを実行して表示される情報を参照してください。

USBデバイスからブートし,ストレージ領域にログインする

前項とは逆にブート領域(ESPやその上のカーネルなど)のデータがおかしくなり,ルートファイルシステムは無事な状況を考えてみましょう。独自ビルドのカーネルやサードパーティのカーネルモジュールを使用した結果,起動途中にカーネルパニックするケースも該当します。もしくはWindowsとデュアルブートしているときにGRUB領域を書き潰してしまうこともあるかもしれません。他にもUEFIなシステムでインストールしたストレージをそのままレガシーBIOSで起動しようとしたり,その逆だったりすると,同じように起動できません※5⁠。

※5
純粋なカーネルの問題であれば,GRUBメニューを表示して古いカーネルを選択したり,悪影響を与えていそうなデバイスを取り外すだけで,とりあえず復旧できる可能性は高いです。原因となるモジュールにあたりがついているなら,GRUBのメニューエントリの編集画面で,linux行の末尾にmodprobe.blacklist=モジュール名を指定するだけで回避できます。

このような状況においては,UbuntuのライブインストーラーをインストールしたUSBデバイスで起動し,そこからもともとのストレージ領域をマウントし,リカバリーを試みるのが一番簡単です。最近ではデスクトップ版だけでなくサーバー版のインストーラーもライブ環境に対応しています。CLIの操作に慣れているのであれば,サーバー版のインストーラーで起動し,⁠Ctrl-Alt-Fx」で別の仮想コンソールに切り替えた上で,操作すると良いでしょう。

一般的なリカバリー手順に従えば回復できる場合は,UbuntuのライブインストーラーよりはSystemRescueのようなリカバリーに特化したイメージを使ったほうが楽な場合も多いです。やりたいことがはっきりしている場合はまずはSystemRescueの利用を検討してください。

手元にUbuntuのライブインストーラーがあってそれをそのまま使いたいとか,ストレージの中身を取り出したいだけなら,Ubuntuのライブインストーラーでも良いでしょう。特に後者であれば,ライブインストーラーで起動し,外部ストレージをマウントしたら,あとは前項の「ストレージのバックアップを取る」と手順は一緒です。デスクトップ版のUbuntuを使っているなら,イメージバックアップに対応したGUIツールをインストールして使うという手もあります。本連載を「バックアップ」で検索すればいろいろでてきますので,使い方にあわせて好みのものを選ぶと良いでしょう。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。