Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C BPF:`BPF_obj_get_info_by_fd`失败,参数无效`_C_Linux_Sockets_Xdp Bpf - Fatal编程技术网

C BPF:`BPF_obj_get_info_by_fd`失败,参数无效`

C BPF:`BPF_obj_get_info_by_fd`失败,参数无效`,c,linux,sockets,xdp-bpf,C,Linux,Sockets,Xdp Bpf,我试图在我的用户空间程序中获取BPF_MAP_TYPE_XSKMAP的fd 代码如下: ret = bpf_get_link_xdp_id(cfg->ifindex, &cfg->prog_id, cfg->xdp_flags); if (ret) { fprintf(stderr, "`bpf_get_link_xdp_id` returned error: %s\n", strerror(errno)); exit(-ret); } cfg->

我试图在我的用户空间程序中获取
BPF_MAP_TYPE_XSKMAP
的fd

代码如下:

ret = bpf_get_link_xdp_id(cfg->ifindex, &cfg->prog_id, cfg->xdp_flags);
if (ret) {
    fprintf(stderr, "`bpf_get_link_xdp_id` returned error: %s\n", strerror(errno));
    exit(-ret);
}

cfg->prog_fd = bpf_prog_get_fd_by_id(cfg->prog_id);
if(cfg->prog_fd < 0) {
    fprintf(stderr, "Failed to obtain prog_fd: %s\n", strerror(errno));
    exit(1);
}

struct bpf_prog_info prog_info;
uint32_t prog_info_len = sizeof(struct bpf_prog_info);
uint32_t map_info_len = sizeof(struct bpf_map_info);
if(bpf_obj_get_info_by_fd(cfg->prog_fd, &prog_info, &prog_info_len) == 0) {

    const uint32_t amnt_of_maps = prog_info.nr_map_ids;
    uint32_t *map_ids = (uint32_t*)malloc(sizeof(uint32_t) * prog_info.nr_map_ids);

    memset(&prog_info, 0, prog_info_len);
    prog_info.nr_map_ids = amnt_of_maps;
    prog_info.map_ids = (uint64_t)(unsigned long)map_ids;

    if(bpf_obj_get_info_by_fd(cfg->prog_fd, &prog_info, &prog_info_len) == 0) {

        for(uint32_t i = 0; i < prog_info.nr_map_ids; i++) {

            const int map_fd = bpf_map_get_fd_by_id(map_ids[i]);

            if(map_fd >= 0) {
                struct bpf_map_info map_info;
                if(bpf_obj_get_info_by_fd(map_fd, &map_info, &map_info_len) == 0) {
                    if(strcmp(map_info.name, "xsks_map") == 0) {
                        cfg->xsks_map_fd = map_fd;
                        printf("Got fd of xsks_map!\n");
                        break;
                    }
                } else {
                    close(map_fd);
                }
            } else {
                fprintf(stderr, "Failed to obtain map_fd for id %d: %s\n", i, strerror(errno));
            }

        }
    } else {
        fprintf(stderr, "Failed to obtain prog_info 2: %s\n", strerror(errno));
    }
} else {
    fprintf(stderr, "Failed to obtain prog_info 1: %s\n", strerror(errno));
}
ret=bpf\u get\u link\u xdp\u id(cfg->ifindex,&cfg->prog\u id,cfg->xdp\u标志);
如果(ret){
fprintf(stderr,“`bpf\u get\u link\u xdp\u id`返回错误:%s\n”,strerror(errno));
出口(-ret);
}
cfg->prog_fd=bpf_prog_get_fd_by_id(cfg->prog_id);
如果(cfg->prog_fd<0){
fprintf(stderr,“无法获取程序fd:%s\n”,strerror(errno));
出口(1);
}
结构bpf_prog_info prog_info;
uint32_t prog_info_len=sizeof(结构bpf_prog_info);
uint32映射信息长度=sizeof(结构bpf映射信息);
如果(bpf_obj_获取_信息由_fd(cfg->prog_fd,&prog_信息,&prog_信息长度)=0){
const uint32\u t amnt\u of\u maps=prog\u info.nr\u map\u id;
uint32地图ID=(uint32地图ID*)malloc(规模(uint32地图ID)*项目信息nr地图ID);
memset(&prog_-info,0,prog_-info-len);
prog_info.nr_map_id=amnt_地图;
prog_info.map_id=(uint64_t)(无符号长)map_id;
如果(bpf_obj_获取_信息由_fd(cfg->prog_fd,&prog_信息,&prog_信息长度)=0){
对于(uint32\u t i=0;i=0){
结构bpf\u映射信息映射信息;
如果(bpf_obj_获取_信息_by_fd(地图_fd,&地图_信息,&地图_信息长度)=0){
if(strcmp(map_info.name,“xsks_map”)==0){
cfg->xsks_map_fd=map_fd;
printf(“获得xsks_地图的fd!\n”);
打破
}
}否则{
关闭(map_fd);
}
}否则{
fprintf(stderr,“无法获取id%d:%s\n的映射\u fd”,i,strerror(errno));
}
}
}否则{
fprintf(stderr,“无法获取程序信息2:%s\n”,strerror(errno));
}
}否则{
fprintf(stderr,“无法获取程序信息1:%s\n”,strerror(errno));
}
但不幸的是,我在调用
bpf\u obj\u get\u info\u by\u fd(cfg->prog\u fd,&prog\u info,&prog\u info,&prog\u info\u len)
时出错:
未能获取prog\u info 1:无效参数

我不知道这是否是因为XDP程序是从另一个进程加载的?同一过程是否必须获得同时加载AF-XDP程序的程序信息

编辑:我在用户空间程序中更改的唯一一件事是通过
BPF\u-MAP\u-update\u-elem
(条目在那里,用
bpftool-MAP-dump-id
)填充
BPF\u-MAP\u-TYPE\u散列,并在我的XDP程序中使用
BPF\u-MAP\u-lookup\u-elem
(相同的散列图)

突然,错误变为:
无法获取程序信息1:地址不正确

当您尝试检索有关程序的信息时,在中调用了一条注释,说明:

/*如果我们得到了一个比我们知道的更大的结构,请确保所有未知位都为0,即新的用户空间不依赖于我们还不知道的任何内核功能扩展。[……]*/

我想这就是你的案子。您的libbpf版本可能使用了内核不知道的
struct bpf\u prog\u info
中的某些属性

要确保内核接受它,只需尝试对结构进行零初始化

struct bpf_prog_info prog_info={};

它不必处于相同的过程中,例如,您可以通过打印从
bpf\u get\u link\u xdp\u id()
获得的id并尝试将其提供给
bpftool prog show id
进行检查。我不知道为什么调用
bpf\u prog\u get\u fd\u by\u id()
失败。您使用的是最新版本的libbpf吗?感谢您的评论,使用旧版本似乎是最好的选择。我刚刚从libbpf-github-repo(最后一次提交是在3月11日)复制了最新版本。我知道这听起来很奇怪,但有时这段代码工作时没有错误,有时则没有(重新启动我的程序会有帮助)。我知道你或其他人对这种含糊不清的说法无能为力,“有时这段代码可以正常工作,有时却不能”->你是指最新的libbpf,还是之前的版本?最新的libbpf带来了什么?您可以通过
strace-ebpf
在成功运行和中止运行之间观察到任何差异吗?我的意思是使用最新的libbpf。我从这里获得libbpf:。我对我原来的帖子做了一些修改。是否存在必须满足的未知函数调用序列,以使这些bpf调用工作,例如,在调用
bpf\u obj\u get\u info\u by\u fd
之前不要填充映射?对不起,我误读了。我认为错误来自
bpf\u prog\u get\u fd\u by_id()
,而不是调用
bpf\u obj\u get\u info\u by_fd()
。这确实解决了问题。非常(再次)感谢你Qeole!