[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed Dec 19 07:09:02 UTC 2018


The branch, master has been updated
       via  5118985841a lib/util: Count a trailing line that doesn't end in a newline
       via  b3e4e094261 s4 messaging: Add support for smbcontrol sleep
       via  a70deab0fb3 s3 server: Add support for smbcontrol sleep
       via  ff9052c923d s3 smbcontrol: Add sleep command
       via  b578fad88e3 s4 messaging tests: Tests for smbcontrol sleep command
       via  8167486b999 s4 messaging: support smbcontrol inject fault command
       via  8741af7af68 s4 messaging tests: Add inject fault command
      from  c817deca0c7 s4: Remove double init of kerberos error table

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


- Log -----------------------------------------------------------------
commit 5118985841aa0363147d552f243ab5a7d90dbdaf
Author: Martin Schwenke <martin at meltin.net>
Date:   Fri Dec 14 14:43:57 2018 +1100

    lib/util: Count a trailing line that doesn't end in a newline
    
    If the final line of a file does not contain a newline then it isn't
    included in the line count.
    
    Change i to point to the next slot in the array instead of the current
    one.  This means that that the current line won't be thrown away if no
    newline is seen.
    
    Without changing i to unsigned int, the -O3 --picky -developer build
    fails with:
    
    [ 745/4136] Compiling lib/util/util_file.c
    
    ==> /builds/samba-team/devel/samba/samba-o3.stderr <==
    ../../lib/util/util_file.c: In function ‘file_lines_parse’:
    ../../lib/util/util_file.c:251:8: error: assuming signed overflow does not occur when simplifying conditional to constant [-Werror=strict-overflow]
      while (i > 0 && ret[i-1][0] == 0) {
            ^
    cc1: all warnings being treated as errors
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13717
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Dec 19 08:08:28 CET 2018 on sn-devel-144

commit b3e4e094261c039320f6ad999043f78695e56021
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Dec 11 11:43:52 2018 +1300

    s4 messaging: Add support for smbcontrol sleep
    
    Add a sleep command that pauses the target process for the specified
    number of seconds
    
    This command is only enabled on developer and self test builds.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a70deab0fb3726611a041c83d616cda2594264c7
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Dec 11 11:39:23 2018 +1300

    s3 server: Add support for smbcontrol sleep
    
    Add a sleep command that pauses the target process for the specified number
    of seconds
    
    This command is only enabled on self test and developer builds.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit ff9052c923d1f474696022527663b64f60195a05
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Dec 4 09:31:22 2018 +1300

    s3 smbcontrol: Add sleep command
    
    Add a sleep command that pauses the target process for the specified
    number of seconds
    
    This command is only enabled on developer and self test builds.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b578fad88e3b5a62fa060474b52dbc7e59fd6a24
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Wed Dec 5 14:50:22 2018 +1300

    s4 messaging tests: Tests for smbcontrol sleep command
    
    Add a sleep command that pauses the target process for the specified
    number seconds
    
    This command is only enabled on developer and self test builds.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 8167486b99920f48db48ebc1574b5c8032647555
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Dec 11 11:04:25 2018 +1300

    s4 messaging: support smbcontrol inject fault command
    
    Add support of the smbcontrol inject fault command to the samba daemon.
    This is useful for manual testing of process restart etc.
    
    command is only enabled for developer and self test builds
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 8741af7af68b2d74123dc3f82dad3ca746f4caf5
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Dec 11 11:01:09 2018 +1300

    s4 messaging tests: Add inject fault command
    
    Test for processing of the smbcontrol inject fault message in the samba
    daemon.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 lib/util/tests/file.c                             | 152 ++++++++++++++++++++++
 lib/util/util_file.c                              |   6 +-
 librpc/idl/messaging.idl                          |   1 +
 python/samba/tests/blackbox/smbcontrol_process.py | 124 ++++++++++++++++++
 source3/smbd/server.c                             |  34 +++++
 source3/utils/smbcontrol.c                        |  46 ++++++-
 source4/lib/messaging/messaging.c                 |  10 ++
 source4/lib/messaging/messaging_handlers.c        | 121 +++++++++++++++++
 source4/lib/messaging/messaging_internal.h        |   2 +
 source4/lib/messaging/wscript_build               |   2 +-
 source4/selftest/tests.py                         |   7 +
 11 files changed, 497 insertions(+), 8 deletions(-)
 create mode 100644 python/samba/tests/blackbox/smbcontrol_process.py
 create mode 100644 source4/lib/messaging/messaging_handlers.c


Changeset truncated at 500 lines:

diff --git a/lib/util/tests/file.c b/lib/util/tests/file.c
index f349c214f08..ca0416e20e6 100644
--- a/lib/util/tests/file.c
+++ b/lib/util/tests/file.c
@@ -60,6 +60,154 @@ static bool test_file_load_save(struct torture_context *tctx)
 	return true;
 }
 
+#define TEST_DATA_WITH_NEWLINE TEST_DATA "\n"
+#define TEST_DATA_NO_NEWLINE TEST_DATA
+#define TEST_DATA_EMPTY ""
+#define TEST_DATA_BLANKS_ONLY "\n\n\n\n\n"
+#define TEST_DATA_WITH_TRAILING_BLANKS TEST_DATA TEST_DATA_BLANKS_ONLY
+
+static bool test_file_lines_load(struct torture_context *tctx)
+{
+	char **lines;
+	int numlines;
+	TALLOC_CTX *mem_ctx = tctx;
+
+	/*
+	 * Last line has trailing whitespace
+	 */
+
+	torture_assert(tctx,
+		       file_save(TEST_FILENAME,
+				 TEST_DATA_WITH_NEWLINE,
+				 strlen(TEST_DATA_WITH_NEWLINE)),
+		       "saving file");
+
+	lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+	torture_assert_int_equal(tctx, numlines, 3, "Lines");
+
+	torture_assert_mem_equal(tctx,
+				 lines[0],
+				 TEST_LINE1,
+				 strlen(TEST_LINE1),
+				 "Line 1");
+
+	torture_assert_mem_equal(tctx,
+				 lines[1],
+				 TEST_LINE2,
+				 strlen(TEST_LINE2),
+				 "Line 2");
+
+	torture_assert_mem_equal(tctx,
+				 lines[2],
+				 TEST_LINE3,
+				 strlen(TEST_LINE3),
+				 "Line 3");
+
+	unlink(TEST_FILENAME);
+
+	/*
+	 * Last line has NO trailing whitespace
+	 */
+
+	torture_assert(tctx,
+		       file_save(TEST_FILENAME,
+				 TEST_DATA_NO_NEWLINE,
+				 strlen(TEST_DATA_NO_NEWLINE)),
+		       "saving file");
+
+	lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+	torture_assert_int_equal(tctx, numlines, 3, "Lines");
+
+	torture_assert_mem_equal(tctx,
+				 lines[0],
+				 TEST_LINE1,
+				 strlen(TEST_LINE1),
+				 "Line 1");
+
+	torture_assert_mem_equal(tctx,
+				 lines[1],
+				 TEST_LINE2,
+				 strlen(TEST_LINE2),
+				 "Line 2");
+
+	torture_assert_mem_equal(tctx,
+				 lines[2],
+				 TEST_LINE3,
+				 strlen(TEST_LINE3),
+				 "Line 3");
+
+	unlink(TEST_FILENAME);
+
+	/*
+	 * Empty file
+	 */
+
+	torture_assert(tctx,
+		       file_save(TEST_FILENAME,
+				 TEST_DATA_EMPTY,
+				 strlen(TEST_DATA_EMPTY)),
+		       "saving file");
+
+	lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+	torture_assert_int_equal(tctx, numlines, 0, "Lines");
+
+	unlink(TEST_FILENAME);
+
+	/*
+	 * Just blank lines
+	 */
+
+	torture_assert(tctx,
+		       file_save(TEST_FILENAME,
+				 TEST_DATA_BLANKS_ONLY,
+				 strlen(TEST_DATA_BLANKS_ONLY)),
+		       "saving file");
+
+	lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+	torture_assert_int_equal(tctx, numlines, 0, "Lines");
+
+	unlink(TEST_FILENAME);
+
+	/*
+	 * Several trailing blank lines
+	 */
+
+	torture_assert(tctx,
+		       file_save(TEST_FILENAME,
+				 TEST_DATA_WITH_TRAILING_BLANKS,
+				 strlen(TEST_DATA_WITH_TRAILING_BLANKS)),
+		       "saving file");
+
+	lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+	torture_assert_int_equal(tctx, numlines, 3, "Lines");
+
+	torture_assert_mem_equal(tctx,
+				 lines[0],
+				 TEST_LINE1,
+				 strlen(TEST_LINE1),
+				 "Line 1");
+
+	torture_assert_mem_equal(tctx,
+				 lines[1],
+				 TEST_LINE2,
+				 strlen(TEST_LINE2),
+				 "Line 2");
+
+	torture_assert_mem_equal(tctx,
+				 lines[2],
+				 TEST_LINE3,
+				 strlen(TEST_LINE3),
+				 "Line 3");
+
+	unlink(TEST_FILENAME);
+
+	return true;
+}
 
 static bool test_afdgets(struct torture_context *tctx)
 {
@@ -102,6 +250,10 @@ struct torture_suite *torture_local_util_file(TALLOC_CTX *mem_ctx)
 	torture_suite_add_simple_test(suite, "file_load_save", 
 				      test_file_load_save);
 
+	torture_suite_add_simple_test(suite,
+				      "file_lines_load",
+				      test_file_lines_load);
+
 	torture_suite_add_simple_test(suite, "afdgets", test_afdgets);
 
 	return suite;
diff --git a/lib/util/util_file.c b/lib/util/util_file.c
index bf2f3e1a27f..926eda240f6 100644
--- a/lib/util/util_file.c
+++ b/lib/util/util_file.c
@@ -220,7 +220,7 @@ parse a buffer into lines
 **/
 char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
 {
-	int i;
+	unsigned int i;
 	char *s, **ret;
 
 	if (!p) return NULL;
@@ -238,11 +238,11 @@ char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx
 	talloc_steal(ret, p);
 
 	ret[0] = p;
-	for (s = p, i=0; s < p+size; s++) {
+	for (s = p, i=1; s < p+size; s++) {
 		if (s[0] == '\n') {
 			s[0] = 0;
-			i++;
 			ret[i] = s+1;
+			i++;
 		}
 		if (s[0] == '\r') s[0] = 0;
 	}
diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl
index c916768ccec..c2f62f673b2 100644
--- a/librpc/idl/messaging.idl
+++ b/librpc/idl/messaging.idl
@@ -109,6 +109,7 @@ interface messaging
 		MSG_SMB_NOTIFY_DB		= 0x031D,
 		MSG_SMB_NOTIFY_REC_CHANGES	= 0x031E,
 		MSG_SMB_NOTIFY_STARTED          = 0x031F,
+		MSG_SMB_SLEEP			= 0x0320,
 
 		/* winbind messages */
 		MSG_WINBIND_FINISHED		= 0x0401,
diff --git a/python/samba/tests/blackbox/smbcontrol_process.py b/python/samba/tests/blackbox/smbcontrol_process.py
new file mode 100644
index 00000000000..4313c6faef3
--- /dev/null
+++ b/python/samba/tests/blackbox/smbcontrol_process.py
@@ -0,0 +1,124 @@
+# Blackbox tests for the smbcontrol fault injection commands
+#
+# Copyright (C) Andrew Bartlett <abartlet at samba.org> 2018
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# As the test terminates and sleeps samba processes these tests need to run
+# in the preforkrestartdc test environment to prevent them impacting other
+# tests.
+#
+from __future__ import print_function
+import time
+from samba.tests import BlackboxTestCase, BlackboxProcessError
+from samba.messaging import Messaging
+
+COMMAND = "bin/smbcontrol"
+PING = "ping"
+
+
+class SmbcontrolProcessBlockboxTests(BlackboxTestCase):
+
+    def setUp(self):
+        super(SmbcontrolProcessBlockboxTests, self).setUp()
+        lp_ctx = self.get_loadparm()
+        self.msg_ctx = Messaging(lp_ctx=lp_ctx)
+
+    def get_process_data(self):
+        services = self.msg_ctx.irpc_all_servers()
+
+        processes = []
+        for service in services:
+            for id in service.ids:
+                processes.append((service.name, id.pid))
+        return processes
+
+    def get_process(self, name):
+        processes = self.get_process_data()
+        for pname, pid in processes:
+            if name == pname:
+                return pid
+        return None
+
+    def test_inject_fault(self):
+        INJECT = "inject"
+        FAULT = "segv"
+        pid = self.get_process("rpc_server")
+
+        #
+        # Ensure we can ping the process before injecting a fault.
+        #
+        try:
+            self.check_run("%s %s %s" % (COMMAND, pid, PING),
+                           msg="trying to ping rpc_server")
+        except BlackboxProcessError as e:
+            self.fail("Unable to ping rpc_server process")
+
+        #
+        # Now inject a fault.
+        #
+        try:
+            self.check_run("%s %s %s %s" % (COMMAND, pid, INJECT, FAULT),
+                           msg="injecting fault into rpc_server")
+        except BlackboxProcessError as e:
+            print(e)
+            self.fail("Unable to inject a fault into the rpc_server process")
+
+        #
+        # The process should have died, so we should not be able to ping it
+        #
+        try:
+            self.check_run("%s %s %s" % (COMMAND, pid, PING),
+                           msg="trying to ping rpc_server")
+            self.fail("Could ping rpc_server process")
+        except BlackboxProcessError as e:
+            pass
+
+    def test_sleep(self):
+        SLEEP = "sleep"  # smbcontrol sleep command
+        DURATION = 5     # duration to sleep server for
+        DELTA = 1        # permitted error for the sleep duration
+
+        pid = self.get_process("rpc_server")
+        #
+        # Ensure we can ping the process before getting it to sleep
+        #
+        try:
+            self.check_run("%s %s %s" % (COMMAND, pid, PING),
+                           msg="trying to ping rpc_server")
+        except BlackboxProcessError as e:
+            self.fail("Unable to ping rpc_server process")
+
+        #
+        # Now ask it to sleep
+        #
+        start = time.time()
+        try:
+            self.check_run("%s %s %s %s" % (COMMAND, pid, SLEEP, DURATION),
+                           msg="putting rpc_server to sleep for %d" % DURATION)
+        except BlackboxProcessError as e:
+            print(e)
+            self.fail("Failed to get rpc_server to sleep for %d" % DURATION)
+
+        #
+        # The process should be sleeping and not respond until it wakes
+        #
+        try:
+            self.check_run("%s %s %s" % (COMMAND, pid, PING),
+                           msg="trying to ping rpc_server")
+            end = time.time()
+            duration = end - start
+            self.assertGreater(duration + DELTA, DURATION)
+        except BlackboxProcessError as e:
+            self.fail("Unable to ping rpc_server process")
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 68cd1d7bd54..871bb923449 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -193,6 +193,36 @@ static void msg_inject_fault(struct messaging_context *msg,
 }
 #endif /* DEVELOPER */
 
+#if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
+/*
+ * Sleep for the specified number of seconds.
+ */
+static void msg_sleep(struct messaging_context *msg,
+		      void *private_data,
+		      uint32_t msg_type,
+		      struct server_id src,
+		      DATA_BLOB *data)
+{
+	unsigned int seconds;
+	struct server_id_buf tmp;
+
+	if (data->length != sizeof(seconds)) {
+		DBG_ERR("Process %s sent bogus sleep request\n",
+			server_id_str_buf(src, &tmp));
+		return;
+	}
+
+	seconds = *(unsigned int *)data->data;
+	DBG_ERR("Process %s request a sleep of %u seconds\n",
+		server_id_str_buf(src, &tmp),
+		seconds);
+	sleep(seconds);
+	DBG_ERR("Restarting after %u second sleep requested by process %s\n",
+		seconds,
+		server_id_str_buf(src, &tmp));
+}
+#endif /* DEVELOPER */
+
 static NTSTATUS messaging_send_to_children(struct messaging_context *msg_ctx,
 					   uint32_t msg_type, DATA_BLOB* data)
 {
@@ -1301,6 +1331,10 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
 			   msg_inject_fault);
 #endif
 
+#if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
+	messaging_register(msg_ctx, NULL, MSG_SMB_SLEEP, msg_sleep);
+#endif
+
 	if (lp_multicast_dns_register() && (dns_port != 0)) {
 #ifdef WITH_DNSSD_SUPPORT
 		smbd_setup_mdns_registration(ev_ctx,
diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c
index 866217c248b..1d60f0eeef8 100644
--- a/source3/utils/smbcontrol.c
+++ b/source3/utils/smbcontrol.c
@@ -380,11 +380,11 @@ static bool do_inject_fault(struct tevent_context *ev_ctx,
 		return False;
 	}
 
-#ifndef DEVELOPER
+#if !defined(DEVELOPER) && !defined(ENABLE_SELFTEST)
 	fprintf(stderr, "Fault injection is only available in "
-		"developer builds\n");
+		"developer and self test builds\n");
 	return False;
-#else /* DEVELOPER */
+#else /* DEVELOPER || ENABLE_SELFTEST */
 	{
 		int sig = 0;
 
@@ -407,7 +407,44 @@ static bool do_inject_fault(struct tevent_context *ev_ctx,
 		return send_message(msg_ctx, pid, MSG_SMB_INJECT_FAULT,
 				    &sig, sizeof(int));
 	}
-#endif /* DEVELOPER */
+#endif /* DEVELOPER || ENABLE_SELFTEST */
+}
+
+static bool do_sleep(struct tevent_context *ev_ctx,
+		     struct messaging_context *msg_ctx,
+		     const struct server_id pid,
+		     const int argc, const char **argv)
+{
+	unsigned int seconds;
+	long input;
+	const long MAX_SLEEP = 60 * 60; /* One hour maximum sleep */
+
+	if (argc != 2) {
+		fprintf(stderr, "Usage: smbcontrol <dest> sleep seconds\n");
+		return False;
+	}
+
+#if !defined(DEVELOPER) && !defined(ENABLE_SELFTEST)
+	fprintf(stderr, "Sleep is only available in "
+		"developer and self test builds\n");
+	return False;
+#else /* DEVELOPER || ENABLE_SELFTEST */
+
+	input = atol(argv[1]);
+	if (input < 1 || input > MAX_SLEEP) {
+		fprintf(stderr,
+			"Invalid duration for sleep '%s'\n"
+			"It should be at least 1 second and no more than %ld\n",
+			argv[1],
+			MAX_SLEEP);
+		return False;
+	}
+	seconds = input;
+	return send_message(msg_ctx, pid,
+			    MSG_SMB_SLEEP,
+			    &seconds,
+			    sizeof(unsigned int));
+#endif /* DEVELOPER || ENABLE_SELFTEST */
 }
 
 /* Force a browser election */
@@ -1421,6 +1458,7 @@ static const struct {
 	  "Print number of smbd child processes" },
 	{ "msg-cleanup", do_msg_cleanup },
 	{ "noop", do_noop, "Do nothing" },
+	{ "sleep", do_sleep, "Cause the target process to sleep" },
 	{ NULL }
 };
 
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index 413a19445eb..59c48cd44cb 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -464,6 +464,16 @@ static struct imessaging_context *imessaging_init_internal(TALLOC_CTX *mem_ctx,
 	if (!NT_STATUS_IS_OK(status)) {
 		goto fail;
 	}
+#if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
+	/*
+	 * Register handlers for messages specific to developer and
+	 * self test builds
+	 */
+	status = imessaging_register_extra_handlers(msg);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto fail;
+	}
+#endif /* defined(DEVELOPER) || defined(ENABLE_SELFTEST) */
 
 	DLIST_ADD(msg_ctxs, msg);
 
diff --git a/source4/lib/messaging/messaging_handlers.c b/source4/lib/messaging/messaging_handlers.c
new file mode 100644
index 00000000000..aee7b66e306
--- /dev/null
+++ b/source4/lib/messaging/messaging_handlers.c
@@ -0,0 +1,121 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Handers for non core Samba internal messages
+
+   Handlers for messages that are only included in developer and self test
+   builds.
+
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2018


-- 
Samba Shared Repository



More information about the samba-cvs mailing list