From ba33d90ed67b787a11b26bc69f9553d0d52dfe45 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 9 May 2018 12:53:53 +1200 Subject: [PATCH] ldb: Ensure we can open a new LDB after a fork() Based on work for an mdb-specific test by Gary Lockyer Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Wed May 9 07:27:24 CEST 2018 on sn-devel-144 --- lib/ldb/tests/ldb_mod_op_test.c | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/lib/ldb/tests/ldb_mod_op_test.c b/lib/ldb/tests/ldb_mod_op_test.c index 78084ef3c9d..67ac024db86 100644 --- a/lib/ldb/tests/ldb_mod_op_test.c +++ b/lib/ldb/tests/ldb_mod_op_test.c @@ -4025,6 +4025,66 @@ static void test_lock_read_across_fork(void **state) } } +static void test_multiple_opens_across_fork(void **state) +{ + struct ldb_context *ldb1 = NULL; + struct ldb_context *ldb2 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + int pipes[2]; + char buf[2]; + int wstatus; + pid_t pid, child_pid; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database again + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + ldb2 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb2, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + struct ldb_context *ldb3 = NULL; + + close(pipes[0]); + ldb3 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); + if (ret != 0) { + print_error(__location__": ldb_connect returned (%d)\n", + ret); + exit(ret); + } + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + print_error(__location__ + " write returned (%d)", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + exit(LDB_SUCCESS); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); +} + int main(int argc, const char **argv) { const struct CMUnitTest tests[] = { @@ -4200,6 +4260,10 @@ int main(int argc, const char **argv) test_lock_read_across_fork, ldbtest_setup, ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_multiple_opens_across_fork, + ldbtest_setup, + ldbtest_teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); -- 2.34.1