落穂拾い

Gleanings in my life

【ubuntu】VAIO Type P で hibernation

2009年07月29日 20時38分52秒 | Linux
VAIO Type P で ubuntu を使っていて、やりたいのに実現できていないことが二つあった。

  1. Batteryの設定 (VAIO Battery Care の代替)
  2. hibernation

一つ目は「バッテリーいたわり充電モード」などの切替をすることである。現状、Windows上の VAIO Battery Care以外では設定が変更できない。そして、これが原因で Windows VISTA を消すことができない。まさに、この機能のためだけに HDD の約半分を VISTA が占拠するという勿体なさである。

二つ目はhibernation。この記事の主題である。suspend to disk と呼ばれる機能のことだ。

VAIO Type P では suspend to RAM が順調に動作しているので、hibernation をする必要性はあまり高くはない。それがこれまで放っておいた原因である。

しかし、時には hibernation がしたくなるときもある。
VAIO Type Pの標準バッテリーでは、suspend to RAM の状態だと、おおよそ30時間くらいでバッテリーが空になってしまう(満充電の場合)。さらに「いたわり充電モード」の場合は、おおよそ24時間くらいになってしまう。

したがって、24時間くらい充電できない可能性がある場合には、電源を落としておく必要がある。
このような場面に hibernation が必要となる。

hibernation がこれまでできなかった理由は、swap がなかったからである。

ubuntu のインストーラにおまかせしてインストールすると、一切 swap を作ってくれない。昔は、RAM容量の2倍のswap領域を確保すべしなどという暗黙の掟があったような気がするのだが、時代は変わったものだ。それだけRAM容量が大きくなったということだろうか。

というわけで、手順としては swap ファイル(パーティションではない)を作成し、その swap ファイルを使うように hibernation 関連の設定をするということになる。

swapファイルの作成


参考にしたのはhttp://wiki.geteasypeasy.com/Fix:_hibernateである。ここでは / ディレクトリに隠しファイルとして .hibernate.img という名前でswapファイルを作成することにする。容量は搭載RAM容量2GBより少ない 768MB。通常RAM領域の大半は cache として使われているし、hibernate する際には圧縮もかかるので、2GBに大して768MB程度でも充分らしい。気になる人はもっと大きな容量を確保した方がいいだろうが、弱小な VAIO Type P のHDD容量を考えると、このくらいで我慢する方がいいかなと思う。
sudo dd if=/dev/zero of=/.hibernate.img bs=1048576 count=768
sudo mkswap /.hibernate.img 

続いて /etc/fstab に下記行を追記する。通常は swap ファイルを使わないので、自動マウントしないように設定する。
/.hibernate.img   swap  swap    noauto,defaults 0       0

これで swap ファイルの準備は完了だ。

swapファイルの場所を調べる


hibernationとは、動作中のPCの情報(要は揮発性メモリ=RAMの中身)を圧縮して不揮発性ストレージ(HDDとか)に保存する作業だ。hibernationからの復帰とは、この保存したデータを読み出して、再び RAM 上に展開することを意味する。

したがって、hibernation から復帰するには「メモリイメージを保存した場所」をきちんと指定してやる必要がある。今回は /.hibernate.img に保存するので、この場所を指定すればよい。

ただし、hibernationから復帰する前の状態では、Linux (OS)は起動し終わっておらず、当然 / パーティションもマウントされていない状態である。そのため、/.hibernate.img という名前で指定しても読み出すことができない。OSが起動していない状態でもディスクにアクセスするには、「ディスクの○○番地に保存した」という形で指示する必要がある。

これがswapパーティションであれば、パーティション名を指定するだけでよい。
しかし swap ファイルの場合は、パーティション名の他にパーティション内での位置も指定する必要がある。

というわけで、パーティション名(ID)と swap ファイルの位置の二つを調べる必要がある。
まずパーティション名は bkld コマンドで調べられる。
blkid

いくつか UUID が表示されるが、ここでは / パーティションの UUID をメモしておく。/ パーティションがどこにあるか分からない場合は mount コマンド等で調べてから bkld を実行する。

次に swap ファイルの位置を調べる。これには filefrag コマンドを使う。ちなみに root priviledge がないと調べられない。
sudo filefrag -v /.hibernate.img | grep First

上記で First Block のところに表示される数字が swap ファイルの位置である。

復帰のための準備1


/etc/initramfs-tools/conf.d/resume を編集する。ここでは UUIDが、xxxxxxx-... 、swapファイルの位置が123456の場合を示す。
RESUME=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx resume_offset=123456


復帰のための準備2:grub


起動する際に swap ファイルの場所を指定するにはカーネルオプションとして指定すればよい。ブートマネージャとして grub を使っているなら、/boot/grub/menu.lst を編集することになる。このファイルの中に
title           Ubuntu 9.04, kernel 2.6.28-14-generic
uuid            xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
kernel          /boot/vmlinuz-2.6.28-14-generic root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ro mem=2038MB quiet splash 
initrd          /boot/initrd.img-2.6.28-14-generic
quiet

といった部分があるはずだ。この中で kernel で始まる行が kernel オプションを記述する場所だ。この行の末尾に "resume_offset=123456" と追記すればよい。

しかし、これではubuntuからカーネルのアップデートがリリースされるたびにこの追記作業が必要となる。なぜなら、通常、menu.lst ファイルは update-grub コマンドによって自動的に書き換えられてしまうからだ(自動書換えを望まない場合は、当然手動で書き換えねばならないし…)。

そこで update-grub コマンドを実行したときに "resume_offset=123456" が自動で付記されるように設定する。

update-grubコマンドは、詳しくは man ページを見れば書いてあるが、デフォルトで付記する kernel オプションを menu.lst ファイル内のコメント行から読み込む。そのコメント行とは"# kopt=" で始まる行である。したがって、"# kopt=" で始まる行の末尾に "resume_offset=123456" を付記すればよい。

たとえば下記のようになる。
# kopt=root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ro mem=2038MB resume_offset=123456

"# kopt=" で始まる行は grub にとってはただのコメント行であるが、update-grub にとってはコマンド行であるので、複数行作ると混乱のもとなので注意が必要だ。

最後にこの設定を反映させる。
update-grub
update-initramfs -u

リブートすれば設定終了。

結末


hinernationのテストをする。まず、普段は使っていない swap ファイルをマウントする。
sudo swapon -a

そして gnome の電源管理メニューから「ハイバネート」を選ぶ。が、再起動がかかる…。

仕方がないので、grubのメニューが表示されたところで、電源ボタン長押し。無事(?)シャットダウンできた。

その後、電源を入れ直すと、無事復帰できた。

hibernate後、電源が落ちずに再起動してしまうのは問題だが、grubのメニューが表示されたところで電源ボタンを長押しすればなんとかなる。頻繁に hibernate するなら困りそうだが、たまのhibernateであるなら、まぁ、なんとか耐えられる範囲か。

なお、普通に shutdown しようとしても電源が落ちないという問題があるので、hibernation 時に電源が落ちず再起動するのも同じ原因なのかなと思う。あと一歩だ、ubuntu…。

コメントを投稿