2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-29 13:28:27 +00:00

zdtm: update and refactor tests for BPF array and hash maps

This commit achieves the following:
a) Refactors ZDTM tests bpf_array.c and bpf_hash.c to make use of the
BPF ZDTM library functions. In addition, these tests now verify whether
information obtained from both procfs and BPF_OBJ_GET_INFO_BY_FD are
the same before and after c/r.
b) Updates ZDTM tests bpf_array.c and bpf_hash.c to include a BPF map's
name and also to freeze maps

Source files modified:

* zdtm/static/bpf_array.c
* zdtm/static/bpf_hash.c

Source files added:

* zdtm/static/bpf_array.desc
* zdtm/static/bpf_hash.desc

Note: ${test_name}.desc files have the 'suid' flag set because
BPF_MAP_FREEZE requires the global (root-userns) CAP_SYS_ADMIN or
CAP_BPF. Hence, only test flavors 'h' and 'ns' are executed ('uns'
is skipped) because BPF_MAP_FREEZE can't be used from non-root user
namespaces.

Signed-off-by: Abhishek Vijeev <abhishek.vijeev@gmail.com>
This commit is contained in:
Abhishek Vijeev 2020-09-12 18:05:28 +05:30 committed by Andrei Vagin
parent 8301c7e012
commit 82cd3bb0d0
4 changed files with 78 additions and 44 deletions

View File

@ -3,6 +3,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "zdtmtst.h" #include "zdtmtst.h"
#include "bpfmap_zdtm.h"
const char *test_doc = "Check that data and meta-data for BPF_MAP_TYPE_ARRAY" const char *test_doc = "Check that data and meta-data for BPF_MAP_TYPE_ARRAY"
"is correctly restored"; "is correctly restored";
@ -58,9 +59,13 @@ int main(int argc, char **argv)
int *keys = NULL, *values = NULL, *visited = NULL; int *keys = NULL, *values = NULL, *visited = NULL;
const uint32_t max_entries = 10; const uint32_t max_entries = 10;
int ret; int ret;
struct bpf_map_info map_info = {}; struct bpf_map_info old_map_info = {};
uint32_t info_len = sizeof(map_info); struct bpf_map_info new_map_info = {};
struct bpfmap_fdinfo_obj old_fdinfo = {};
struct bpfmap_fdinfo_obj new_fdinfo = {};
uint32_t info_len = sizeof(struct bpf_map_info);
struct bpf_create_map_attr xattr = { struct bpf_create_map_attr xattr = {
.name = "array_test_map",
.map_type = BPF_MAP_TYPE_ARRAY, .map_type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int), .key_size = sizeof(int),
.value_size = sizeof(int), .value_size = sizeof(int),
@ -95,34 +100,47 @@ int main(int argc, char **argv)
if (map_batch_update(map_fd, max_entries, keys, values)) if (map_batch_update(map_fd, max_entries, keys, values))
goto err; goto err;
ret = bpf_map_freeze(map_fd);
if (ret) {
pr_perror("Could not freeze map");
goto err;
}
ret = bpf_obj_get_info_by_fd(map_fd, &old_map_info, &info_len);
if (ret) {
pr_perror("Could not get old map info");
goto err;
}
ret = parse_bpfmap_fdinfo(map_fd, &old_fdinfo, 8);
if (ret) {
pr_perror("Could not parse old map fdinfo from procfs");
goto err;
}
test_daemon(); test_daemon();
test_waitsig(); test_waitsig();
ret = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len); ret = bpf_obj_get_info_by_fd(map_fd, &new_map_info, &info_len);
if (ret) { if (ret) {
pr_perror("Could not get map info"); pr_perror("Could not get new map info");
goto err;
}
ret = parse_bpfmap_fdinfo(map_fd, &new_fdinfo, 8);
if (ret) {
pr_perror("Could not parse new map fdinfo from procfs");
goto err; goto err;
} }
if (map_info.type != BPF_MAP_TYPE_ARRAY) { if (cmp_bpf_map_info(&old_map_info, &new_map_info)) {
pr_err("Map type should be BPF_MAP_TYPE_ARRAY\n"); pr_err("bpf_map_info mismatch\n");
goto err; goto err;
} }
if (map_info.key_size != sizeof(*keys)) {
pr_err("Key size should be %zu\n", sizeof(*keys)); if (cmp_bpfmap_fdinfo(&old_fdinfo, &new_fdinfo)) {
goto err; pr_err("bpfmap fdinfo mismatch\n");
}
if (map_info.value_size != sizeof(*values)) {
pr_err("Value size should be %zu\n", sizeof(*values));
goto err;
}
if (map_info.max_entries != max_entries) {
pr_err("Max entries should be %d\n", max_entries);
goto err;
}
if (!(map_info.map_flags & BPF_F_NUMA_NODE)) {
pr_err("Map flag BPF_F_NUMA_NODE should be set\n");
goto err; goto err;
} }

View File

@ -0,0 +1 @@
{'flavor': 'h ns', 'flags': 'suid'}

View File

@ -3,6 +3,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "zdtmtst.h" #include "zdtmtst.h"
#include "bpfmap_zdtm.h"
const char *test_doc = "Check that data and meta-data for BPF_MAP_TYPE_HASH" const char *test_doc = "Check that data and meta-data for BPF_MAP_TYPE_HASH"
"is correctly restored"; "is correctly restored";
@ -57,9 +58,13 @@ int main(int argc, char **argv)
int *keys = NULL, *values = NULL, *visited = NULL; int *keys = NULL, *values = NULL, *visited = NULL;
const uint32_t max_entries = 10; const uint32_t max_entries = 10;
int ret; int ret;
struct bpf_map_info map_info = {}; struct bpf_map_info old_map_info = {};
uint32_t info_len = sizeof(map_info); struct bpf_map_info new_map_info = {};
struct bpfmap_fdinfo_obj old_fdinfo = {};
struct bpfmap_fdinfo_obj new_fdinfo = {};
uint32_t info_len = sizeof(struct bpf_map_info);
struct bpf_create_map_attr xattr = { struct bpf_create_map_attr xattr = {
.name = "hash_test_map",
.map_type = BPF_MAP_TYPE_HASH, .map_type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(int), .key_size = sizeof(int),
.value_size = sizeof(int), .value_size = sizeof(int),
@ -94,38 +99,47 @@ int main(int argc, char **argv)
if (map_batch_update(map_fd, max_entries, keys, values)) if (map_batch_update(map_fd, max_entries, keys, values))
goto err; goto err;
ret = bpf_map_freeze(map_fd);
if (ret) {
pr_perror("Could not freeze map");
goto err;
}
ret = bpf_obj_get_info_by_fd(map_fd, &old_map_info, &info_len);
if (ret) {
pr_perror("Could not get old map info");
goto err;
}
ret = parse_bpfmap_fdinfo(map_fd, &old_fdinfo, 8);
if (ret) {
pr_perror("Could not parse old map fdinfo from procfs");
goto err;
}
test_daemon(); test_daemon();
test_waitsig(); test_waitsig();
ret = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len); ret = bpf_obj_get_info_by_fd(map_fd, &new_map_info, &info_len);
if (ret) { if (ret) {
pr_perror("Could not get map info"); pr_perror("Could not get new map info");
goto err;
}
ret = parse_bpfmap_fdinfo(map_fd, &new_fdinfo, 8);
if (ret) {
pr_perror("Could not parse new map fdinfo from procfs");
goto err; goto err;
} }
if (map_info.type != BPF_MAP_TYPE_HASH) { if (cmp_bpf_map_info(&old_map_info, &new_map_info)) {
pr_err("Map type should be BPF_MAP_TYPE_HASH\n"); pr_err("bpf_map_info mismatch\n");
goto err; goto err;
} }
if (map_info.key_size != sizeof(*keys)) {
pr_err("Key size should be %zu\n", sizeof(*keys)); if (cmp_bpfmap_fdinfo(&old_fdinfo, &new_fdinfo)) {
goto err; pr_err("bpfmap fdinfo mismatch\n");
}
if (map_info.value_size != sizeof(*values)) {
pr_err("Value size should be %zu\n", sizeof(*values));
goto err;
}
if (map_info.max_entries != max_entries) {
pr_err("Max entries should be %d\n", max_entries);
goto err;
}
if (!(map_info.map_flags & BPF_F_NO_PREALLOC)) {
pr_err("Map flag BPF_F_NO_PREALLOC should be set\n");
goto err;
}
if (!(map_info.map_flags & BPF_F_NUMA_NODE)) {
pr_err("Map flag BPF_F_NUMA_NODE should be set\n");
goto err; goto err;
} }

View File

@ -0,0 +1 @@
{'flavor': 'h ns', 'flags': 'suid'}