Vagrantの上のCentOS 6.5でyum updateした後、vagrant upで発生したエラーの原因と対処

概要

Vagrant + VirtualBoxで動かしているCentOS 6.5のVMでyum updateしたら、 その後のvagrant up実行時にエラーが出るようになったので原因を調べてみました。

$ vagrant up

(snip)

default: /vagrant => /Users/kawahara_taisuke/Documents/program/ruby/vagrant-test
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

忘れた頃にまた踏みそうなのでメモしておきます。

環境の詳細

Vagrantfileは下記の通り。

Vagrant.configure(2) do |config|
  config.vm.box = "chef/centos-6.5"
  config.vm.box_check_update = false

  config.vm.network "private_network", ip: "192.168.33.10"

  config.vm.provider "virtualbox" do |vb|
    # Don't boot with headless mode
    vb.gui = false

    # Use VBoxManage to customize the VM. For example to change memory:
    vb.customize ["modifyvm", :id, "--memory", "2048"]
  end
end

boxイメージはChef社のCentOS 6.5
https://vagrantcloud.com/chef/centos-6.5

カーネルのアップデートによってVirtualBoxのGuest Additionsが動作しなくなり、 共有フォルダのマウントに失敗して上記のエラーが出るようになっていました。

エラー発生までの手順

一回目の vagrant up は成功します。

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'chef/centos-6.5'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: vagrant-test_default_1410100159081_14315
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...

(snip)

==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => /Users/kawahara_taisuke/Documents/program/ruby/vagrant-test

(snip)

==> default: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
==> default: [2014-09-07T14:31:47+00:00] INFO: *** Chef 11.14.6 ***
==> default: [2014-09-07T14:31:47+00:00] INFO: Chef-client pid: 3272
==> default: [2014-09-07T14:31:49+00:00] INFO: Run List is []
==> default: [2014-09-07T14:31:49+00:00] INFO: Run List expands to []
==> default: [2014-09-07T14:31:49+00:00] INFO: Starting Chef Run for localhost
==> default: [2014-09-07T14:31:49+00:00] INFO: Running start handlers
==> default: [2014-09-07T14:31:49+00:00] INFO: Start handlers complete.
==> default: [2014-09-07T14:31:49+00:00] INFO: Chef Run complete in 0.050052809 seconds
==> default: [2014-09-07T14:31:49+00:00] INFO: Running report handlers
==> default: [2014-09-07T14:31:49+00:00] INFO: Report handlers complete

ゲストOSにログインして、yum updateを実行します。

$ vagrant ssh
Last login: Fri Mar  7 16:57:20 2014 from 10.0.2.2
[vagrant@localhost ~]$ sudo yum update -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
Setting up Update Process
Resolving Dependencies
--> Running transaction check
---> Package audit.x86_64 0:2.2-2.el6 will be updated

(snip)

  Verifying  : libcurl-7.19.7-37.el6_4.x86_64                                                                                                                                                                                         121/121

Installed:
  kernel.x86_64 0:2.6.32-431.23.3.el6

Updated:
  audit.x86_64 0:2.2-4.el6_5                                   audit-libs.x86_64 0:2.2-4.el6_5                             ca-certificates.noarch 0:2014.1.98-65.0.el6_5             centos-release.x86_64 0:6-5.el6.centos.11.2
  coreutils.x86_64 0:8.4-31.el6_5.2                            coreutils-libs.x86_64 0:8.4-31.el6_5.2                      cpio.x86_64 0:2.10-12.el6_5                               curl.x86_64 0:7.19.7-37.el6_5.3
  device-mapper-persistent-data.x86_64 0:0.2.8-4.el6_5         dracut.noarch 0:004-336.el6_5.2                             dracut-kernel.noarch 0:004-336.el6_5.2                    e2fsprogs.x86_64 0:1.41.12-18.el6_5.1
  e2fsprogs-libs.x86_64 0:1.41.12-18.el6_5.1                   ethtool.x86_64 2:3.5-1.4.el6_5                              glib2.x86_64 0:2.26.1-7.el6_5                             glibc.x86_64 0:2.12-1.132.el6_5.4
  glibc-common.x86_64 0:2.12-1.132.el6_5.4                     grep.x86_64 0:2.6.3-4.el6_5.1                               grub.x86_64 1:0.97-84.el6_5                               initscripts.x86_64 0:9.03.40-2.el6.centos.4
  iproute.x86_64 0:2.6.32-32.el6_5                             kernel-firmware.noarch 0:2.6.32-431.23.3.el6                krb5-libs.x86_64 0:1.10.3-15.el6_5.1                      libblkid.x86_64 0:2.17.2-12.14.el6_5
  libcom_err.x86_64 0:1.41.12-18.el6_5.1                       libcurl.x86_64 0:7.19.7-37.el6_5.3                          libss.x86_64 0:1.41.12-18.el6_5.1                         libtasn1.x86_64 0:2.3-6.el6_5
  libtirpc.x86_64 0:0.2.1-6.el6_5.2                            libuuid.x86_64 0:2.17.2-12.14.el6_5                         libxml2.x86_64 0:2.7.6-14.el6_5.2                         mysql-libs.x86_64 0:5.1.73-3.el6_5
  nfs-utils.x86_64 1:1.2.3-39.el6_5.3                          nfs-utils-lib.x86_64 0:1.1.5-6.el6_5                        nspr.x86_64 0:4.10.6-1.el6_5                              nss.x86_64 0:3.16.1-4.el6_5
  nss-softokn.x86_64 0:3.14.3-10.el6_5                         nss-softokn-freebl.x86_64 0:3.14.3-10.el6_5                 nss-sysinit.x86_64 0:3.16.1-4.el6_5                       nss-tools.x86_64 0:3.16.1-4.el6_5
  nss-util.x86_64 0:3.16.1-1.el6_5                             openldap.x86_64 0:2.4.23-34.el6_5.1                         openssl.x86_64 0:1.0.1e-16.el6_5.15                       p11-kit.x86_64 0:0.18.5-2.el6_5.2
  p11-kit-trust.x86_64 0:0.18.5-2.el6_5.2                      plymouth.x86_64 0:0.8.3-27.el6.centos.1                     plymouth-core-libs.x86_64 0:0.8.3-27.el6.centos.1         plymouth-scripts.x86_64 0:0.8.3-27.el6.centos.1
  postfix.x86_64 2:2.6.6-6.el6_5                               psmisc.x86_64 0:22.6-19.el6_5                               python.x86_64 0:2.6.6-52.el6                              python-libs.x86_64 0:2.6.6-52.el6
  selinux-policy.noarch 0:3.7.19-231.el6_5.3                   selinux-policy-targeted.noarch 0:3.7.19-231.el6_5.3         tzdata.noarch 0:2014e-1.el6                               upstart.x86_64 0:0.6.5-13.el6_5.3
  util-linux-ng.x86_64 0:2.17.2-12.14.el6_5                    wget.x86_64 0:1.12-1.11.el6_5                               yum.noarch 0:3.2.29-43.el6.centos                         yum-plugin-fastestmirror.noarch 0:1.1.30-17.el6_5

Complete!

次にvagrant haltしてvagrant upすると、下記のように失敗します。

$ vagrant halt
==> default: Attempting graceful shutdown of VM...
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2222 (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => /Users/kawahara_taisuke/Documents/program/ruby/vagrant-test
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

yum updateでカーネルが更新されたことでVirtualBoxのGuest Additionsが動作しなくなり、 vagrant up の途中で共有フォルダのマウントに失敗していた、というのがこのエラーの原因だったようです。

もう一度ゲストOSにログインして、Guest Additionsを再ビルドします。

# ビルドに必要なパッケージをインストール
$ sudo yum install -y gcc perl kernel-devel

# ビルドを実行
sudo /etc/init.d/vboxadd setup
Removing existing VirtualBox non-DKMS kernel modules       [  OK  ]
Building the VirtualBox Guest Additions kernel modules
Building the main Guest Additions module                   [  OK  ]
Building the shared folder support module                  [  OK  ]
Building the OpenGL support module                         [  OK  ]
Doing non-kernel setup of the Guest Additions              [  OK  ]

新しいVMを立ち上げた時にyum updateを一回実行しておきたい、というのはよくあると思うので、できれば自動化したいところ。 /etc/init.d/vboxadd setupはカーネルをアップデートして再起動した後でなければ意味が無いため、手順は少し複雑になります。

chefで書いてみたらこんな感じです。/etc/rc.localにスクリプトを追加した後、実行後に自己消去します。

execute 'yum-update' do
  command <<-SCRIPT
    yum update -y                        && \
    yum install -y gcc perl kernel-devel && \
    cat <<EOF >> /etc/rc.local
/etc/init.d/vboxadd setup; touch /root/.yum-updated
mv /etc/rc.local /etc/rc.local.off; sed -e '\\$d' /etc/rc.local.off | sed -e '\\$d' > /etc/rc.local; rm -f /etc/rc.local.off
EOF
    shutdown -r now
  SCRIPT
  creates '/root/.yum-updated'
end

もっとスマートな書き方がある気がする。 なお共有フォルダを有効にするには、このレシピの適用後に最低でもvagrant reloadを一回実行する必要があります。

だいぶ無理筋な感じがするので素直にyum update後のboxを作ったほうが良いかもしれません。