Search code examples
linuxlinux-kernelebpfbpflibbpf

how to deal with this libbpf: Error in bpf_create_map_xattr(queue_map):Invalid argument(-22)


I use libbpf write a bpf program to watch the file open action. I used BPF_MAP_TYPE_QUEUE to pass the pathname. It seem worked, but not normally.

libbpf: elf: skipping unrecognized data section(8) .rodata.str1.16
libbpf: elf: skipping unrecognized data section(22) .eh_frame
libbpf: elf: skipping relo section(23) .rel.eh_frame for section(22) .eh_frame
libbpf: Error in bpf_create_map_xattr(queue_map):Invalid argument(-22). Retrying without BTF.
******Loop times 0 ******
******Loop times 1 ******
pid=3478152                 cmd=titan_monitor              pathname=
pid=3478152                 cmd=titan_monitor              pathname=/
pid=3478152                 cmd=titan_monitor              pathname=uptime
pid=3478152                 cmd=titan_monitor              pathname=stat
pid=6311                    cmd=python                     pathname=cmdline
pid=6311                    cmd=python                     pathname=proc
pid=6311                    cmd=python                     pathname=sem.1NGcnv
pid=6311                    cmd=python                     pathname=sem.xW06WV
pid=6311                    cmd=python                     pathname=sem.9GYRMO
pid=6311                    cmd=python                     pathname=sem.a5psds
ç******Loop times 2 ******
pid=3478176                 cmd=titanagent                 pathname=
pid=3478152                 cmd=titan_monitor              pathname=urandom
pid=3478152                 cmd=titan_monitor              pathname=/
pid=3478152                 cmd=titan_monitor              pathname=uptime
pid=3478152                 cmd=titan_monitor              pathname=stat
pid=3478152                 cmd=titan_monitor              pathname=cmdline
pid=3478152                 cmd=titan_monitor              pathname=/
pid=3478152                 cmd=titan_monitor              pathname=uptime
pid=3478152                 cmd=titan_monitor              pathname=stat

it loss the first value every time in the loop.

166     //print out
167     signal(SIGINT, do_quit);
168     int count = 0;
169     while (!quit) {
170         int key = 0;
171         unsigned long long val;
172         struct hash_key hkey = {}, nhkey= {};
173
174         printf("******Loop times %d ******\n", count);
175         count++;
176         memset(&nhkey, 0, sizeof(hkey));
177         while (bpf_map_lookup_and_delete_elem(queue_map_fd, 0, &nhkey) == 0) {
178             printf("pid=%d  \t\t    cmd=%s  \t\t   pathname=%s\n",
179                         (__u32) nhkey.pid,  nhkey.comm,  hkey.pathname);
180             //print_stack(&nhkey, stack_map_fd);
181             hkey = nhkey;
182             //usleep(1000000);
183         }
184
185         usleep(1000000);
186     }
 37 struct {
 38     __uint(type, BPF_MAP_TYPE_QUEUE);
 39     __type(value, struct hash_key);
 40     __uint(max_entries, 10);
 41 } queue_map SEC(".maps");

how to deal with this


Solution

  • libbpf: Error in bpf_create_map_xattr(queue_map):Invalid argument(-22). Retrying without BTF.

    So, it fails to load initially, but the retry without BTF works, otherwise your program would have exited. I can't be 100% certain but believe this mechanism exists because older kernels do not support providing the BTF info for maps. If that is the case, the warning/error should go away on newer kernels, otherwise something might be wrong with the BTF itself, but I can't tell that from the info provided.

    it loss the first value every time in the loop.

    Copying code for refrence

    166     //print out
    167     signal(SIGINT, do_quit);
    168     int count = 0;
    169     while (!quit) {
    170         int key = 0;
    171         unsigned long long val;
    172         struct hash_key hkey = {}, nhkey= {};
    173
    174         printf("******Loop times %d ******\n", count);
    175         count++;
    176         memset(&nhkey, 0, sizeof(hkey));
    177         while (bpf_map_lookup_and_delete_elem(queue_map_fd, 0, &nhkey) == 0) {
    178             printf("pid=%d  \t\t    cmd=%s  \t\t   pathname=%s\n",
    179                         (__u32) nhkey.pid,  nhkey.comm,  hkey.pathname);
    180             //print_stack(&nhkey, stack_map_fd);
    181             hkey = nhkey;
    182             //usleep(1000000);
    183         }
    184
    185         usleep(1000000);
    186     }
    

    If you follow the code for each iteration of the while(!quit) loop:

    1. struct hash_key hkey = {}, nhkey= {}; both hkey and nhkey are initialized.
    2. memset(&nhkey, 0, sizeof(hkey)); hkey is zeroed out
    3. The first iteration of the inner loop bpf_map_lookup_and_delete_elem(queue_map_fd, 0, &nhkey) you fill nhkey with the map value
    4. printf("pid=%d \t\t cmd=%s \t\t pathname=%s\n",179 (__u32) nhkey.pid, nhkey.comm, hkey.pathname); then print nhkey.pid and nhkey.comm which have values. And also hkey.pathname but hkey is still zero, so nothing it printed.
    5. hkey = nhkey; you then copy nhkey to hkey so the next iteration, hkey does have a value, but it is the value of the last iteration.

    So unless you are using it for something else, you should remove hkey from your code and replace your print line with:

    printf("pid=%d \t\t cmd=%s \t\t pathname=%s\n", 179 (__u32) nhkey.pid, nhkey.comm, nhkey.pathname);

    166     //print out
    167     signal(SIGINT, do_quit);
    168     int count = 0;
    169     while (!quit) {
    170         int key = 0;
    171         unsigned long long val;
    172         struct hash_key nhkey= {};
    173
    174         printf("******Loop times %d ******\n", count);
    175         count++;
    176         while (bpf_map_lookup_and_delete_elem(queue_map_fd, 0, &nhkey) == 0) {
    177             printf("pid=%d  \t\t    cmd=%s  \t\t   pathname=%s\n",
    178                         (__u32) nhkey.pid,  nhkey.comm,  nhkey.pathname);
    179         }
    180
    181         usleep(1000000);
    182     }