カーネル関連のブートの問題から Azure Linux 仮想マシンを回復する方法

この記事では、カーネルの変更を適用した後に Linux 仮想マシン (VM) を再起動できない問題の解決策を示します。

元の製品バージョン:   Linux を実行している仮想マシン
元の KB 番号:   4091524

現象

Azure 上の Linux 仮想マシン (VM) に特定のカーネルの変更 (カーネル アップグレードなど) を適用した後、VM を再起動できます。 起動プロセス中に、次のいずれかのカーネル エラーがログに記録されます。

  • 次のような "ルート デバイスが見つかりません" エラー。

    dracut Warning: No root device "block:/dev/disk/by-uuid/UUID" found
    dracut Warning: Boot has failed. To debug this issue add "rdshell" to the kernel command line.
    dracut Warning: Signal caught!
    Kernel panic - not syncing: Attempted to kill init!
    Pid: 1, comm: init Not tainted 2.6.32-504.12.2.el6.x86_64 #1
    Call Trace:
    [<ffffffff8152933c>] ? panic+0xa7/0x16f
    [<ffffffff8107a5f2>] ? do_exit+0x862/0x870
    [<ffffffff8118fa25>] ? fput+0x25/0x30
    [<ffffffff8107a658>] ? do_group_exit+0x58/0xd0
    [<ffffffff8107a6e7>] ? sys_exit_group+0x17/0x20
    [<ffffffff8100b072>] ? system_call_fastpath+0x16/0x1b
    
  • 次のようなカーネル タイムアウト エラー。

    INFO: task swapper:1 blocked for more than 120 seconds.
    Not tainted 2.6.32-504.8.1.el6.x86_64 #1
    "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
    swapper       D 0000000000000000     0     1      0 0x00000000
    ffff88010f64fde0 0000000000000046 ffff88010f64fd50 ffffffff81074f95
    0000000000005c2f ffffffff8100bb8e ffff88010f64fe50 0000000000100000
    0000000000000002 00000000fffb73e0 ffff88010f64dab8 ffff88010f64ffd8
    Call Trace:
    [<ffffffff81074f95>] ? __call_console_drivers+0x75/0x90
    [<ffffffff8100bb8e>] ? apic_timer_interrupt+0xe/0x20
    [<ffffffff81075d51>] ? vprintk+0x251/0x560
    [<ffffffff8152a862>] schedule_timeout+0x192/0x2e0
    [<ffffffff810874f0>] ? process_timeout+0x0/0x10
    [<ffffffff8152a9ce>] schedule_timeout_uninterruptible+0x1e/0x20
    [<ffffffff81089650>] msleep+0x20/0x30
    [<ffffffff81c2a571>] prepare_namespace+0x30/0x1a9
    [<ffffffff81c2992a>] kernel_init+0x2e1/0x2f7
    [<ffffffff8100c20a>] child_rip+0xa/0x20
    [<ffffffff81c29649>] ? kernel_init+0x0/0x2f7
    [<ffffffff8100c200>] ? child_rip+0x0/0x20
    
  • 次のような null ポインター エラー。

    Pid: 242, comm: async/1 Not tainted 2.6.32-504.12.2.el6.x86_64 #1
    Call Trace:
    [<ffffffff81177468>] ? kmem_cache_create+0x538/0x5a0
    [<ffffffff8152aede>] ? mutex_lock+0x1e/0x50
    [<ffffffff81370424>] ? attribute_container_add_device+0x104/0x150
    [<ffffffffa009c1de>] ? storvsc_device_alloc+0x4e/0xa0 [hv_storvsc]
    [<ffffffff8138a1dc>] ? scsi_alloc_sdev+0x1fc/0x280
    [<ffffffff8138a739>] ? scsi_probe_and_add_lun+0x4d9/0xe10
    [<ffffffff8128e62d>] ? kobject_set_name_vargs+0x6d/0x70
    [<ffffffff8152aede>] ? mutex_lock+0x1e/0x50
    [<ffffffff81370424>] ? attribute_container_add_device+0x104/0x150
    [<ffffffff81367ae9>] ? get_device+0x19/0x20
    [<ffffffff8138b440>] ? scsi_alloc_target+0x2d0/0x300
    [<ffffffff8138b661>] ? __scsi_scan_target+0x121/0x740
    [<ffffffff8138bd07>] ? scsi_scan_channel+0x87/0xb0
    [<ffffffff8138bde0>] ? scsi_scan_host_selected+0xb0/0x190
    [<ffffffff8138bf51>] ? do_scsi_scan_host+0x91/0xa0
    [<ffffffff8138c13c>] ? do_scan_async+0x1c/0x150
    [<ffffffff810a7086>] ? async_thread+0x116/0x2e0
    [<ffffffff81064b90>] ? default_wake_function+0x0/0x20
    [<ffffffff810a6f70>] ? async_thread+0x0/0x2e0
    [<ffffffff8109e66e>] ? kthread+0x9e/0xc0
    [<ffffffff8100c20a>] ? child_rip+0xa/0x20
    [<ffffffff8109e5d0>] ? kthread+0x0/0xc0
    [<ffffffff8100c200>] ? child_rip+0x0/0x20
    BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
    IP: [<ffffffffa009c0a0>] storvsc_device_destroy+0x20/0x50 [hv_storvsc]
    PGD 0
    
  • 次のようなカーネル カーネル エラー。

    Invalid op code: 0000 [#2] [11427.908676] - end trace 61a458bb863d7f0f ]-
    Kernel panic - not syncing: attempted to kill the idle task!
    

解決方法

ヒント

VM の最新のバックアップがある場合は、バックアップから VM の復元を試み、起動の問題を解決することができます。

Azure 上の Linux VM を回復するには、次のいずれかの修復オプションを使用して、新しいカーネルをインストールするか、以前のバージョンに手動でロールバックする必要があります。

このアクションを実行するには、次の手順を使用します。影響を受ける Linux VM を削除し、オペレーティング システム ディスクを保持してから、影響を受ける VM の同じバージョン (または少なくとも同じ配布) を持つ新しい VM にディスクを接続します。 次に、次のいずれかの修復オプションを使用します。

修復オプション 1

カーネルをロールバックし、構成ファイルを編集して以前の動作中のセットアップから開始します。 詳細については、「構成ファイルを 更新する方法」を参照してください

注意

Linux ブート ローダーには、通常、起動に使用するカーネルを定義する複数のエントリがあります。 新しくインストールされたカーネルを参照するアップグレードを実行すると、エントリが更新されます。

修復オプション 2

影響を受ける VM オペレーティング システム ディスクを一時的な新しい VM に接続し、apt-get、(YUM)、などのツールを実行して、カーネルをインストールまたは再インストール Yellowdog Updater Modified します Zypper 。 詳細については、「Linux の回復: CHROOT の手順を使用してアクセスできない VM を回復する」を参照してください

注意

ファイルを手動で編集する必要はないので、この 2 つ目のオプションが修復を行う最適な方法です。

VM が以前のカーネルから起動できない場合は、initramfs ファイルの再構築を試みてから、Linux カーネルの新しい圧縮イメージをコピーできます。 詳細については 、initramfs ファイルを再構築する方法を参照してください

詳細情報

構成ファイルについて

uname -a コマンドを 使用すると、 すべてのシステム情報を取得できます。 たとえば、CentOS 6.6 を実行している Linux VM にカーネル バージョン 2.6.32-504.16.2.el6.x86_64 が読み込まれている場合、次の出力が表示されます。

Linux vfldev 2.6.32-504.16.2.el6.x86_64 #1 SMP Date\Time x86_64 x86_64 x86_64 GNU/Linux

ブート ローダー構成ファイルには、読み込まれるカーネル バージョンに関する情報が含まれています。 CentOS のファイルは /boot/grub/grub.conf で、RHEL 7 の新しいバージョンは /boot/grub2/grub.cfg です。

grub.conf ファイルの最初の 4 行には、現在読み込まれているバージョンに関する次の情報が含まれています。

  • title: メニューにのみ表示されるタイトルを指定します (クラウド環境には適用されません)。
  • root: ルート パーティションを指定します。
  • kernel: 起動時に読み込まれるカーネル コマンド ラインとそのパラメーターを指定します。
  • initrd: 起動するために読み込まれる initrd ファイルのパスを指定します。通常はカーネルのインストール パスと一致します。

Linux カーネルの異なるバージョンの grub ファイルの例を次に示します。

title CentOS (2.6.32-504.16.2.el6.x86_64)
root (hd0,0)
kernel /boot/vmlinuz-2.6.32-504.16.2.el6.x86_64 ro root=UUID=UUIDrd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off console=ttyS0 earlyprintk=ttyS0 rootdelay=300 crashkernel=auto
initrd /boot/initramfs-2.6.32-504.16.2.el6.x86_64.img
title CentOS (2.6.32-504.12.2.el6.x86_64)
root (hd0,0)
kernel /boot/vmlinuz-2.6.32-504.12.2.el6.x86_64 ro root=UUID=UUIDrd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off console=ttyS0 earlyprintk=ttyS0 rootdelay=300 crashkernel=auto
initrd /boot/initramfs-2.6.32-504.12.2.el6.x86_64.img
title CentOS (2.6.32-504.8.1.el6.x86_64)
root (hd0,0)
kernel /boot/vmlinuz-2.6.32-504.8.1.el6.x86_64 ro root=UUID=UUIDrd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off console=ttyS0 earlyprintk=ttyS0 rootdelay=300 crashkernel=auto
initrd /boot/initramfs-2.6.32-504.8.1.el6.x86_64.img
title CentOS (2.6.32-431.29.2.el6.x86_64)
root (hd0,0)
kernel /boot/vmlinuz-2.6.32-431.29.2.el6.x86_64 ro root=UUID=UUIDrd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off console=ttyS0 earlyprintk=ttyS0 rootdelay=300
initrd /boot/initramfs-2.6.32-431.29.2.el6.x86_64.img

構成ファイルを更新する方法

ブート ローダー (grub.conf) を変更し、Linux VM に別のカーネルを強制的に読み込むには、手動による介入が必要です。 このアクションを実行するには、次のいずれかのメソッドを使用します。

方法 1: シリアル コンソール

シリアル コンソールは、この問題を解決する最速の方法です。 これにより、回復 VM にシステム ディスクを表示することなく、問題を直接修正できます。 配布に必要な前提条件を満たしていることを確認します。 詳しくは 、Linux 用の仮想マシン シリアル コンソールに関するページをご覧ください。 シリアル コンソールにアクセスした後、軽減策の手順に 進みます。 軽減策の手順が完了したら、VM を再起動します。

方法 2: オフライン修復

VM でシリアル コンソールが有効になっていない場合、または動作しない場合は、次の手順に従ってシステムをオフラインで修復できます。

  1. VM のシステム ディスクをデータ ディスクとして回復用 VM (任意の動作中の Linux VM) に接続します。 これを行うには 、CLI コマンドまたは VM 回復 スクリプトを使用します
  2. 軽減策セクションの手順に従います。
  3. 元の仮想ハード ディスクのマウントを解除してデタッチし、元のシステム ディスクから VM を作成します。 これを行うには 、CLI コマンドまたは VM 回復 スクリプトを使用します

軽減策の手順

  1. ファイルを変更 /mnt/troubleshootingdisk /boot/grub.conf します。 変更された grub.conf ファイルの例を次に示します。

    #title CentOS (2.6.32-504.16.2.el6.x86_64)
    
    #root (hd0,0)
    
    #kernel /boot/vmlinuz-2.6.32-504.16.2.el6.x86_64 ro root=UUID=UUID rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off console=ttyS0 earlyprintk=ttyS0 rootdelay=300 crashkernel=auto
    
    #initrd /boot/initramfs-2.6.32-504.16.2.el6.x86_64.img
    
  2. ブート ローダー ファイル grub.conf の UUID 値で指定されたデバイスが存在するかどうかを確認します。

    たとえば、探してマウントされているシステム ディスクを確認すると /mnt/troubleshootingdisk 、grub.conf ファイルで参照されている対応する UUID ファイルがディスク上に存在しているのを確認できます。 /mnt/troubleshootingdisk /dev/disk/by-uuid ファイルは、実際には、オペレーティング システムのディスク sda1 を指している lrwxrwxrwx 属性の最初の文字 l で示されるシンボリック リンクです。 ファイルが見つからない場合は、システムの起動時にシンボリック リンクを作成し換えることができます。

  3. sda1 がスタートアップ デバイスであり、対応する UUID がわかっている場合は、次のコマンドを実行してシンボリック リンクを手動で作成できます。

    cd /mnt/troubleshootingdisk/dev/disk/by-uuid ln -s ../../sda1 UUID
    

    注意

    sda1 ファイルは Linux のブロック デバイスと呼ばれるファイルです。 これは、属性の文字で示されているコマンド出力 ls b で確認 brw-rw-- できます。

  4. このファイルが CentOS 6.5 に存在するかどうかを確認し、見つからない場合はファイルを再作成できます。 たとえば、次のコマンドを実行します。

    cd /mnt/troubleshootingdisk/dev/disk/by-uuid ls -ltr ../../sda1
    

    出力は次のようになります。

    brw-rw-- 1 root disk 8, 1 Date\Time ../../sda1
    

    次のコマンドを使用して、ファイルの種類を確認できます。

    file ../../sda1 ../../sda1: block special
    

initramfs ファイルを再構築する方法

initramfs ファイルとカーネル ファイルは、次のように例の grub ファイル (前のセクション) で確認できます。

  • Initramfs ファイル

    initrd /boot/initramfs-2.6.32-504.16.2.el6.x86_64.img

  • カーネル ファイル

    /boot/vmlinuz-2.6.32-504.16.2.el6.x86_64

通常、回復 CD オンプレミス環境からシステムを起動します。 ただし、クラウド環境では、システム ディスクを同じオペレーティング システムとバージョンの一時 VM に接続して、システム ファイルを回復または操作して、起動を行う必要はありません。 initramfs ファイルとカーネル ファイルをコピーまたは作成し直す場合に必要です。

注意

オペレーティング システム ディスクを /mnt/troubleshootingdisk 上の一時 VM に接続した後 (最初にオペレーティング システム ディスクからコピーしてデータを保護します)、以前に行った変更を grub.conf に戻します (再び起動する最初のカーネルを参照するエントリをコメント アウトしていた場合)。

initramfs ファイルを再構築するには、次の手順を実行します。

  1. 既存のバージョンに基づいて initramfs ファイルを生成します。

    mv /mnt/troubleshootingdisk/boot/initramfs-2.6.32-504.8.1.el6.x86_64.img /mnt/troubleshootingdisk/boot/initramfs-2.6.32-504.8.1.el6.x86_64.old-img dracut /mnt/troubleshootingdisk/boot/initramfs-2.6.32-504.8.1.el6.x86_64.img 2.6.32-504.8.1.el6.x86_64

    たとえば、まったく同じ initramfs ファイルが見つからないので、一時的な CentOS 6.6 Linux VM で利用可能な最新バージョンをビルドして使用する必要があります。

  2. 関連する vmlinuz ファイルをコピーし、grub.conf ファイルを更新して新しいカーネル値を反映します。 これを行うには、次の表のコマンドを使用します。

Command 出力
ls -ltr /lib/modules/ drwxr-xr-x. 7 root root 4096 Date 2.6.32-431.11.2.el6.x86_64
drwxr-xr-x. 7 root root 4096 Date 2.6.32-431.17.1.el6.x86_64
drwxr-xr-x. 7 root root 4096 Date 2.6.32-431.29.2.el6.x86_64
drwxr-xr-x. 7 root root 4096 Date\Time 2.6.32-504.1.3.el6.x86_64
drwxr-xr-x. 7 root root 4096 Date\Time 2.6.32-504.12.2.el6.x86_64
dracut /mnt/troubleshootingdisk/boot/initramfs-2.6.32-504.12.2.el6.x86_64.img 2.6.32-504.12.2.el6.x86_64
ls -ltr /mnt/troubleshootingdisk/boot/initramfs-2.6.32-504.12.2.el6.x86_64.img
-rw---. 1 root root 19354168 Date\Time /mnt/troubleshootingdisk/boot/initramfs-2.6.32-504.12.2.el6.x86_64.img
cp /boot/vmlinuz-2.6.32-504.12.2.el6.x86_64 /mnt/troubleshootingdisk/boot/
ls -ltr /mnt/troubleshootingdisk/boot/vmlinuz*
-rwxr-xr-x. 1 root root 4128368 Date\Time /mnt/troubleshootingdisk/boot/vmlinuz-2.6.32-431.el6.x86_64
-rwxr-xr-x. 1 root root 4128688 Date\Time /mnt/troubleshootingdisk/boot/vmlinuz-2.6.32-431.3.1.el6.x86_64
-rwxr-xr-x. 1 root root 4129872 Date\Time /mnt/troubleshootingdisk/boot/vmlinuz-2.6.32-431.17.1.el6.x86_64
-rwxr-xr-x. 1 root root 4131984 Date\Time /mnt/troubleshootingdisk/boot/vmlinuz-2.6.32-431.29.2.el6.x86_64
-rwxr-xr-x. 1 root root 4153008 Date\Time /mnt/troubleshootingdisk/boot/vmlinuz-2.6.32-504.8.1.el6.x86_64
-rwxr-xr-x. 1 root root 4152720 Date\Time /mnt/troubleshootingdisk/boot/vmlinuz-2.6.32-504.12.2.el6.x86_64
vi /mnt/troubleshootingdisk/boot/grub/grub.conf title CentOS (2.6.32-504.12.2.el6.x86_64)
root (hd0,0)
kernel /boot/vmlinuz-2.6.32-504.12.2.el6.x86_64 ro root=UUID=UUID rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet numa=off console=ttyS0 earlyprintk=ttyS0 rootdelay=300
initrd /boot/initramfs-2.6.32-504.12.2.el6.x86_64.img