From: Dmitry V. Levin Date: Mon, 15 Jul 2019 15:54:51 +0000 (+0000) Subject: tests: serialize bpf-obj_get_info_by_fd based executables X-Git-Tag: v5.3~121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6e1208271af257ed4dd51abfac44f35590da1427;p=strace tests: serialize bpf-obj_get_info_by_fd based executables Concurrent execution of many bpf-obj_get_info_by_fd based tests may lead to a temporary resource shortage that causes them to fail with the following error diagnostics: BPF_MAP_CREATE failed: Operation not permitted Avoid this issue by serializing execution of all relevant tests. * tests/lock_file.c: New file. * tests/Makefile.am (libtests_a_SOURCES): Add lock_file.c * tests/tests.h (lock_file_by_dirname): New prototype. * tests/bpf-obj_get_info_by_fd.c (main): Call lock_file_by_dirname to obtain an exclusive lock on bpf-obj_get_info_by_fd executable. References: https://github.com/strace/strace/issues/74 References: https://github.com/strace/strace/issues/105 --- diff --git a/tests/Makefile.am b/tests/Makefile.am index ab2ae78d..05aede5d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -40,6 +40,7 @@ libtests_a_SOURCES = \ inode_of_sockfd.c \ libmmsg.c \ libsocketcall.c \ + lock_file.c \ overflowuid.c \ pipe_maxfd.c \ print_quoted_string.c \ diff --git a/tests/bpf-obj_get_info_by_fd.c b/tests/bpf-obj_get_info_by_fd.c index 3e18591d..2bbebc30 100644 --- a/tests/bpf-obj_get_info_by_fd.c +++ b/tests/bpf-obj_get_info_by_fd.c @@ -232,8 +232,10 @@ try_bpf(kernel_ulong_t cmd, void (*printer)(void *attr, size_t size, long rc), } int -main(void) +main(int ac, char **av) { + lock_file_by_dirname(av[0], "bpf-obj_get_info_by_fd"); + struct BPF_MAP_CREATE_struct bpf_map_create_attr = { .map_type = BPF_MAP_TYPE_ARRAY, .key_size = 4, diff --git a/tests/lock_file.c b/tests/lock_file.c new file mode 100644 index 00000000..56cf112d --- /dev/null +++ b/tests/lock_file.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" + +#include +#include +#include +#include +#include +#include + +/* Obtain an exclusive lock on dirname(path_name)/lock_name file. */ +int +lock_file_by_dirname(const char *path_name, const char *lock_name) +{ + const char *slash = path_name ? strrchr(path_name, '/') : NULL; + const int plen = slash ? (int) (slash - path_name) + 1 : 0; + + char *lock_file = NULL; + if (asprintf(&lock_file, "%.*s%s", plen, path_name, lock_name) < 0) + perror_msg_and_fail("asprintf"); + + int lock_fd = open(lock_file, O_RDONLY); + if (lock_fd < 0) + perror_msg_and_fail("open: %s", lock_file); + + if (flock(lock_fd, LOCK_EX)) + perror_msg_and_fail("flock: %s", lock_file); + + free(lock_file); + + return lock_fd; +} diff --git a/tests/tests.h b/tests/tests.h index 4fca9886..8403bbb9 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -86,6 +86,12 @@ void perror_msg_and_skip(const char *, ...) /* Stat the specified file and skip the test if the stat call failed. */ void skip_if_unavailable(const char *); +/* + * Obtain an exclusive lock on dirname(path_name)/lock_name file + * using open and flock. + */ +int lock_file_by_dirname(const char *path_name, const char *lock_name); + /* * Allocate memory that ends on the page boundary. * Pages allocated by this call are preceded by an unmapped page