F-STACK 编译安装与使用

F-STACK 的编译使用以及一些问题的规避

缩略语及基本概念

  • DPDK - Data Plane Development Kit 数据⾯开发⼯作集

  • EAL - Environment Abstraction Layer 环境抽象层

    提供了⼀个通⽤接⼝,隐藏应⽤程序和库中的环境细节。

  • rte - runtime environment 运⾏时环境

  • PMD - Poll Mode Drivers 提供全⽤户态的驱动

  • lcore

    EAL线程(eal pthread),由eal创建和管理,执⾏的任务函数由remote_launch的回调函数指定,在每个EAL pthread中,有⼀个名为lcore_id的TLS(thread local storage)作为唯⼀标识,由于通常情况下eal pthread和CPU是1:1绑定,所以lcore_id⼀般等于CPU ID号

  • KNI - Kernel Network Interface

    主要是和Linux内核协议栈建⽴通道,因为有些和性能⽆关的但和管理、功能等相关的东⻄直接使⽤Linux内核协议栈更⽅便。

  • LPM - 最⻓匹配

    由Classify库提供,除了LPM,还有Exact Match(精确匹配)和ACL(通配符匹 配)。

  • port

    指⽹卡,如port 0指第⼀块⽹卡,port 1指第⼆块⽹卡。

环境要求

F-STACK 基于 DPDK 因此参考DPDK 环境要求即可。

  • Linux kernel >= 3.16
  • 内核配置
    • HUGETLBFS 大页内存
    • PROC_PAGEi_MONITOR 支持
  • GNU make
  • gcc 4.9+
  • libc-headers(etc. glibc-devel libc6-dev)
  • Linux kernel headers and modules(etc. kernel-devel)
  • glibc >= 2.7
  • libgcc
  • libstdc++
  • Library for handling NUMA(Non Uniform Memory Access)
    • numactl-devel
    • libnuma-dev
  • Pyhton 2.7+ or 3.2+
1
yum install -y numactl numactl-libs numactl-devel libpcap-devel gcc-c++ make cmake cmake3 pciutils

DPDK 相关问题参考 DPDK 文档

安装

官网快速使用手册

官网搭建向导手册

基础环境安装

1
yum install -y git gcc openssl-devel kernel-devel-$(uname -r) bc numactl-devel python libpcap libpcap-devel

下载源码

1
2
mkdir -p /data/f-stack
git clone https://github.com/F-Stack/f-stack.git /data/f-stack

编译与配置

1
2
3
4
5
6
7
8
9
cd /data/f-stack

# Compile DPDK
cd dpdk
./usertools/dpdk-setup.sh # compile with x86_64-native-linuxapp-gcc

# 如有需要可安装
cd build # 或者 x86_64-native-linuxapp-gcc
make install

设置大页内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看numa支持 支持的机器会显示node
numastat

# 对于没有numa的机器
echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

# 对于又numa的机器 假设又两个node
echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages

# 挂载大页内存
mkdir -p /mnt/huge
mount -t hugetlbfs none /mnt/huge -o pagesize=2MB

# 清空大页内存只需要把数字改0即可

# 如果想永久保存,则在:/etc/fstab文文件中增加
nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0

关闭 ASLR

1
2
# Close ASLR; it is necessary in multiple process
echo 0 > /proc/sys/kernel/randomize_va_space

加载编译好的驱动

1
2
3
4
5
6
7
# 查看和移除系统自带的uio
lsmod | grep uio
modprobe uio

# 加载编译好的igb\_uio
insmod kmod/igb_uio.ko
insmod kmod/rte_kni.ko

绑定网卡驱动

1
2
3
4
5
6
7
8
# 查看当前网卡信息
./usertools/dpdk-devbind.py --status

# 首先保证网卡非活动
ip link set ethx down

# 使用dpdk脚本进行绑定
./usertools/dpdk-devbind.py --bind=igb_uio 00:09.0 ...

设置 F-STACK 环境

1
2
3
4
5
export FF_PATH=/data/f-stack
# 设置 dpdk 库目录
export FF_DPDK=/data/f-stack/dpdk/x86_64-native-linuxapp-gcc
cd ../lib/
make

安装 F-STACK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Install F-STACK
# libfstack.a will be installed to /usr/local/lib
# ff_*.h will be installed to /usr/local/include
# start.sh will be installed to /usr/local/bin/ff_start
# config.ini will be installed to /etc/f-stack.conf
make install

# output
rm -rf /usr/local/lib/libfstack.a.1.21
rm -rf /usr/local/lib/libfstack.a
rm -rf /usr/local/include/ff_config.h
rm -rf /usr/local/include/ff_api.h
rm -rf /usr/local/include/ff_event.h
rm -rf /usr/local/include/ff_errno.h
rm -rf /usr/local/include/ff_epoll.h
rm -rf /usr/local/bin/ff_start
cp -f libfstack.a /usr/local/lib/libfstack.a.1.21
ln -sf /usr/local/lib/libfstack.a.1.21 /usr/local/lib/libfstack.a
cp -f ff_config.h /usr/local/include/ff_config.h
cp -f ff_api.h /usr/local/include/ff_api.h
cp -f ff_event.h /usr/local/include/ff_event.h
cp -f ff_errno.h /usr/local/include/ff_errno.h
cp -f ff_epoll.h /usr/local/include/ff_epoll.h
cp -f /data/f-stack/lib/../start.sh /usr/local/bin/ff_start
test -f '/etc/f-stack.conf' || cp -f /data/f-stack/lib/../config.ini /etc/f-stack.conf

测试

使用 example 测试 F-STACK 是否可以使用

1
2
3
cd example && make && cd ..
# 执行此程序前需要修改 config.ini 配置好 ip 相关的设置
./example/helloworld --conf config.ini --proc-type=primary --proc-id=0

在另一台机器上执行命令进行测试查看结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
➜  ~ curl -k http://10.20.48.80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to F-Stack!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to F-Stack!</h1>

<p>For online documentation and support please refer to
<a href="http://F-Stack.org/">F-Stack.org</a>.<br/>

<p><em>Thank you for using F-Stack.</em></p>
</body>
</html>

其他

执行 F-STACK 的 ifconfig 需要对 F-STACK 的环境已经初始化(即有使用 F-STACK 的进程正在运行),如果没有就会出现如下错误

1
2
3
4
5
6
7
8
9
10
11
[root@localhost sbin]# ./ifconfig
PANIC in rte_eal_config_attach():
Cannot open '/var/run/.rte_config' for rte_mem_config
7: [./ifconfig() [0x41355e]]
6: [/lib64/libc.so.6(__libc_start_main+0xf5) [0x7f6b5f3a43d5]]
5: [./ifconfig() [0x413dfd]]
4: [./ifconfig() [0x4207a2]]
3: [./ifconfig() [0x4458b4]]
2: [./ifconfig() [0x405ee2]]
1: [./ifconfig() [0x44b2ea]]
已放弃

编译并启动 Nginx, for more details, see nginx guide.

1
2
3
4
5
6
cd app/nginx-1.16.1
bash ./configure --prefix=/usr/local/nginx_fstack --with-ff_module
make
make install
cd ../..
/usr/local/nginx_fstack/sbin/nginx

手动配置 DPDK PORT 的 IP

1
/data/f-stack/tools//sbin/ifconfig f-stack-0 10.20.48.80

配置好 ip 之后在另一台机器上连接

1
2
3
➜  ~ curl -k http://10.20.48.80
<title>Welcome to F-Stack Nginx!</title>
pad data:0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789

编译并安装 Redis

1
2
3
cd app/redis-5.0.5/
make
make install