mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-24 02:29:23 +00:00
criu: parse information about BPF maps from procfs
This commit enables CRIU to: (a) identify an anonymous inode as being a BPF map (b) parse information about BPF maps from procfs Source files modified: * files.c - Checks anonymous inodes to see whether they are BPF maps. If so, sets struct fdtype_ops *ops to a structure that knows how to dump BPF maps * proc_parse.c - Function parse_fdinfo_pid_s() now checks whether the current file being processed is a BPF map. If so, it calls a newly defined function parse_bpfmap() which knows how to parse information about BPF maps from procfs Signed-off-by: Abhishek Vijeev <abhishek.vijeev@gmail.com>
This commit is contained in:
parent
4d5fc9fe5c
commit
adf2da9bec
2 changed files with 68 additions and 0 deletions
|
|
@ -48,6 +48,7 @@
|
|||
#include "string.h"
|
||||
#include "kerndat.h"
|
||||
#include "fdstore.h"
|
||||
#include "bpfmap.h"
|
||||
|
||||
#include "protobuf.h"
|
||||
#include "util.h"
|
||||
|
|
@ -539,6 +540,10 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
|
|||
ops = &signalfd_dump_ops;
|
||||
else if (is_timerfd_link(link))
|
||||
ops = &timerfd_dump_ops;
|
||||
#ifdef CONFIG_HAS_LIBBPF
|
||||
else if (is_bpfmap_link(link))
|
||||
ops = &bpfmap_dump_ops;
|
||||
#endif
|
||||
else
|
||||
return dump_unsupp_fd(&p, lfd, "anon", link, e);
|
||||
|
||||
|
|
|
|||
|
|
@ -1682,6 +1682,57 @@ nodata:
|
|||
goto parse_err;
|
||||
}
|
||||
|
||||
typedef struct bpfmap_fmt {
|
||||
char *fmt;
|
||||
void *value;
|
||||
} bpfmap_fmt;
|
||||
|
||||
static int parse_bpfmap(struct bfd *f, char *str, BpfmapFileEntry *bpf)
|
||||
{
|
||||
/*
|
||||
* Format is:
|
||||
*
|
||||
* uint32_t map_type
|
||||
* uint32_t key_size
|
||||
* uint32_t value_size
|
||||
* uint32_t max_entries
|
||||
* uint32_t map_flags
|
||||
* uint64_t memlock
|
||||
* uint32_t map_id
|
||||
* boolean frozen
|
||||
*/
|
||||
|
||||
bpfmap_fmt map[] = {
|
||||
{"map_type: %u", &bpf->map_type },
|
||||
{"key_size: %u", &bpf->key_size },
|
||||
{"value_size: %u", &bpf->value_size },
|
||||
{"max_entries: %u", &bpf->max_entries },
|
||||
{"map_flags: %"PRIx32"", &bpf->map_flags },
|
||||
{"memlock: %"PRIu64"", &bpf->memlock },
|
||||
{"map_id: %u", &bpf->map_id },
|
||||
{"frozen: %d", &bpf->frozen },
|
||||
};
|
||||
|
||||
size_t n = sizeof(map) / sizeof(bpfmap_fmt);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (sscanf(str, map[i].fmt, map[i].value) != 1)
|
||||
return -1;
|
||||
|
||||
if (i == n - 1)
|
||||
break;
|
||||
|
||||
str = breadline(f);
|
||||
if (IS_ERR_OR_NULL(str)) {
|
||||
pr_err("No data left in proc file while parsing bpfmap\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define fdinfo_field(str, field) !strncmp(str, field":", sizeof(field))
|
||||
|
||||
static int parse_file_lock_buf(char *buf, struct file_lock *fl,
|
||||
|
|
@ -2014,6 +2065,18 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type, void *arg)
|
|||
entry_met = true;
|
||||
continue;
|
||||
}
|
||||
if (fdinfo_field(str, "map_type")) {
|
||||
BpfmapFileEntry *bpf = arg;
|
||||
if (type != FD_TYPES__BPFMAP)
|
||||
goto parse_err;
|
||||
|
||||
ret = parse_bpfmap(&f, str, bpf);
|
||||
if (ret)
|
||||
goto parse_err;
|
||||
|
||||
entry_met = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
exit_code = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue