始めは些細な勘違いだった。 コンパクトフラッシュを挿したまま、ハイバネートしようとしたら、 クラッシュした。
盛大に i/o エラーが出たので、きっと swap のパーティションがとんだんだと 勘違いした。 実際にはパーティションは無事で、不良セクタなども一切なく、 第一、そういう事が起きる時には必ずあるような、 事故のしばらくまえから発生する I/O エラーも syslog には全く記録されていなかったし、 書き込みにやたらな時間がかかって変な音がする事もなかったのだが。 だが、焦っていたのでこれを確かめる事をしなかった。
パーティションに何か書き込むとエラーが出るかどうか、 直ちに確かめて見るべきだと思った私は、 そのためにどんなコマンドが使えるかを調べることなく、 本当に当該ブロックデバイスにデータを書き込んでみた。
私が本当にやりたかったことは、ブロックデバイスに無意味なデータを 書き込む事ではなく、入出力が正常に行われるかどうかをテストする、 という事であり、それは無意味なデータをデバイスに実際に書き込む事に よってのみ達成される、というようなものではない。 だが、時差ボケと連日の追い込みでアホになっていた私は、 そういう判断ができなくなっていた。
その結果、私が実行した愚劣窮まり無いコマンドとは以下の如きものだ。 良い子は真似しないでくささい。データがなくなります。
dd if=/dev/zero of=/dev/sda7
sda7が swap デバイスである。 無事、書き込めた(デバイスが壊れているわけではないので、当り前だが)。 すると、 sda7 は swap デバイスとして認識されなくなってしまった。 壊れてないのに壊れてしまったわけである。うっわ。むっちゃ謎。 完全に理解不能。
じつは、swap デバイスは先頭何ページかが、こんな内容になってないと いけないのである。
sudo od -a /dev/sda7 | head 0000000 y nl y nl y nl y nl y nl y nl y nl y nl * 0002000 soh nul nul nul & + enq nul nul nul nul nul 7 us y W 0002020 x s O 2 syn % ' ack stx v syn % nul nul nul nul 0002040 nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul * 0007740 nul nul nul nul nul sp U nl nul nul nul nul S W A P 0007760 S P A C E 2 S W A P S P A C E 2 0010000 nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul
SWAPSPACE2 とか書いてある。 dd 閣下に任せておくと、 こんなものは根こそぎであることは言うまでもない。 その結果、ハイバネートも動かなくなった。 あらゆる動かなくなるのは当然の結末といえよう。 こうなると、えらい便利悪いがな。
さて、この愚行からの復旧であるが、デバイスが正常であることを badblocks コマンドで確認したら、 mkswap /dev/sda7 で復活である。
mrmt さんありがとうございました。
/var/cache/apt 以下には deb が一時的に保管されていて、 明示的に消去しないかぎり古い版が残っている。 これは、ディスクに余裕さえあれば、問題が発生したときにいつでも 問題のなかった以前の版に戻せる事を意味するのであり、 安心できて具合が良いのだが、 実際に戻すとなると dpkg -i ファイル名 などのコマンドを実行する事になり、 これは勝手に依存関係を処理してくれないので、 多くのパッケージを処理する必要が生じた場合は大変だ。
もしこのディレクトリ以下にあるものも apt が管理してくれると そのへんも楽になるのだが‥ というのは誰しもが思うところであり、 そのための段取りをこのほど、 Debian パッケージ著者のやまだあきらさんにうかがうことができた。
/etc/apt/sources.list に追加する予定のパス(仮に /path/to/dir とする) を作成し、そこに移動して
apt-ftparchive packages /var/cache/apt/archives > ./Packages
というのを実行すると、キャッシュの中身が Packages に書き込まれる。 /etc/apt/sources.list に
deb file:///path/to/dir ./
を追加して apt-get update すればいい。 古い版をインストールするときは
aptitude install パケジ=バージョン
で古い版を指定してインストールしなおせる。
apt-cache policy パケジ
で念のためバージョンの値確認し、表示されている文字列をそのまま全部 コピペして指定すると間違い無い感じ。
やまだあきらさん、いつもありがとうございます。