2012年10月9日火曜日

OpenBlocks AX3でVyattaを動かす(ビルド編)

◆はじめに

VyattaはVyatta社が開発しているソフトウェアルータです。有償版もありますが、Vyatta COREと呼ばれるものはオープンソースとして公開されています。有償版に比べてWebベースのGUIが無い等はありますがオープンソース版でも多くの機能を使うことはできます。Vyattaは主にIntelプロセッサ向けに開発されていますが、ARMアーキテクチャのOpenBlocks AX3でオープンソース版のVyatta CORE 6.4を動かすこと目指し、今回は各パッケージのビルドまでを行います。


◆Vyattaソースコード取得

まずはVyattaのソースコードを取得します。ソースコードの取得にはgitが必要になるのでgitをインストールします。
 $ su
 # aptitude install git-core
 # exit
次にソースコードを取得します。
今回は執筆時点での最新のリリース版のVyatta CORE 6.4を利用します。
このバージョンはoxnardというブランチ名で開発されています。
 $ git clone http://git.vyatta.com/build-iso.git
 $ cd build-iso
 $ git checkout --track -b oxnard origin/oxnard
READMEファイルにビルド方法が記載されているので参考にします。
基本的にIntelプロセッサ向けに書かれていますのでARMでは多少変更する部分があります。


◆aptで必要なパッケージを導入する

まずは必要debianパッケージをインストールします。
インストール用のスクリプトがありますのでそれを実行します。
$ su
# sh ./setup-pkg-build 
400パッケージほどダウンロードされインストールされますのでかなり時間がかかります。
まだ不足しているパッケージがあるので追加でインストールします。
 # aptitude install python-central indent parted dosfstools ntp fakechroot uboot-mkimage libattr1-dev automake libsensors4-dev libboost-filesystem1.42-dev libapt-pkg-dev
このときlibsensors-devとconflictするので削除することになります。

i386やamd64ではビルド時にpackages.vyatta.comからパッケージを取得します。そのためvyatta-pubkey.gpgのインストールが必要となるのですが、armel用のパッケージはpackaegs.vyatta.comには存在しないため自前で準備する必要があります。そのため今回はvyatta-pubkey.gpgのインストールは不要となります。


◆サブモジュール群のビルド

ここからサブモジュール群のビルドに入ります。
Intel向けだとすでにビルドされたバイナリをサイトからaptで入手できますがARM向けは存在しないので自力でコンパイルする必要があります。

まずはサブモジュールを初期化します。
 $ git submodule init
次はgit submodule updateを行うのですが、その前にnfctがgitで取得できないため.git/configから以下を削除します。
ちなみにnfctはconntrack-toolsで生成されます。
 [submodule "pkgs/nfct"]
        url = http://git.vyatta.com/nfct.git
同様に.gitmoduleから以下を削除します。
 [submodule "pkgs/nfct"]
         path = pkgs/nfct
         url = http://git.vyatta.com/nfct.git

 $ git rm --cached pkgs/nfct
全てのサブモジュールを取得します。
 $ git submodule update
各モジュールのブランチをoxnardに変更します。
 $ git submodule foreach git checkout --track -b oxnard origin/oxnard
サブモジュールのビルドは基本的にはTOPディレクトリ(build_iso直下)でmake <サブモジュール名>
で行います。またエラーになった場合など一度クリアしたい場合にはmake clear-<サブモジュール名>とします。
例えばサブモジュール名がhogeの場合には以下のようになります。
 $ make hoge         (hogeのビルド)
 $ make clear-hoge   (hogeのクリア)
まずはビルド時に必要となるライブラリ等のビルドおよびインストールを行います。

squashfs-toolsをビルドしインストールします。
 $ make squashfs
 $ su
 # dpkg -i pkgs/squashfs-tools_4.1+vyatta-7+oxnard1_armel.deb
 # cat >| /etc/apt/preferences.d/squashfs-tools <<EOF
 Package: squashfs-tools
 Pin: version 4.*
 Pin-Priority: 1001
 EOF
 # exit
Debian squeezeには存在しないlibnet0 libsablot0をインストールするためにlennyのレポジトリを一時的に登録します。
 $ su
 # echo "deb http://archive.debian.org/debian/ lenny contrib main non-free" > /etc/apt/sources.list.d/lenny.list
 # aptitude update
 # aptitude install libnet0 libnet0-dev libsablot0 libsablot0-dev
 # rm /etc/apt/sources.list.d/lenny.list
 # exit
libmnlをビルドおよびインストールします。
 $ make libmnl
 $ su
 # dpkg -i pkgs/libmnl-dev_1.0.3-6_armel.deb \
           pkgs/libmnl0_1.0.3-6_armel.deb
 # exit
libcapをビルドおよびインストールします。
 $ make libcap
 $ su
 # dpkg -i pkgs/libcap-dev_2.19-3+vyatta2+oxnard1_armel.deb \
           pkgs/libcap2_2.19-3+vyatta2+oxnard1_armel.deb 

 # cat >| /etc/apt/preferences.d/libcap-dev <<EOF
 Package: libcap-dev
 Pin: version 2.*
 Pin-Priority: 1001
 EOF
 # cat >| /etc/apt/preferences.d/libcap2 <<EOF
 Package: libcap2
 Pin: version 2.*
 Pin-Priority: 1001
 EOF
iptablesをビルドおよびインストールします。
 $ make iptables
 $ su
 # dpkg -i pkgs/iptables-dev_1.4.10+vyatta+2+oxnard2_armel.deb \
           pkgs/iptables_1.4.10+vyatta+2+oxnard2_armel.deb
net-snmpをビルドおよびインストールします。
 $ make net-snmp
 $ su
 # dpkg -i pkgs/libsnmp-base_5.6.1.1-vyatta+7+oxnard6_all.deb \
           pkgs/libsnmp-python_5.6.1.1-vyatta+7+oxnard6_armel.deb \
           pkgs/libsnmp-dev_5.6.1.1-vyatta+7+oxnard6_armel.deb \
           pkgs/libsnmp-perl_5.6.1.1-vyatta+7+oxnard6_armel.deb \
           pkgs/libsnmp15_5.6.1.1-vyatta+7+oxnard6_armel.deb
daqをビルドおよびインストールします。
 $ make daq
 $ su
 # dpkg -i pkgs/libdaq-dev_0.3-2+vyatta3+oxnard1_armel.deb \
           pkgs/libdaq0_0.3-2+vyatta3+oxnard1_armel.deb
libnetfilter-conntrackをビルドおよびインストールします。
 $ make libnetfilter-conntrack
 $ su
 # dpkg -i pkgs/libnetfilter-conntrack3_1.0.0-1+vyatta10+oxnard4_armel.deb \
           pkgs/libnetfilter-conntrack3-dbg_1.0.0-1+vyatta10+oxnard4_armel.deb \
           pkgs/libnetfilter-conntrack-dev_1.0.0-1+vyatta10+oxnard4_armel.deb
libnetfilter-cthelperをビルドおよびインストールします。
 $ make libnetfilter-cthelper
 $ su
 # dpkg -i pkgs/libnetfilter-cthelper_1.0.1-5_armel.deb
libnetfilter-cttimeoutをビルドおよびインストールします。
 $ make libnetfilter-cthelper
 $ su
 # dpkg -i pkgs/libnetfilter-cttimeout_0.2+oxnard4_armel.deb
libnetfilter-queueをビルドおよびインストールします。
 $ make libnetfilter-cthelper
 $ su
 # dpkg -i pkgs/libnetfilter-queue-dev_1.0.1-2_armel.deb \
           pkgs/libnetfilter-queue1_1.0.1-2_armel.deb  
vyatta-cfgをビルドおよびインストールします。
 $ make vyatta-cfg
 $ su
 # dpkg -i pkgs/libvyatta-cfg-dev_0.99.73+oxnard6_armel.deb \
   pkgs/libvyatta-cfg1_0.99.73+oxnard6_armel.deb 
ここまででビルドに必要なパッケージのインストールは終わりました。
次からはパッケージのビルドだけ行います。Linuxカーネル(linux-image)は厄介なので後回しにして
Linuxカーネル以外の残りのパッケージをビルドします。
最終的に使用されるパッケージリストは livecd/config.vyatta/chroot_local-packageslists/vyatta-full.list
に記載されているので、このリストに記載されているもの以外は除外しています。

また一部コンパイルが通らないパッケージ(vyatta-cfg-systemとvyatta-biosdevname)
があるので修正します。
vyatta-cfg-system
grub-pcは不要なので削除します。また、ハイパバイザの判定にIntel Processor用アセンブラを使用している
部分を削除します。
 diff --git a/debian/control b/debian/control
 index 0b06b26..7396100 100644
 --- a/debian/control
 +++ b/debian/control
 @@ -52,7 +52,6 @@ Depends:  acpid,
   apt-transport-https,
   hostapd (>= 1:0.6.9-3),
   cpufrequtils,
 - grub-pc (>= 1.98+20100804),
   libcap2-bin (>= 2.19)
  Pre-Depends: bash-completion
  Suggests: util-linux (>= 2.13-5),
 diff --git a/src/hypervisor_vendor.c b/src/hypervisor_vendor.c
 index 0a44756..9bcef8b 100644
 --- a/src/hypervisor_vendor.c
 +++ b/src/hypervisor_vendor.c
 @@ -43,6 +43,7 @@
   */
  #define HYPERVISOR_INFO_LEAF   0x40000000
  
 +#if 0
  static inline void
  cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx,
  unsigned int *ecx, unsigned int *edx)
 @@ -64,6 +65,7 @@ cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx,
   "=d" (*edx)
  : "1" (op), "c"(0));
  }
 +#endif
  
  
  /* Use CPUID instruction to find hypervisor vendor.
 @@ -72,6 +74,7 @@ cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx,
   */
  static const char *get_hypervisor_cpuid(void)
  {
 +#if 0
  unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
  char hyper_vendor_id[13];
  
 @@ -95,6 +98,7 @@ static const char *get_hypervisor_cpuid(void)
  else if (!strncmp("VMwareVMware", hyper_vendor_id, 12))
  return "VMware";
  else
 +#endif
  return NULL;
  }
vyatta-biosdevname
仮想マシンかどうかの判定の部分でIntel Processor用アセンブラを用いている部分があるので削除します。
 diff --git a/src/bios_dev_name.c b/src/bios_dev_name.c
 index e2f8454..a5b5fdd 100644
 --- a/src/bios_dev_name.c
 +++ b/src/bios_dev_name.c
 @@ -104,6 +104,7 @@ parse_opts(int argc, char **argv)
                 opts.prefix = "em";
  }
  
 +/*
  static u_int32_t
  cpuid (u_int32_t eax, u_int32_t ecx)
  {
 @@ -114,6 +115,7 @@ cpuid (u_int32_t eax, u_int32_t ecx)
         : "%ebx", "%edx");
      return ecx;
  }
 +*/
  
  /*
    Algorithm suggested by:
 @@ -125,9 +127,11 @@ running_in_virtual_machine (void)
  {
      u_int32_t eax=1U, ecx=0U;
  
 +/*
      ecx = cpuid (eax, ecx);
      if (ecx & 0x80000000U)
         return 1;
 +*/
      return 0;
  }
 以上の修正後に、以下のコマンドでビルドを実行します。
 $ make barnyard2 conntrack-tools initramfs-tools iproute ipset
 $ make live-initramfs lldpd netplug ntp pmacct ppp squidguard linux-firmware
 $ make vyatta-base vyatta-bash vyatta-busybox vyatta-conntrack
 $ make vyatta-conntrack-sync vyatta-cfg-dhcp-relay
 $ make vyatta-cfg-dhcp-server vyatta-cfg-firewall
 $ make vyatta-cfg-op-pppoe vyatta-cfg-qos vyatta-cfg-quagga vyatta-cfg-system
 $ make vyatta-cfg-vpn vyatta-cluster vyatta-config-migrate
 $ make vyatta-dhcp3-client vyatta-idp-snort vyatta-ipv6-rtradv vyatta-keepalived vyatta-nat vyatta-op
 $ make vyatta-op-dhcp-server vyatta-op-firewall vyatta-op-qos vyatta-op-quagga vyatta-op-vpn vyatta-op-xml
 $ make vyatta-openvpn vyatta-quagga vyatta-ravpn vyatta-snort vyatta-util vyatta-wanloadbalance
 $ make vyatta-webgui vyatta-webproxy vyatta-wireless vyatta-wirelessmodem
 $ make vyatta-netflow vyatta-biosdevname vyatta-lldp vyatta-zone vyatta-config-mgmt


◆OpenBlocks AX3対応のvyatta用Linuxカーネルをビルド

最後にLinuxカーネルパッケージ linux-imageをビルドします。
準備としてオリジナルのLinuxカーネルからOpenBlocks AX3用の差分を抽出します。
OpenBlocks AX3のカーネルにはunionfsのパッチが適用されています。また、vyattaのカーネルにもunionfsのパッチが適用されています。そこでオリジナルのLinuxカーネルにunionfsのパッチを適用してその後に差分をとるという手順にします。

まずはOpenBlocks AX3用のカーネルを取得します。
 $ cd ~
 $ wget ftp://ftp.plathome.co.jp/pub/OBSAX3/squeeze/3.0.6-4/source/linux-3.0.6-20120820-1.tar.gz
 $ tar zxf linux-3.0.6-20120820-1.tar.gz
 $ mv linux-3.0.6 linux-3.0.6.obsax3
次にオリジナルのカーネル3.0.6とunionfs用の差分を取得し差分を適用します。
 $ wget ftp://ftp.ne.jp/Linux/kernel.org/linux/kernel/v3.x/linux-3.0.6.tar.xz
 $ wget http://download.filesystems.org/unionfs/unionfs-2.x/unionfs-2.5.11_for_3.0.18.diff.gz
 $ tar Jxf linux-3.0.6.tar.xz
 $ cd linux-3.0.6
 $ zcat ../unionfs-2.5.11_for_3.0.18.diff.gz |patch -s -p1
 (ここで一ヶ所rejectされるので手動でパッチをあてます。)
 $ cd ..
OpenBlocks AX3用の差分を抽出します。
 $ diff -urN linux-3.0.6 linux-3.0.6.obsax3 > linux-3.0.6.obsax3.diff
準備ができたのでvyattaのlinux-imageのビルドに戻ります。
まずは準備したOpenBlocks AX3用の差分を適用します。
 $ cd build-iso/pkgs/linux-image
 $ patch -s -p1 < ~/DIFF-3.0.6 
 1 out of 5 hunks FAILED -- saving rejects to file arch/arm/kernel/smp.c.rej
 1 out of 2 hunks FAILED -- saving rejects to file drivers/tty/tty_ldisc.c.rej
 2 out of 10 hunks FAILED -- saving rejects to file fs/splice.c.rej
 The next patch would delete the file include/linux/namei.h.orig,
 which does not exist!  Assume -R? [n] 
 Apply anyway? [n] 
 1 out of 1 hunk ignored
 1 out of 2 hunks FAILED -- saving rejects to file include/linux/socket.h.rej
 1 out of 1 hunk FAILED -- saving rejects to file kernel/printk.c.rej
 3 out of 11 hunks FAILED -- saving rejects to file net/bridge/br_fdb.c.rej
rejectされた箇所を順番に確認していきます。
arch/arm/kernel/smp.c.rej
           手動で差分を適用します。
drivers/tty/tty_ldisc.c.rej
           tty_ldisc_reinit()関数への差分は不要なようなので適用しません。
fs/splice.c.rej
           該当部分を以下のように修正しました。
        int ret, more;

        ret = buf->ops->confirm(pipe, buf);
        if (!ret) {
                more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;

                if (sd->len < sd->total_len)
                         more |= MSG_SENDPAGE_NOTLAST;
                ret = file->f_op->sendpage(file, buf->page, buf->offset,
                                           sd->len, &pos, more);
        }

        return ret;

include/linux/socket.h.rej
           MSG_KERNSPACE, MSG_NOCATCHSIGはMarvellが追加したもののようで、
           MSG_SENDPAGE_NOTLASTとconflictしてしまします。
           そこで番号を以下のように変更します。
   #define MSG_KERNSPACE   0x200000
   #define MSG_NOCATCHSIG  0x400000

kernel/printk.c.rej
           手動で差分を適用します。
net/bridge/br_fdb.c.rej
           手動で差分を適用します。


続いてlinux-imageのarmel用build設定をします。
 $ cd ~/build-iso/pkgs/linux-image
 $ mkdir debian/arch/armel
 $ touch debian/arch/armel/config

debian/arch/armel/defines.obsax3-vyatta を以下のように作成します。
 $ vi debian/arch/armel/defines.obsax3-vyatta 
 [base] 
 flavours: obsax3-vyatta 
 kernel-arch: arm 
 kernel-header-dirs: arm 
 [obsax3-vyatta_build] 
 image-file: arch/arm/boot/zImage 
 [obsax3-vyatta_description] 
 hardware: OpenBlocks AX3
 hardware-long: OpenBlocks AX3
 [obsax3-vyatta_image] 
 recommends: uboot-mkimage 
 check-size: 2097080
 [obsax3-vyatta] 
 class: arm 
 longclass: arm and compatible 

armel archを追加します。
 $ vi debian/arch/defines
 arches:
  i386 amd64 armel

次にconfigを生成します。
まずはOpenBlocks AX3のデフォルトconfigをコピーしmenuconfigは必要な設定を追加します。
 $ cp arch/arm/configs/obsax3_defconfig .config
 $ make menuconfig
 (以下を追加しました)
 CONFIG_NETFILTER_NETLINK_CTHELPER=m
 CONFIG_NF_CONNTRACK_TIMEOUT=y
 CONFIG_NF_CT_NETLINK_TIMEOUT=m
 CONFIG_IP_SET_BITMAP_IP=m
 CONFIG_IP_SET_BITMAP_IPMAC=m
 CONFIG_IP_SET_BITMAP_PORT=m
 CONFIG_IP_SET_HASH_IP=m
 CONFIG_IP_SET_HASH_IPPORT=m
 CONFIG_IP_SET_HASH_IPPORTIP=m
 CONFIG_IP_SET_HASH_IPPORTNET=m
 CONFIG_IP_SET_HASH_NET=m
 CONFIG_IP_SET_HASH_NETPORT=m
 CONFIG_IP_SET_LIST_SET=m
 CONFIG_IP_VS_FTP=m
 CONFIG_IP_NF_MATCH_IPP2P=m
 CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_XATTR=y
 CONFIG_SQUASHFS_LZO=y
 CONFIG_SQUASHFS_XZ=y
 CONFIG_SQUASHFS_EMBEDDED=y
 CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
生成された .configを必要な場所にコピーします。
 $ cp .config debian/arch/armel/config.obsax3-vyatta
次にbuild-flavour.shを実行してdebian/controlファイルを生成するのですが、その前に生成されるcontrolファイルのSection: adminがSection: kernelになるようにtemplateファイルに修正を加えます。
これをしないと後ほどパッケージビルド時にエラーが起こります。
 $ for f in debian/templates/control.image.*
   do
     sed -i -e 's/^Section: admin/Section: kernel/' $f
   done
kernel flavour の準備をします。最後にエラーがでますが無視して問題ありません。
 $ ./debian/bin/build-flavour.sh obsax3-vyatta

 (snip)
 This target is made to fail intentionally, to make sure
 that it is NEVER run during the automated build. Please
 ignore the following error, the debian/control file has
 been generated SUCCESSFULLY.
 exit 1
 make[1]: *** [debian/control-real] Error 1
 make[1]: Leaving directory `/home/ono/build-iso/pkgs/linux-image'
 make: *** [debian/control] Error 2

ようやくlinux-imageパッケージ生成の準備ができましたのでビルドします。

 $ cd ~/build-iso
 $ make linux-image


◆まとめ

今回はOpenBlocks AX3上でVyatta CORE 6.4のサブモジュールのビルドを行いました。次回はLIVE ISOイメージを作成して実際にOpenBlocks AX3で起動させてみます。

0 件のコメント:

コメントを投稿