[infiniband] Problems encountered in rdma-core compilation and solutions

1. Missing package

Run ./build.sh, prompt error:

--   No package 'libnl-3.0' found
--   No package 'libnl-route-3.0' found
CMake Error at /usr/share/cmake-3.13/Modules/FindPkgConfig.cmake:452 (message):
  A required package was not found
Call Stack (most recent call first):
  /usr/share/cmake-3.13/Modules/FindPkgConfig.cmake:622 (_pkg_check_modules_internal)
  CMakeLists.txt:450 (pkg_check_modules)


-- Configuring incomplete, errors occurred!

solve:

apt install libnl-3-dev
apt install libnl-route-3-dev

2. The path is too long

Prompt error:

Scanning dependencies of target rdmacm
[ 30%] Building C object librdmacm/CMakeFiles/rdmacm.dir/acm.c.o
In file included from /root/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES/rdma-core-50mlnx1/build/include/ccan/minmax.h:7,
                 from /root/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES/rdma-core-50mlnx1/librdmacm/cma.h:48,
                 from /root/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES/rdma-core-50mlnx1/librdmacm/acm.c:43:
/root/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES/rdma-core-50mlnx1/librdmacm/acm.c: In function ‘ucma_ib_init’:
/root/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES/rdma-core-50mlnx1/build/include/ccan/build_assert.h:23:26: error: size of unnamed array is negative
  do { (void) sizeof(char [1 - 2*!(cond)]); } while(0)
                          ^
/root/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES/rdma-core-50mlnx1/librdmacm/acm.c:170:3: note: in expansion of macro ‘BUILD_ASSERT’
   BUILD_ASSERT(sizeof(IBACM_SERVER_PATH) <=
   ^~~~~~~~~~~~
make[2]: *** [librdmacm/CMakeFiles/rdmacm.dir/build.make:63: librdmacm/CMakeFiles/rdmacm.dir/acm.c.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:636: librdmacm/CMakeFiles/rdmacm.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

Ask GPT, answer:

根据编译错误信息,问题出在 build/include/ccan/build_assert.h 头文件中的 BUILD_ASSERT 宏定义上。
这个宏是用来做编译期断言的,它的实现是:
c
#define BUILD_ASSERT(cond) \
  do { (void) sizeof(char [1 - 2*!(cond)]); } while(0)
如果 cond 条件为假,数组大小会变为负值,导致编译错误。
这里提示数组大小为负,说明编译期断言失败了。
仔细看,问题出在 acm.c 文件的这行:
c 
BUILD_ASSERT(sizeof(IBACM_SERVER_PATH) <= ...);
看来 IBACM_SERVER_PATH 的大小超过了断言的大小。
可能的解决方案:
1. 增加 BUILD_ASSERT 中的大小
2. 调整 IBACM_SERVER_PATH 的定义,减小其大小
3. 关闭这个编译期断言,如果对大小不敏感的话
需要分析 IBACM_SERVER_PATH 的实际大小和断言的预期是否匹配,从而决定合适的解决方案。
总之,编译失败的根本原因是编译期断言触发了,需要调整相关的类型大小。
这个编译错误是因为 BUILD_ASSERT 断言失败导致的,具体原因是 IBACM_SERVER_PATH 的大小超过了 addr.unx.sun_path 的大小。
从代码来看,IBACM_SERVER_PATH 是 AF_UNIX 域套接字地址中的路径名,而 addr.unx.sun_path 是这个路径名的存储缓冲区。
一些可能的解决方案:
1. 增大 addr.unx.sun_path 的大小
   修改 union 定义,增加 sun_path 数组大小,如改为:
   
c
   char sun_path[108];
   
2. 缩短 IBACM_SERVER_PATH 的长度
   如果可以的话,修改 IBACM_SERVER_PATH 的定义,减小路径名长度。
3. 关闭断言
   如果对大小不敏感,可以直接注释掉 BUILD_ASSERT这行。
4. 使用动态分配的缓冲区
   也可以考虑不使用静态 union,而是动态分配缓冲区存储 sun_path。
5. 分配在 heap 而不是 stack
   将 union 和 addr 定义为动态变量,分配在 heap 上而不是 stack 上。
基本思路就是确保 sun_path 有足够空间存放路径名,具体来说要确保 addr.unx.sun_path 大于等于 IBACM_SERVER_PATH 的大小。
struct sockaddr_un 是一个UNIX域socket地址结构,它被定义在<sys/un.h>头文件中。
主要字段包括:
- sa_family_t sun_family: 地址族类型,对于UNIX域socket,该字段值为AF_UNIX
- char sun_path[108]: socket文件在文件系统中的路径名
这个路径名可以是绝对路径,也可以是相对路径。长度受sun_path数组大小限制,一般为108字节。
示例:
c
struct sockaddr_un addr;
addr.sun_family = AF_UNIX; 
strcpy(addr.sun_path, "/tmp/socket");

bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
这个结构常用于UNIX域socket,bind到指定路径以创建listening socket,或者connect到server端socket。
主要注意sun_path长度限制,如果路径名过长,需要将sun_path数组扩大来容纳。
除了文件系统中的socket,Linux也支持abstract namespace的UNIX domain socket,这时sun_path第一个字节为null字节'\0'。
所以sockaddr_un可以表示两种UNIX socket地址,file system socket和abstract socket。这为本地socket通信提供了灵活的选择。
您提到的IBACM_SERVER_PATH的定义使用了 CMAKE_INSTALL_FULL_RUNDIR 这个CMake变量。
在编译时,CMAKE_INSTALL_FULL_RUNDIR会被展开为实际的运行时目录,这可能导致最终的IBACM_SERVER_PATH超过了108字节限制。
一种可能的解决方案是:
1. 在CMake构建脚本中,将CMAKE_INSTALL_FULL_RUNDIR设置为一个较短的目录,例如:
set(CMAKE_INSTALL_FULL_RUNDIR "/var/run/")
2. 或者在定义IBACM_SERVER_PATH时,只取CMAKE_INSTALL_FULL_RUNDIR的最后一部分,例如:
#define IBACM_SERVER_PATH "@CMAKE_INSTALL_FULL_RUNDIR@/ibacm.sock"
=>
#define IBACM_SERVER_PATH "/ibacm.sock"
3. 修改struct sockaddr_un的定义,增加sun_path大小,要大于最终解析后的IBACM_SERVER_PATH。
主要是要控制好最终生成的IBACM_SERVER_PATH字符串长度,不能超过sockaddr_un.sun_path的大小。
可以在编译前打印出最终的IBACM_SERVER_PATH定义,来验证是否超长。调整CMake变量或者修改sun_path大小来解决。

solve:

Move the rdma-core directory to a shorter path.

root@debian:~/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES# mv rdma-core-50mlnx1/ /root/infiniband/

3. Clear cache

Prompt error:

CMake Error: The current CMakeCache.txt directory /root/infiniband/rdma-core-50mlnx1/build/CMakeCache.txt is different than the directory /root/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES/rdma-core-50mlnx1/build where CMakeCache.txt was created. This may result in binaries being created in the wrong place. If you are not sure, reedit the CMakeCache.txt
CMake Error: The source "/root/infiniband/rdma-core-50mlnx1/CMakeLists.txt" does not match the source "/root/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES/rdma-core-50mlnx1/CMakeLists.txt" used to generate cache.  Re-run cmake with a different source directory.

Ask GPT, answer:

这个 CMake 错误表示,当前的 CMakeLists.txt 源文件与用于生成 CMake cache 的源文件不一致。
具体来看,当前的 CMakeLists.txt 路径为:
/root/infiniband/rdma-core-50mlnx1/CMakeLists.txt
而用于生成 CMake cache 的源文件路径为:
/root/infiniband/MLNX_OFED_LINUX-4.9-7.1.0.0-debian10.0-x86_64/src/MLNX_OFED_SRC-4.9-7.1.0.0/SOURCES/rdma-core-50mlnx1/CMakeLists.txt
这说明你当前的 CMake 构建目录与初次生成 CMake cache 时的源目录不一样了。
可能的原因:
- 你把源代码移动到了新的位置,但是 CMake cache 没有更新
- 你在新的目录运行 cmake,但是使用的是旧的 CMake cache
要解决这个问题,有以下几种方法:
1. 删除 CMake cache,在当前源代码目录完全重新运行 cmake
2. 将源代码移动回初次运行 cmake 的位置
3. 用 cmake 的 -S 和 -B 参数分别指定源代码目录和构建目录
4. 直接运行:cmake -S /root/infiniband/rdma-core-50mlnx1 -B . 来重建
基本上,需要确保运行 cmake 的源代码目录和构建目录与生成 cache 时的一致,就可以解决这个错误。

solve:

Delete the cache directory build of cmake.

rm -rf build

Guess you like

Origin blog.csdn.net/eidolon_foot/article/details/132596667