diff --git a/criu/bpfmap.c b/criu/bpfmap.c index 0c5d4c5c37..e1cbad4bca 100644 --- a/criu/bpfmap.c +++ b/criu/bpfmap.c @@ -1,4 +1,5 @@ #include +#include #include "common/compiler.h" #include "imgset.h" @@ -11,6 +12,11 @@ #include "protobuf.h" #include "bpfmap-file.pb-c.h" +struct bpfmap_file_info { + BpfmapFileEntry *bpfe; + struct file_desc d; +}; + int is_bpfmap_link(char *link) { return is_anon_link_type(link, "bpf-map"); @@ -45,4 +51,77 @@ static int dump_one_bpfmap(int lfd, u32 id, const struct fd_parms *p) const struct fdtype_ops bpfmap_dump_ops = { .type = FD_TYPES__BPFMAP, .dump = dump_one_bpfmap, +}; + +static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, + unsigned int size) +{ + return syscall(__NR_bpf, cmd, attr, size); +} + +static int bpf_create_map(enum bpf_map_type map_type, + unsigned int key_size, + unsigned int value_size, + unsigned int max_entries) +{ + union bpf_attr attr = { + .map_type = map_type, + .key_size = key_size, + .value_size = value_size, + .max_entries = max_entries + }; + + return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); +} + +static int bpfmap_open(struct file_desc *d, int *new_fd) +{ + struct bpfmap_file_info *info; + BpfmapFileEntry *bpfe; + int tmp; + + info = container_of(d, struct bpfmap_file_info, d); + bpfe = info->bpfe; + + tmp = bpf_create_map(bpfe->map_type, bpfe->key_size, + bpfe->value_size, bpfe->max_entries); + if (tmp < 0) { + pr_perror("Can't create bpfmap %#08x", + bpfe->id); + return -1; + } + + if (rst_file_params(tmp, bpfe->fown, bpfe->flags)) { + pr_perror("Can't restore params on bpfmap %#08x", + bpfe->id); + goto err_close; + } + + *new_fd = tmp; + return 0; + +err_close: + close(tmp); + return -1; +} + +static struct file_desc_ops bpfmap_desc_ops = { + .type = FD_TYPES__BPFMAP, + .open = bpfmap_open, +}; + +static int collect_one_bpfmap(void *obj, ProtobufCMessage *msg, struct cr_img *i) +{ + struct bpfmap_file_info *info = obj; + + info->bpfe = pb_msg(msg, BpfmapFileEntry); + pr_info_bpfmap("Collected ", info->bpfe); + return file_desc_add(&info->d, info->bpfe->id, &bpfmap_desc_ops); +} + +struct collect_image_info bpfmap_cinfo = { + .fd_type = CR_FD_BPFMAP_FILE, + .pb_type = PB_BPFMAP_FILE, + .priv_size = sizeof(struct bpfmap_file_info), + .collect = collect_one_bpfmap, }; \ No newline at end of file diff --git a/criu/include/bpfmap.h b/criu/include/bpfmap.h index 7ed6b94047..d19c10405d 100644 --- a/criu/include/bpfmap.h +++ b/criu/include/bpfmap.h @@ -5,5 +5,6 @@ extern int is_bpfmap_link(char *link); extern const struct fdtype_ops bpfmap_dump_ops; +extern struct collect_image_info bpfmap_cinfo; #endif /* __CR_BPFMAP_H__ */ \ No newline at end of file