Skip to main content
 首页 » 编程设计

docker之在 Linux Alpine 上安装 DPDK 时出错

2024年04月17日67dudu

我正在尝试安装DPDK在 Alpine Linux 上。我在 Docker 中运行 Alpine Linux。以下是我正在使用的步骤:

  1. docker pull alpine
  2. docker run -it alpine /bin/sh
  3. wget https://git.dpdk.org/dpdk-stable/snapshot/dpdk-stable-16.11.8.tar.gz
  4. tar -xzf dpdk-stable-16.11.8.tar.gz
  5. cd dpdk-stable-16.11.8
  6. apk add --no-cache make gcc libc-dev bsd-compat-headers linux-headers musl-dev
  7. apk add numactl-dev --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted
  8. make install T=x86_64-native-linuxapp-gcc

安装失败并出现以下错误和警告:

make[5]: Nothing to be done for 'depdirs'.

Configuration done

== Build lib

== Build lib/librte_compat

== Build lib/librte_eal

== Build lib/librte_eal/common

== Build lib/librte_eal/linuxapp

== Build lib/librte_eal/linuxapp/eal

CC eal_hugepage_info.o

/dpdk/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c: In function 'clear_hugedir':

/dpdk/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:229:8: warning: implicit declaration of function 'openat'; did you mean 'popen'? [-Wimplicit-function-declaration] fd = openat(dir_fd, dirent->d_name, O_RDONLY); ^~~~~~ popen

/dpdk/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:229:8: warning: nested extern declaration of 'openat' [-Wnested-externs]

/dpdk/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:229:39: error: 'O_RDONLY' undeclared (first use in this function) fd = openat(dir_fd, dirent->d_name, O_RDONLY); ^~~~~~~~ /dpdk/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:229:39: note: each undeclared identifier is reported only once for each function it appears in

/dpdk/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c: In function 'eal_hugepage_info_init':

/dpdk/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:320:26: warning: implicit declaration of function 'open'; did you mean 'popen'? [-Wimplicit-function-declaration] hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY); ^~~~ popen

/dpdk/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:320:26: warning: nested extern declaration of 'open' [-Wnested-externs]

/dpdk/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:320:45: error: 'O_RDONLY' undeclared (first use in this function) hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY); ^~~~~~~~

make[7]: *** [/dpdk/dpdk-stable-16.11.8/mk/internal/rte.compile-pre.mk:140: eal_hugepage_info.o] Error 1

make[6]: *** [/dpdk/dpdk-stable-16.11.8/mk/rte.subdir.mk:63: eal] Error 2

make[5]: *** [/dpdk/dpdk-stable-16.11.8/mk/rte.subdir.mk:63: linuxapp] Error 2

make[4]: *** [/dpdk/dpdk-stable-16.11.8/mk/rte.subdir.mk:63: librte_eal] Error 2

make[3]: *** [/dpdk/dpdk-stable-16.11.8/mk/rte.sdkbuild.mk:80: lib] Error 2

make[2]: *** [/dpdk/dpdk-stable-16.11.8/mk/rte.sdkroot.mk:127: all] Error 2

make[1]: *** [/dpdk/dpdk-stable-16.11.8/mk/rte.sdkinstall.mk:86: pre_install] Error 2

make: *** [/dpdk/dpdk-stable-16.11.8/mk/rte.sdkroot.mk:101: install] Error 2

更新1

我修复了一些错误,但现在出现了新的错误。 以下是更新的步骤:

  1. docker pull alpine
  2. docker run -it alpine /bin/sh
  3. wget https://git.dpdk.org/dpdk-stable/snapshot/dpdk-stable-16.11.8.tar.gz
  4. tar -xzf dpdk-stable-16.11.8.tar.gz
  5. cd dpdk-stable-16.11.8
  6. apk add --no-cache make gcc libc-dev bsd-compat-headers linux-headers musl-dev
  7. apk add numactl-dev --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted
  8. 添加#include <fcntl.h>lib/librte_eal/common/include/rte_common.h
  9. 添加CFLAGS += -D_GNU_SOURCElib/librte_eal/linuxapp/eal/Makefile
  10. make install T=x86_64-native-linuxapp-gcc

安装现在失败并出现以下错误:

make[5]: Nothing to be done for 'depdirs'. Configuration done

== Build lib

== Build lib/librte_compat

== Build lib/librte_eal

== Build lib/librte_eal/common

== Build lib/librte_eal/linuxapp

== Build lib/librte_eal/linuxapp/eal

CC eal_vfio_mp_sync.o

/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c: In function 'vfio_mp_sync_send_fd':

/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c:75:17: error: 'struct cmsghdr' has no member named '__cmsg_data' memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\ ^

/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c:187:2: note: in expansion of macro 'FD_TO_CMSGHDR' FD_TO_CMSGHDR(fd, *chdr); ^~~~~~~~~~~~~

/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c: In function 'vfio_mp_sync_receive_fd':

/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c:78:24: error: 'struct cmsghdr' has no member named '__cmsg_data' memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd)) ^

/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c:228:2: note: in expansion of macro 'CMSGHDR_TO_FD' CMSGHDR_TO_FD(*chdr, fd); ^~~~~~~~~~~~~

make[7]: *** [/dpdk-stable-16.11.8/mk/internal/rte.compile-pre.mk:140: eal_vfio_mp_sync.o] Error 1

make[6]: *** [/dpdk-stable-16.11.8/mk/rte.subdir.mk:63: eal] Error 2

make[5]: *** [/dpdk-stable-16.11.8/mk/rte.subdir.mk:63: linuxapp] Error 2

make[4]: *** [/dpdk-stable-16.11.8/mk/rte.subdir.mk:63: librte_eal] Error 2

make[3]: *** [/dpdk-stable-16.11.8/mk/rte.sdkbuild.mk:80: lib] Error 2

make[2]: *** [/dpdk-stable-16.11.8/mk/rte.sdkroot.mk:127: all] Error 2

make[1]: *** [/dpdk-stable-16.11.8/mk/rte.sdkinstall.mk:86: pre_install] Error 2

make: *** [/dpdk-stable-16.11.8/mk/rte.sdkroot.mk:101: install] Error 2

如果你看一下/usr/include/x86_64-linux-gnu/bits/socket.h , struct cmsghdr定义如下:

/* Structure used for storage of ancillary data object information.  */ 
struct cmsghdr 
{ 
    size_t cmsg_len; 
    /* Length of data in cmsg_data plus length 
       of cmsghdr structure. 
       !! The type should be socklen_t but the 
       definition of the kernel is incompatible 
       with this.  */ 
    int cmsg_level;     /* Originating protocol.  */ 
    int cmsg_type;      /* Protocol specific type.  */ 
#if __glibc_c99_flexarr_available 
    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */ 
#endif 
}; 

什么是__glibc_c99_flexarr_available ?我可以以某种方式使其可用吗?

更新2

我尝试使用 this而不是musl-dev但错误仍然相同。

然后按照建议,我安装了 glibc在我的 Alpine Linux 上使用它而不是 musl 。按照步骤 here 。现在我收到这样的错误:

In file included from /dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal.c:48:0:

/usr/include/limits.h:124:26: fatal error: limits.h: No such file or directory

# include_next

请您参考如下方法:

DPDK 似乎与 musl libc 不兼容,因此您可能很难一一修复错误。必须手动添加预处理器定义并包含到 CFLAGS 似乎是一个坏兆头。

最后一个错误是这样的 libc 不兼容:

/dpdk-stable-16.11.8/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c:78:24: error: 'struct cmsghdr' has no member named '__cmsg_data' memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))

在我的 glibc (Ubuntu 16.04) 中,cmsghdrbits/socket.h 中定义如下:

/* Structure used for storage of ancillary data object information.  */ 
struct cmsghdr 
  { 
    size_t cmsg_len;            /* Length of data in cmsg_data plus length 
                                   of cmsghdr structure. 
                                   !! The type should be socklen_t but the 
                                   definition of the kernel is incompatible 
                                   with this.  */ 
    int cmsg_level;             /* Originating protocol.  */ 
    int cmsg_type;              /* Protocol specific type.  */ 
#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L 
    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */ 
#endif 
  }; 

注意最后的__cmsg_data的定义。

在 musl 中,cmsghdr 定义为:

struct cmsghdr { 
        socklen_t cmsg_len; 
        int __pad1; 
        int cmsg_level; 
        int cmsg_type; 
}; 

请注意缺少的 __cmsg_data 字段。