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

Reply via email to