diff --git a/libos/test/regression/fork_and_mmap.c b/libos/test/regression/fork_and_mmap.c new file mode 100644 index 0000000000..6204b730fc --- /dev/null +++ b/libos/test/regression/fork_and_mmap.c @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* Copyright (C) 2023 IBM Corporation + * Stefan Berger + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#define NUM_PAGES 1024 + +int proceed = 0; + +static void* thread_func(void* arg) { + while (__atomic_load_n(&proceed, __ATOMIC_ACQUIRE) == 0) + usleep(1); + proceed = 0; + + usleep(1); + pid_t pid = fork(); + if (pid < 0) { + perror("fork failed\n"); + exit(1); + } + if (pid > 0) { + while (__atomic_load_n(&proceed, __ATOMIC_ACQUIRE) == 0) + usleep(1); + printf("TEST OK\n"); + } else { + printf("Child started\n"); + } + exit(0); +} + +int main(int argc, char** argv) { + long page_size = sysconf(_SC_PAGESIZE); + if (page_size == -1 && errno) { + err(1, "sysconf"); + } + + + pthread_t forker; + if (pthread_create(&forker, NULL, thread_func, NULL) != 0) { + perror("pthread_create failed"); + return 1; + } + + proceed = 1; + while (__atomic_load_n(&proceed, __ATOMIC_ACQUIRE) == 1); + + size_t i; + for (i = 0; i < NUM_PAGES; i++) + mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + + proceed = 1; + sleep(1); + + return 0; +} diff --git a/libos/test/regression/meson.build b/libos/test/regression/meson.build index 956faf8185..b388d03823 100644 --- a/libos/test/regression/meson.build +++ b/libos/test/regression/meson.build @@ -39,6 +39,7 @@ tests = { 'fork_and_close': {}, 'fork_and_exec': {}, 'fork_and_mprotect': {}, + 'fork_and_mmap': {}, 'fork_and_munmap': {}, 'fork_and_pthread_create': {}, 'fork_and_sbrk': {}, diff --git a/libos/test/regression/test_libos.py b/libos/test/regression/test_libos.py index 2878d22572..b952e91a84 100644 --- a/libos/test/regression/test_libos.py +++ b/libos/test/regression/test_libos.py @@ -1023,6 +1023,13 @@ def test_164_fork_and_sbrk(self): stdout, _ = self.run_binary(['fork_and_sbrk']) self.assertIn("TEST OK", stdout) + def test_165_fork_and_mmap(self): + for _ in range(0, 10): + stdout, _ = self.run_binary(['fork_and_mmap']) + self.assertIn("TEST OK", stdout) + # error: Sending IPC process-exit notification failed: Connection reset by peer (ECONNRESET) + self.assertNotIn("ECONNRESET", stdout) + class TC_31_Syscall(RegressionTestCase): def test_000_syscall_redirect(self): stdout, _ = self.run_binary(['syscall']) diff --git a/libos/test/regression/tests.toml b/libos/test/regression/tests.toml index 8a01fbacc7..9d9a32b90a 100644 --- a/libos/test/regression/tests.toml +++ b/libos/test/regression/tests.toml @@ -42,6 +42,7 @@ manifests = [ "fork_and_close", "fork_and_exec", "fork_and_mprotect", + "fork_and_mmap", "fork_and_munmap", "fork_and_pthread_create", "fork_and_sbrk", diff --git a/libos/test/regression/tests_musl.toml b/libos/test/regression/tests_musl.toml index 837c9846c0..fdcd82c541 100644 --- a/libos/test/regression/tests_musl.toml +++ b/libos/test/regression/tests_musl.toml @@ -44,6 +44,7 @@ manifests = [ "fork_and_close", "fork_and_exec", "fork_and_mprotect", + "fork_and_mmap", "fork_and_munmap", "fork_and_pthread_create", "fork_and_sbrk",