うちではFreeBSDをインストールしたPCをファイルサーバにしています。今は2TB以下のハードディスクを使っているのでパーティションテーブルはMBRですが、そのうち3TBのディスクに入れ替えようと思っていて、そのためにBIOSからでもGPTのディスクを起動できることを前回確認しました。

ところで、現在HDDのパーティションは下記のような構成にしています(実際にはgeliやらバックアップやらでもう少し複雑ですが、コンセプトはまあこんな感じ)。

  • ad0
    • s1
      • a (/)
      • b (swap)
    • s2
      • a (/)
      • b (swap)
    • s3
      • a (/)
      • b (swap)
    • s4
      • e (/home)

OSがバージョンアップするたびにクリーンインストールするのが好みなので、最初はs1にインストールし、バージョンアップがあるとs2にインストール、次はs3、その次はs1に戻るという具合に、3世代でローテーションするようにしています。こうしておくと、何かのはずみで現環境が動かなくなったときでもとりあえず前の世代でしのいだり、そこから復旧作業できたりして便利です。で、このs1/s2/s3のどれを起動するかを、MBRのboot0で選択しています。

しかし、GPTを使う際にProtective MBRに書きこむ/boot/pmbrは、boot0のように立ち上げ時に起動パーティションを選択する機能がありません。freebsd-ufsのパーティションをいくつ作っても、デフォルトでは一番最初に見つかったものが使われてしまいます。

そこで、GPTのbootme属性で同じような運用ができるか試してみました。

実験機で、まずfreebsd-ufsパーティションを2つもつように設定します。

Fixit# gpart show ad0
=>       34  117210173  ad0  GPT  (56G)
         34        128    1  freebsd-boot  (64K)
        162    2097152    2  freebsd-swap  (1.0G)
    2097314   41943040    3  freebsd-ufs  (20G)
   44040354   73169853    4  freebsd-ufs  (35G)

ad0p3とad0p4に両方FreeBSD-8.2-RELEASEをインストールします。このまま起動すると、ad0p3から立ち上がります。その状態でfreebsd-updateを実行し、ad0p3のカーネルだけ8.2-RELEASE-p3にアップデートしました。ad0p4のカーネルは8.2-RELEASEのままなので、起動時のログをみればどちらがロードされているかがわかります。

ここで、gpart setを使ってad0p4にbootme属性を付加します。

# gpart set -a bootme -i 4 ad0
bootme set on ad0p4
# gpart show ad0
=>       34  117210173  ad0  GPT  (56G)
         34        128    1  freebsd-boot  (64K)
        162    2097152    2  freebsd-swap  (1.0G)
    2097314   41943040    3  freebsd-ufs  (20G)
   44040354   73169853    4  freebsd-ufs  [bootme]  (35G)

gpart showで確認すると、[bootme]という属性が付いているのがわかります。

この状態でPCを再起動すると、確かにad0p4のカーネルがロードされました。これで起動パーティションの指定はなんとかなりそうです。

ところで、いつも使ってるパーティションをいじってたら起動しなくなり、急遽別のパーティションから起動させたい、というような場合はどうすればいいのでしょうか。bootme属性を付け替えてやればいいので、Fixitから起動させてgpart unsetで現パーティションのbootmeを落とし、gpart setで旧パーティションにbootmeを付けて再起動、とすれば確かに切り替え可能ですが、いかにも面倒です。MBR時代のboot2には、起動するパーティションやカーネルをプロンプトから指定する機能がありましたが、gptbootにも同じ機能があれば、それが使えそうです。

それを確認するため、ad0p4にbootmeが付いた状態のままマシンを再起動し、loaderがロードされる前(「FreeBSD」のアスキーアート文字が出る前)の、- \ | / がクリクリ回っている状態のときにキーボードの任意のキーを押してみます。すると、boot2と同様に下記のプロンプトが表示されました。

-
FreeBSD/x86 boot
Default: 0:ad(0p4)/boot/loader
boot:

ここでad0p3を指定すれば、そこから起動できそうです。

boot: 0:ad(0p3)/boot/loader

上記を指定すると、8.2-RELEASE-p3のカーネルが起動しました。ちゃんとad0p3から起動しているということです。これで、bootme属性を無視した起動も可能であることが分かりました。

デフォルトで起動するパーティションの指定と緊急時の切り替えができれば、GPTでも今までと同レベルの運用ができそうです。GPTではパーティションを最低でも128個は作れるので、やろうと思えばOSを100世代持つなんてこともできそうですね(なんの意味があるのかはさておき……)。

※バージョンメモ

  • FreeBSD 8.2-RELEASE