先日O3のハンズオンに参加した際にLagopusのビルドで幾つか嵌ったので
その際に調べた対処方法を纏めてみます。
ハンズオンで利用したLagopusやDPDKのバージョンは古いし
今後は必要なくなるかもしれないけれど念のため。
当日使用した環境
ハンズオン当日はMBA上のイカの仮想化環境を使用していました。
ちなみにゲストOSはUbuntu14.04 のBox(自家製)。
Item | Version |
---|---|
Vagrant | 1.6.5 |
VirtualBox | 4.3.18 |
ビルド対象のLagopusとDPDKのバージョンはイカの通りです。
Item | Version |
---|---|
DPDK | 1.7.0 |
Lagopus | 0.1.1 |
一応ここで軽く説明しておくと、今回の問題はVM環境のCPUのサポート機能とvagrantのboxが原因なので
ネイティブ環境にインストールするなら多分問題ないと思います。
あと、ハンズオンで指定されるアーカイブが上記バージョンのためこのバージョンを利用しましたが、
同一環境でもDPDK 1.7.1とLagopus 0.1.1なら問題なくビルドできることを確認しました。
Lagopusインストール
対処をいれるところ含めて、Lagopusインストール全体の流れを説明します。
ここに記載する内容は基本的にイカのハンズオン資料に基づいています。
http://lagopus.github.io/handson/handson.pdf
ハンズオン用ファイルの取得
$ wget https://github.com/lagopus/lagopus.github.io/raw/master/handson/handson.tar.xz
$ tar Jxf handson.tar.xz
パッケージインストール
$ sudo apt-get update
$ sudo apt-get install unzip build-essential libexpat1-dev libgmp-dev libncurses5-dev libssl-dev libpcap-dev byacc flex libreadline-dev python-dev python-pastedeploy python-paste python-twisted git python-setuptools python-pip libxml2-dev libxslt1-dev ethtool
DPDKのビルド
必要なファイルをとってきたのでまずDPDKをビルドします。
が、ここでまずエラーが出ます。
嵌りポイントその1です。
$ cd handson
$ ./compile_dpdk.sh
...
In file included from /home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c:41:0:
/usr/lib/gcc/x86_64-linux-gnu/4.8/include/nmmintrin.h:31:3: error: #error "SSE4.2 instruction set not enabled"
# error "SSE4.2 instruction set not enabled"
^
/home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c: In function ‘ixgbe_recv_pkts_vec’:
/home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c:297:3: error: implicit declaration of function ‘_mm_shuffle_epi8’ [-Werror=implicit-function-declaration]
pkt_mb4 = _mm_shuffle_epi8(descs[3], shuf_msk);
^
/home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c:297:3: error: nested extern declaration of ‘_mm_shuffle_epi8’ [-Werror=nested-externs]
/home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c:297:11: error: incompatible types when assigning to type ‘__m128i’ from type ‘int’
pkt_mb4 = _mm_shuffle_epi8(descs[3], shuf_msk);
^
/home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c:298:11: error: incompatible types when assigning to type ‘__m128i’ from type ‘int’
pkt_mb3 = _mm_shuffle_epi8(descs[2], shuf_msk);
^
/home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c:313:11: error: incompatible types when assigning to type ‘__m128i’ from type ‘int’
pkt_mb2 = _mm_shuffle_epi8(descs[1], shuf_msk);
^
/home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c:314:11: error: incompatible types when assigning to type ‘__m128i’ from type ‘int’
pkt_mb1 = _mm_shuffle_epi8(descs[0], shuf_msk);
^
/home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c:341:3: error: implicit declaration of function ‘_mm_popcnt_u64’ [-Werror=implicit-function-declaration]
var = _mm_popcnt_u64(_mm_cvtsi128_si64(staterr));
^
/home/vagrant/handson/dpdk-1.7.0/lib/librte_pmd_ixgbe/ixgbe_rxtx_vec.c:341:3: error: nested extern declaration of ‘_mm_popcnt_u64’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
make[5]: *** [ixgbe_rxtx_vec.o] エラー 1
make[4]: *** [librte_pmd_ixgbe] エラー 2
make[3]: *** [lib] エラー 2
make[2]: *** [all] エラー 2
make[1]: *** [x86_64-native-linuxapp-gcc_install] エラー 2
make: *** [install] エラー 2
どうやらSSE4.2使えねーよ!って言っているようですが、
cpuinfo見ると確かにSSE4.2 サポートが無い。
$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 69
model name : Intel(R) Core(TM) i5-4250U CPU @ 1.30GHz
stepping : 1
microcode : 0x19
cpu MHz : 1846.212
cache size : 6144 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 5
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni ssse3 lahf_lm
bogomips : 3692.42
clflush size : 64
cache_alignment : 64
address sizes : 39 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 69
model name : Intel(R) Core(TM) i5-4250U CPU @ 1.30GHz
stepping : 1
microcode : 0x19
cpu MHz : 1846.212
cache size : 6144 KB
physical id : 0
siblings : 2
core id : 1
cpu cores : 2
apicid : 1
initial apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 5
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni ssse3 lahf_lm
bogomips : 3692.42
clflush size : 64
cache_alignment : 64
address sizes : 39 bits physical, 48 bits virtual
power management:
対処
DPDKのMLとか見てるとconfigファイルの設定で回避できるらしいのでイカを追記。
$ vi dpdk-1.7.0/config/defconfig_x86_64-native-linuxapp-gcc
# add following line
CONFIG_RTE_IXGBE_INC_VECTOR=n
CONFIG_RTE_LIBRTE_ACL=n
VBoxManageでSSE4.2 サポートを有効にできるぽい?ですが、試していないのでそれでうまくいくかわかりません!
わかったら追記します。
ちなみに別途cloneしてきて試したDPDK 1.7.1だと問題なくビルドできたので1.7.1で対処されたぽい?
設定を追加したら気を取り直してビルドです。
$ ./compile_dpdk.sh
NICの情報確認
イカのツールを実行してバス情報を取得します。
$ ./dpdk-1.7.0/tools/dpdk_nic_bind.py --status
Network devices using DPDK-compatible driver
============================================
<none>
Network devices using kernel driver
===================================
0000:00:03.0 '82540EM Gigabit Ethernet Controller' if=eth0 drv=e1000 unused= *Active*
0000:00:08.0 '82540EM Gigabit Ethernet Controller' if=eth1 drv=e1000 unused=
0000:00:09.0 '82540EM Gigabit Ethernet Controller' if=eth2 drv=e1000 unused=
Other network devices
=====================
<none>
確認した情報でインストールスクリプトを書き換えます。
$ vi install-dpdk.sh
# change device info
$ diff install-dpdk.sh.org install-dpdk.sh
5c5
< DPDK_NIC_PCIS="0000:02:02.0 0000:02:03.0"
---
> DPDK_NIC_PCIS="0000:00:08.0 0000:00:09.0"
DPDKのインストール
先ほど確認した情報で設定を書き換えインストールスクリプトを実行します。
が、vagrant使っていると(利用しているboxによりますが)modprobeがうまくいかないことがあります。
(自分は自家製boxだったので大丈夫でしたが)
$ ./install_dpdk.sh
...略
modprobe: FATAL: Module uio not found.
...略
どうもboxを軽くするために色々削っているのが原因のようで、
イカのパッケージを入れればおKです。
$ sudo apt-get install linux-generic linux-header-generic
パッケージインストールしたらとりあえず再起動しておきましょう。
$ exit
$ vagrant reload
戻ってきたらもう一度インストールスクリプトを実行です。
$ cd handson
$ ./install_dpdk.sh
Network devices using DPDK-compatible driver
============================================
0000:00:08.0 '82540EM Gigabit Ethernet Controller' drv=igb_uio unused=
0000:00:09.0 '82540EM Gigabit Ethernet Controller' drv=igb_uio unused=
Network devices using kernel driver
===================================
0000:00:03.0 '82540EM Gigabit Ethernet Controller' if=eth0 drv=e1000 unused=igb_uio *Active*
Other network devices
=====================
<none>
Set hugepagesize=256 of 2MB page
Creating /mnt/huge and mounting as hugetlbfs
Lagopusのビルド/インストール
あとはLagopusをビルドしてインストールすれば終わり!
$ cd lagopus
$ ./configure --with-dpdk-dir=${HOME}/handson/dpdk-1.7.0
$ make
$ sudo make install
$ sudo cp ~/handson/files/lagopus.conf /usr/local/etc/lagopus/
起動!
$ sudo lagopus -d -- -c3 -n1 -- -p3
なんだか無駄に長くなりました。
たぶん自分が変に嵌っただけで普通にやれば問題ないかとも思いますが
誰かの役に立つといいな。