LoginSignup
4
3

More than 5 years have passed since last update.

OpenStack(Mitaka)で、EFI起動させてみる

Last updated at Posted at 2017-03-18

■自分の環境
・ホストサーバ:ubuntu 16.04
・libvertのバージョン:1.3.1
・OpenStack:mitaka

■必須環境
・libvertのバージョン:1.2.9以上
・OpenStack:mitaka以上であること

■対象とする読者
OpenStack環境はすでにできているが、仮想サーバをEFI起動させたいという方に向けて書いています。
自分はなかなかハマってしまったので、備忘として。
やることがわかっていれば、簡単なのでしょうが、仮想化の初心者なので。。。

大きく分けて、3つの作業を行います。
1.KVMで、EFI起動できるようにする。
2.Glanceへのイメージ登録時に、EFI起動の設定を加える。
3.起動ファイルの再作成(バグ?対応。本当はいらない作業)

■参考にしたURL
また、今回の調査にあたり、以下のサイトや記事を参考にさせていただきました。
みなさま、ありがとうございます。
OpenStackドキュメント - Boot From UEFI image
uefi_bootsupport_techtip_final.pdf
OpenStackドキュメント - Images and instances
QEMU の為の UEFI ファームウェアのビルド手順
libvirt の UEFI 設定
第441回 QEMU/KVMでUEFIファームウェアを使う

それでは、始めていきます。
(EFI起動は、OpenStackのMitakaからの対応らしいので、ご注意を)

1.KVMで、EFI起動できるようにする。

自分はOpenStackの仮想サーバを、KVMで実行しているのですが、
KVMは、デフォルトではEFI起動はせず、BIOSでの起動となってしまうようです。
Horizonで作成したインスタンスを起動しようとすると、
エラーメッセージが出てきて、なんだか切ない気持ちになります。
スクリーンショット 2017-02-24 19.02.31.png

そこで、まずはKVMでもEFI起動できるようにしていきます。
その前にlibvertのバージョンを調べます。

・libvirtのバージョン確認

$ virsh version
コンパイル時に使用したライブラリ: libvirt 1.3.1
使用中のライブラリ: libvirt 1.3.1
使用中の API: QEMU 1.3.1
実行中のハイパーバイザー: QEMU 2.5.0

libvirtのバージョンが1.2.9以上であることを確認してください。

バージョンに問題がなければ、KVMでEFI起動できるようにするための「OVMF」をインストールします。

・OVMFをインストール

$ sudo apt install ovmf

・何かできている
以下のコマンドを打って、それぞれ2つのファイルができていることを確認します。

$ ls /usr/share/OVMF/
OVMF_CODE.fd
OVMF_VARS.fd

これで、KVM側の作業は終了です。

2.Glanceへのイメージ登録時に、EFI起動の設定を加える。

Glanceへのイメージの登録の際に、EFI起動するための指定が必要です。
Horizonでは、設定項目がなさそうなので、コマンドラインから、Glanceの登録を行います。

・glanceイメージを登録
(筆者はvdiファイルを取り込んだので、file、disk-formatなどは環境に合わせた値に変換してください。)

$ openstack image create "NAME" --file XXXXXXXXXX.vdi --disk-format vdi --container-format bare --property hw_firmware_type=uefi --public

「--property hw_firmware_type=uefi」がポイント!
このpropertyを指定しないと、OpenStack側は、EFI起動せず、BIOSで起動させようとしてしまうので、注意してください!

MySqlでglanceユーザでログインし、「image_properties」テーブルを参照してみてください。
先ほど登録したGlanceイメージのpropertyが、name:hw_firmware_type、 value:uefiで登録されていることを確認します。

$ sudo mysql glance

MariaDB [glance]> select * from image_properties;
+----+--------------------------------------+-------------- ---+-------+---------------------+---------------
| id | image_id | name | value | created_at | updated_at >| deleted_at | deleted |
+----+--------------------------------------+------------- ----+-------+---------------------+---------------
| 1 | xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | hw_firmware_type | uefi | 2017-01-01 04:57:31 | 2017-01-01 04:57:31 | NULL | 0 |
+----+--------------------------------------+-------------- ---+-------+---------------------+---------------

これで、準備はOK。

その前に。。。

・driver.pyをちょっと見てみる
先ほど設定した「--property hw_firmware_type=uefi」はどのように使用されるのでしょうか。
そのヒントは、以下のpyファイルに書かれているようです。

$ view /usr/lib/python2.7/dist-packages/nova/virt/libvirt/driver.py

driver.py

(前略)
DEFAULT_UEFI_LOADER_PATH = {                          ←①
    "x86_64": "/usr/share/OVMF/OVMF_CODE.fd",
    "aarch64": "/usr/share/AAVMF/AAVMF_CODE.fd"
}

(中略)

            if hw_firmware_type == fields.FirmwareType.UEFI:    ←②
                if self._has_uefi_support():
                    global uefi_logged
                    if not uefi_logged:
                        LOG.warn(_LW("uefi support is without some kind of "
                                    "functional testing and therefore "
                                    "considered experimental."))
                        uefi_logged = True
                    guest.os_loader = DEFAULT_UEFI_LOADER_PATH[    ←③
                        caps.host.cpu.arch]
                    guest.os_loader_type = "pflash"
                else:
                    raise exception.UEFINotSupported()
            guest.os_mach_type = self._get_machine_type(image_meta, caps)
(後略)

①の部分にて、「DEFAULT_UEFI_LOADER_PATH」の指定が、
OVMFをインストールされた際にできた「OVMF_CODE.fd」に指定されていることがわかります。
これが、EFI起動するためのローダーとなるのでしょう。

さらに、いつこのPATHを使うかというと、
②の「if hw_firmware_type == fields.FirmwareType.UEFI」ブロックの中。
hw_firmware_typeや、UEFIなどの記載があります。

はい、先ほど指定したpropertyの値ですね。
おそらく、fields.FirmwareType.UEFIは、固定文字でuefiとなっているのでしょう。
このif文に入った際に、③でguest.os_loader = DEFAULT_UEFI_LOADER_PATHとあります。

きっとこれで、EFI起動するためのお膳立てはできているはず!

3.起動ファイルの再作成

・まだダメだった
これで普通にインスタンス作成すれば、起動すると思いきや!!

謎のエラーメッセージが出て起動しない!!
スクリーンショット 2017-02-24 22.49.59.png

ここで数時間試行錯誤。

で、ふと思い、KVM側の設定を確認してみる。

$ virsh list
Id |名前 |状態
----------------------------------------------------
20 |instance-00000001 |実行中

・設定を確認
以下のコマンドで、VMの起動設定のXMLファイルを、確認/編集することができます。

$ virsh edit <インスタンス名>

virshコマンド実行
(前略)
  <os>
    <type arch='x86_64' machine='pc-i440fx-xenial'>hvm</type>
    <loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader>
    <nvram template='/usr/share/OVMF/OVMF_CODE.fd'>/var/lib/libvirt/qemu/nvram/インスタンス名_VARS.fd</nvram>
    <boot dev='hd'/>
    <smbios mode='sysinfo'/>
  </os>
(後略)

あれれ? 参考にしたサイトと、表示が異なっている!!
「<nvram template='/usr/share/OVMF/OVMF_CODE.fd'>」となっている!?
「<nvram template='/usr/share/OVMF/OVMF_VARS.fd'>」になると思っていたのに!!

こちらのサイトでは、
OVMF_CODE.fdは、ファームウェアの指定で、
OVMF_VARS.fdは、nvramの指定、と説明されていました。
上記の設定は、nvramのテンプレートにOVMF_CODE.fdが設定されている。
うーん。もしかして設定が変なことになってしまっている???
ここは、OpenStack側が、自動で設定する項目のはずなのに。

・仕方ないので、起動ファイルを再作成
すでにOVMF_CODE.dfをテンプレートとして起動ファイルが作成されてしまっているため、
OVMF_VARS.dfをテンプレートとして作成するようにします。

まずは、すでに作成されているファイルがあると、再作成されないため、リネームする。

$ sudo mv /var/lib/libvirt/qemu/nvram/instance-00000001_VARS.fd /var/lib/libvirt/qemu/nvram/instance-00000001_VARS.fd_bk

以下のコマンドで、<os>部分のパラメータを書き換えます。

$ virsh edit <インスタンス名>

virshコマンド実行
(前略)
  <os>
    <type arch='x86_64' machine='pc-i440fx-xenial'>hvm</type>
    <loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader>
    <nvram template='/usr/share/OVMF/OVMF_VARS.fd'></nvram>
    <boot dev='hd'/>
    <smbios mode='sysinfo'/>
  </os>
(後略)

・再作成

$ virsh start <インスタンス名>

・設定を確認

$ virsh edit <インスタンス名>

virshコマンド実行
(前略)
  <os>
    <type arch='x86_64' machine='pc-i440fx-xenial'>hvm</type>
    <loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader>
    <nvram template='/usr/share/OVMF/OVMF_VARS.fd'>/var/lib/libvirt/qemu/nvram/インスタンス名_VARS.fd</nvram>  ←値が変更されていることを確認
    <boot dev='hd'/>
    <smbios mode='sysinfo'/>
  </os>
(後略)

・いけんじゃねーか
ということで、あとは、コマンドラインでも、Horizonからでも、普通にインスタンスを作成すれば、EFI起動がなされます。
スクリーンショット 2017-02-26 16.43.07.png

本当は、XMLファイルを作成するスクリプトを編集すればスマートなのでしょうが、そこまでは追っていません。
また、今回はmitakaで試しましたが、最新版では解消されているかも??

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3