試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

Gentoo Linux上のuswsuspについての覚え書き(UUID指定による休止を行う)

Debian/Ubuntuではinitrdの関係で比較的簡単にできたUUIDによるパーティション指定は、Gentoo Linuxではできなくはないものの色々と面倒だった。ここでは、その手順についてをメモしておく。

genkernelのinitrdをベースにする

http://gentoo-wiki.com/HOWTO_Userspace_Software_Suspend_(uswsusp)
に書かれているinitrdでは、(復帰に使用するパーティションを示す)ラベルやUUIDを処理して「/dev/hda7」のような(ブロック)デバイス名に名前解決する処理をしていないため、このまま指定することは無理であることや、通常起動時の「/」のファイルシステムに関しても同様に処理できないこともあり、genkernelの作成するinitrdをもとに、必要なものを追加する方向で作業をする。

genkernelのパッチ当て

http://bugs.gentoo.org/show_bug.cgi?id=156445
のパッチをもとに色々試した*1ところ、どうもスワップパーティションを使用したときには、復帰するときの起動時にそのパーティションが見えない(?)ようで、ラベルやUUIDからデバイス名に名前解決するbusyboxの組み込みコマンドfindfsなどを実行しても出てこず*2、実際のデバイス名が得られないため、手動で具体的なデバイス名を指定しないと復帰できない。
そこで、スワップパーティションとして使用していた領域を通常のファイルシステムとしてフォーマットし、その中にスワップ「ファイル」を配置するという形で試したところ、initrd内のスクリプトを多少いじることでラベルやUUIDによる指定からの復帰ができるようになった。
変更したスクリプトはgenkernelの中に含まれる形のため、genkernelに対するパッチとなる。これを当てた後に作成されたinitrdでは、uswsuspのスワップ「ファイル」に限り、これを含んだパーティションのラベルかUUIDによる指定が可能になる。
パッチと修正ebuild
http://cid-3f9be5b1cd4a806c.skydrive.live.com/browse.aspx/%e5%85%ac%e9%96%8b/Gentoo%20Linux%20ebuild/sys-kernel/genkernel
以下に作成、アップロードした。
下の作業は全て、このパッチの適用されたgenkernelを使用していることを前提としている。
genkernelの実行時には「--suspend」オプションを付けることでinitrdにuswsuspを組み込んでくれる。
(2008/5/14)splashutils 1.5.4.1でsplash_geninitramfsの場所が変わったことによりinitrdにfbsplash関係のファイルが入らなくなってしまった問題に対処(3.4.9-r1としてアップロード)
(2008/6/28)genkernelのバージョン3.4.10-r1向けのパッチとebuildを追加

スワップファイルを使用した準備の流れ

下の例では、パーティション/dev/hda7をスワップ用に使用するものとする(環境に応じて変更する)。

ファイルシステムの作成とマウント
$ sudo mkfs.ext3 -m 0 -L swap -T largefile4 /dev/hda7
$ sudo mkdir /media/swap
$ sudo mount -t ext3 /dev/hda7 /media/swap
スワップファイルの作成

パーティション全体を使用したファイルにするため、わざと大きな値を指定した。

$ sudo dd if=/dev/zero of=/media/swap/swap.dat bs=1G count=[大きな値]
dd: writing `/media/swap/swap.dat': デバイスに空き領域がありません
(以下略)

自動的に止まり、ファイルのサイズが最大になる。もちろん、bs=count=を適切に指定することで好みのサイズに指定することもできる。
次に、mkswapスワップとして初期化する。

$ sudo mkswap /media/swap/swap.dat
パーティション内の位置情報を取得

このファイルを消したり、パーティションの初期化を行ったりすると値は変わるので注意。

$ sudo sh -c 'swap-offset /media/swap/swap.dat >> /etc/suspend.conf'

/etc/suspend.confに「resume offset」行が既にあれば、古いものは消しておく。

uswsuspの設定ファイルでのUUID指定

ファイル名: /etc/suspend.conf

resume device = /dev/disk/by-uuid/[スワップを作成したパーティションのUUID]

ここで使用するUUIDは、スワップを含んだファイルシステムのほうのUUIDで、mkswap時に表示されたUUIDは使用しない。

自動マウントの設定

ファイルシステム名やマウントオプションなどは環境によって調整。
ファイル名: /etc/fstab

UUID=[スワップを作成したパーティションのUUID] /media/swap ext3 noatime 0 1
/media/swap/swap.dat none swap sw 0 0
スワップを有効にする
$ sudo /sbin/swapon -a

ここまでで準備はほとんどできているのだが、/dev/disk/by-uuid/以下のシンボリックリンクが間違っていることがあるため、一度再起動する(あるいは手動でリンクを修正)。

カーネル引数/ブートローダの設定

initrdがカーネル引数のreal_resumeの値を解析するようになっている。busyboxfindfsによる名前解決をこの値に対して行うため、下のような形での指定になる。

title  Gentoo Linux
root (hd0,4)
kernel /kernel quiet root=UUID=[「/」パーティションのUUID] video=uvesafb:1280x1024-32,mtrr:3,ywrap maxvf:60 splash=silent,theme:livecd-2007.0 console=tty1 real_resume=UUID=[スワップファイルを含むパーティションのUUID]
initrd /initrd.cpio.gz
boot
uswsuspをinitrdに組み込む(手動で行う場合)

以下の作業はパッチの当たったgenkernel--suspendオプションを付けることで不要になる(組み込み済みinitrdが作成される)。しかし、設定ファイル/etc/suspend.confを変更した場合は設定反映のために作業を行う必要がある*3
追加するのは復帰のための実行ファイル/usr/lib/suspend/resumeと設定ファイル/etc/suspend.confの2つ。/dev/snapshotはinitrd内のスクリプトが必要に応じて自動的に作成する。

$ mkdir work/initrd.d -p
$ fakeroot bash
fakeroot# cd work/initrd.d/
fakeroot# zcat /boot/initrd.cpio.gz | cpio -idm --quiet -H newc
fakeroot# cp /usr/lib/suspend/resume bin/
fakeroot# cp /etc/suspend.conf etc/
fakeroot# find | cpio --quiet -L -o -H newc | gzip -9 > ../out.cpio.gz
$ sudo cp work/out.cpio.gz /boot/initrd.cpio.gz
$ rm work/ -fr
テスト

これでhibernate-scriptもしくはs2diskの直接実行により、休止と復帰をテストする。もしfbsplashを使用している場合、復帰時のカーネルへの引数からsplash=を一時的に外しておくと情報のメッセージが見られ、問題が起きたときの助けになる。
手元の環境では、ここまでを行ったところでUUID指定をした場合の休止と復帰が無事に確認できた。

関連記事:

使用したバージョン:

  • uswsusp 0.8(suspend 0.8)
  • hibernate-script 1.97(1.97-r4)
  • genkernel 3.4.9 + 独自パッチ

*1:uswsuspのファイルは手動で組み込んだ

*2:復帰をせずに通常起動してblkidを実行してもこのパーティションだけ見えない状態

*3:設定変更の反映の場合、/etc/suspend.confの上書きだけで、/usr/lib/suspend/resumeはコピーする必要はない