The branch, master has been updated via 6c0d053 s4: torture: Ensure kernel oplock test can't hang in pause(). from f8cd211 s3: smbclient: tests: Test "volume" command over SMB1 and SMB2+.
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 6c0d053ec0ea54e4152878564c5d21dfae9f346b Author: Jeremy Allison <j...@samba.org> Date: Wed Nov 15 10:12:06 2017 -0800 s4: torture: Ensure kernel oplock test can't hang in pause(). Use an alarm to break out of waiting for a signal. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13121 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Thu Nov 16 22:27:06 CET 2017 on sn-devel-144 ----------------------------------------------------------------------- Summary of changes: source4/torture/smb2/oplock.c | 67 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) Changeset truncated at 500 lines: diff --git a/source4/torture/smb2/oplock.c b/source4/torture/smb2/oplock.c index 1830a01..b6d9f84 100644 --- a/source4/torture/smb2/oplock.c +++ b/source4/torture/smb2/oplock.c @@ -4817,6 +4817,17 @@ static void got_rt_break(int sig) got_break = 1; } +static int got_alarm; + +/* + * Signal handler. + */ + +static void got_alarm_fn(int sig) +{ + got_alarm = 1; +} + /* * Child process function. */ @@ -4835,6 +4846,13 @@ static int do_child_process(int pipefd, const char *name) if (ret == -1) { return 1; } + /* Set up a signal handler for SIGALRM. */ + ZERO_STRUCT(act); + act.sa_handler = got_alarm_fn; + ret = sigaction(SIGALRM, &act, NULL); + if (ret == -1) { + return 1; + } /* Open the passed in file and get a kernel oplock. */ fd = open(name, O_RDWR, 0666); if (fd == -1) { @@ -4857,16 +4875,26 @@ static int do_child_process(int pipefd, const char *name) return 5; } + /* Ensure the pause doesn't hang forever. */ + alarm(5); + /* Wait for RT_SIGNAL_LEASE. */ ret = pause(); if (ret != -1 || errno != EINTR) { return 6; } + if (got_alarm == 1) { + return 10; + } + if (got_break != 1) { return 7; } + /* Cancel any pending alarm. */ + alarm(0); + /* Force the server to wait for 3 seconds. */ sleep(3); @@ -4928,6 +4956,23 @@ static bool wait_for_child_oplock(struct torture_context *tctx, } #endif +static void child_sig_term_handler(struct tevent_context *ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + void *private_data) +{ + int *pstatus = (int *)private_data; + int status; + wait(&status); + if (WIFEXITED(status)) { + *pstatus = WEXITSTATUS(status); + } else { + *pstatus = status; + } +} + /* * Deal with a non-smbd process holding a kernel oplock. */ @@ -4944,6 +4989,8 @@ static bool test_smb2_kernel_oplocks8(struct torture_context *tctx, struct smb2_handle h1 = {{0}}; struct smb2_handle h2 = {{0}}; const char *localdir = torture_setting_string(tctx, "localdir", NULL); + struct tevent_signal *se = NULL; + int child_exit_code = -1; time_t start; time_t end; @@ -4963,6 +5010,14 @@ static bool test_smb2_kernel_oplocks8(struct torture_context *tctx, smb2_util_close(tree, h1); ZERO_STRUCT(h1); + se = tevent_add_signal(tctx->ev, + tctx, + SIGCHLD, + 0, + child_sig_term_handler, + &child_exit_code); + torture_assert(tctx, se != NULL, "tevent_add_signal failed\n"); + /* Take the oplock locally in a sub-process. */ ret = wait_for_child_oplock(tctx, localdir, fname); torture_assert_goto(tctx, ret = true, ret, done, @@ -5013,6 +5068,18 @@ static bool test_smb2_kernel_oplocks8(struct torture_context *tctx, "Error opening the file\n"); h2 = io.out.file.handle; + /* Wait for the exit code from the child. */ + while (child_exit_code == -1) { + int rval = tevent_loop_once(tctx->ev); + torture_assert(tctx, rval == 0, "tevent_loop_once error\n"); + } + + if (child_exit_code != 0) { + torture_comment(tctx, "Bad child exit code %d\n", + child_exit_code); + ret = false; + } + done: if (!smb2_util_handle_empty(h1)) { smb2_util_close(tree, h1); -- Samba Shared Repository