[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Thu Mar 15 13:21:02 MDT 2012


The branch, master has been updated
       via  79a1bae s4:selftest: make the use of writetimeupdatedelay consistent across all tests
       via  64627de s3:selftest: reactivate the writetimeupdatedelay speed-up
       via  c80f703 s3:smbd: let smbd/nmbd/winbindd child processes terminate if the parent process died.
      from  e5ebe67 idl: add offload data transfer ioctl types

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 79a1baec86312d02b9aa67d364eedb80bb13480d
Author: Michael Adam <obnox at samba.org>
Date:   Thu Mar 15 17:32:51 2012 +0100

    s4:selftest: make the use of writetimeupdatedelay consistent across all tests
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User: Michael Adam <obnox at samba.org>
    Autobuild-Date: Thu Mar 15 20:20:13 CET 2012 on sn-devel-104

commit 64627de35c205572119a32b7afc1bdfd07b8f26b
Author: Michael Adam <obnox at samba.org>
Date:   Thu Mar 15 17:28:38 2012 +0100

    s3:selftest: reactivate the writetimeupdatedelay speed-up
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>

commit c80f70390c3763d5d7248979db9542cd05b7cb44
Author: Michael Adam <obnox at samba.org>
Date:   Thu Mar 15 16:29:27 2012 +0100

    s3:smbd: let smbd/nmbd/winbindd child processes terminate if the parent process died.
    
    This applies to all child processes making use of reinit_after_fork().
    It is implemented by establishing a pipe between parent and child.
    The child watches for EOF on the read end of the pipe, indidcating
    an exited parent.
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 selftest/target/Samba3.pm   |    2 +-
 selftest/target/Samba4.pm   |    6 ++--
 source3/include/proto.h     |    1 +
 source3/lib/util.c          |   56 +++++++++++++++++++++++++++++++++++++++++++
 source3/nmbd/nmbd.c         |   11 ++++++++
 source3/selftest/tests.py   |    3 +-
 source3/smbd/server.c       |   13 ++++++++++
 source3/winbindd/winbindd.c |   11 ++++++++
 8 files changed, 98 insertions(+), 5 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 7e4e601..077e600 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -934,7 +934,7 @@ sub provision($$$$$$)
 	server signing = auto
 
 	smbd:sharedelay = 100000
-#	smbd:writetimeupdatedelay = 500000
+	smbd:writetimeupdatedelay = 500000
 	map hidden = no
 	map system = no
 	map readonly = no
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index d9385c8..c46f192 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -733,14 +733,14 @@ sub provision($$$$$$$$)
 	read only = no
 	posix:sharedelay = 10000
 	posix:oplocktimeout = 3
-	posix:writetimeupdatedelay = 500000
+	posix:writetimeupdatedelay = 50000
 
 [xcopy_share]
 	path = $ctx->{tmpdir}
 	read only = no
 	posix:sharedelay = 10000
 	posix:oplocktimeout = 3
-	posix:writetimeupdatedelay = 500000
+	posix:writetimeupdatedelay = 50000
 	create mask = 777
 	force create mode = 777
 
@@ -1220,7 +1220,7 @@ sub provision_rodc($$$)
 	read only = no
 	posix:sharedelay = 10000
 	posix:oplocktimeout = 3
-	posix:writetimeupdatedelay = 500000
+	posix:writetimeupdatedelay = 50000
 
 ";
 
diff --git a/source3/include/proto.h b/source3/include/proto.h
index e0d9f31..e8a0d42 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -484,6 +484,7 @@ char *unix_clean_name(TALLOC_CTX *ctx, const char *s);
 char *clean_name(TALLOC_CTX *ctx, const char *s);
 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos);
 int set_blocking(int fd, bool set);
+NTSTATUS init_before_fork(void);
 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
 			   struct event_context *ev_ctx,
 			   bool parent_longlived);
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 822db43..fa2cc9f 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -356,6 +356,46 @@ ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos
 #endif
 }
 
+static int reinit_after_fork_pipe[2] = { -1, -1 };
+
+NTSTATUS init_before_fork(void)
+{
+	int ret;
+
+	ret = pipe(reinit_after_fork_pipe);
+	if (ret == -1) {
+		NTSTATUS status;
+
+		status = map_nt_error_from_unix_common(errno);
+
+		DEBUG(0, ("Error creating child_pipe: %s\n",
+			  nt_errstr(status)));
+
+		return status;
+	}
+
+	return NT_STATUS_OK;
+}
+
+/**
+ * Detect died parent by detecting EOF on the pipe
+ */
+static void reinit_after_fork_pipe_handler(struct tevent_context *ev,
+					   struct tevent_fd *fde,
+					   uint16_t flags,
+					   void *private_data)
+{
+	char c;
+
+	if (read(reinit_after_fork_pipe[0], &c, 1) != 1) {
+		/*
+		 * we have reached EOF on stdin, which means the
+		 * parent has exited. Shutdown the server
+		 */
+		(void)kill(getpid(), SIGTERM);
+	}
+}
+
 
 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
 			   struct event_context *ev_ctx,
@@ -363,6 +403,11 @@ NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
 {
 	NTSTATUS status = NT_STATUS_OK;
 
+	if (reinit_after_fork_pipe[1] != -1) {
+		close(reinit_after_fork_pipe[1]);
+		reinit_after_fork_pipe[1] = -1;
+	}
+
 	/* Reset the state of the random
 	 * number generation system, so
 	 * children do not get the same random
@@ -380,6 +425,17 @@ NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
 		smb_panic(__location__ ": Failed to re-initialise event context");
 	}
 
+	if (reinit_after_fork_pipe[0] != -1) {
+		struct tevent_fd *fde;
+
+		fde = tevent_add_fd(ev_ctx, ev_ctx /* TALLOC_CTX */,
+				    reinit_after_fork_pipe[0], TEVENT_FD_READ,
+				    reinit_after_fork_pipe_handler, NULL);
+		if (fde == NULL) {
+			smb_panic(__location__ ": Failed to add reinit_after_fork pipe event");
+		}
+	}
+
 	if (msg_ctx) {
 		/*
 		 * For clustering, we need to re-init our ctdbd connection after the
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 52d7ed9..eff1eca 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -951,6 +951,17 @@ static bool open_sockets(bool isdaemon, int port)
 		exit(1);
 	}
 
+	/*
+	 * Do not initialize the parent-child-pipe before becoming
+	 * a daemon: this is used to detect a died parent in the child
+	 * process.
+	 */
+	status = init_before_fork();
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("init_before_fork failed: %s\n", nt_errstr(status)));
+		exit(1);
+	}
+
 	if (!nmbd_setup_sig_term_handler(msg))
 		exit(1);
 	if (!nmbd_setup_stdin_handler(msg, !Fork))
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 8bd16e0..cbef215 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -31,7 +31,8 @@ torture_options = [configuration, "--maximum-runtime=$SELFTEST_MAXTIME",
                    "--target=samba3", "--basedir=$SELFTEST_TMPDIR",
                    '--option="torture:winbindd_netbios_name=$SERVER"',
                    '--option="torture:winbindd_netbios_domain=$DOMAIN"', 
-                   '--option=torture:sharedelay=100000']
+                   '--option=torture:sharedelay=100000',
+                   '--option=torture:writetimeupdatedelay=500000' ]
 
 if not os.getenv("SELFTEST_VERBOSE"):
     torture_options.append("--option=torture:progress=no")
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index aa3da1f..851b460 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -57,6 +57,8 @@ struct smbd_parent_context {
 	/* the list of current child processes */
 	struct smbd_child_pid *children;
 	size_t num_children;
+	/* pipe for detecting death of parent process in child: */
+	int child_pipe[2];
 
 	struct timed_event *cleanup_te;
 };
@@ -1231,6 +1233,17 @@ extern void build_options(bool screen);
 		exit(1);
 	}
 
+	/*
+	 * Do not initialize the parent-child-pipe before becoming
+	 * a daemon: this is used to detect a died parent in the child
+	 * process.
+	 */
+	status = init_before_fork();
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("init_before_fork failed: %s\n", nt_errstr(status)));
+		exit(1);
+	}
+
 	smbd_server_conn->msg_ctx = msg_ctx;
 
 	parent = talloc_zero(ev_ctx, struct smbd_parent_context);
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index d1d36fd..66e53d9 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -1461,6 +1461,17 @@ int main(int argc, char **argv, char **envp)
 		exit(1);
 	}
 
+	/*
+	 * Do not initialize the parent-child-pipe before becoming
+	 * a daemon: this is used to detect a died parent in the child
+	 * process.
+	 */
+	status = init_before_fork();
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("init_before_fork failed: %s\n", nt_errstr(status)));
+		exit(1);
+	}
+
 	winbindd_register_handlers(!Fork);
 
 	status = init_system_info();


-- 
Samba Shared Repository


More information about the samba-cvs mailing list