[SCM] Samba Shared Repository - branch v4-6-test updated

Karolin Seeger kseeger at samba.org
Mon Feb 20 13:45:04 UTC 2017


The branch, v4-6-test has been updated
       via  6bc0acf ctdb-scripts: Initialise CTDB_NFS_CALLOUT in statd-callout
       via  00723fa ctdb-tests: Add more comm tests
       via  1284283 ctdb-common: Fix use-after-free error in comm_fd_handler()
       via  dd79298 s3: torture: Regression test for smbd trying to open an invalid symlink.
       via  27c25fc s3: smbd: Don't loop infinitely on bad-symlink resolution.
       via  7c74e90 s3-vfs: Only walk the directory once in open_and_sort_dir()
       via  91c0bf9 s3/rpc_server/mdssvc: add attribute "kMDItemContentType"
       via  caf33c5 s3/smbd: check for invalid access_mask smbd_calculate_access_mask()
       via  964ecb1 selftest: also run test base.createx_access against ad_dc
       via  ca34320 WHATSNEW: vfs_fruit metadata xattr name on *BSD and mvxattr
       via  6b3f1be s3/util: mvxattr, a tool to rename extended attributes
       via  6745bf2 lib/replace: validate xattr namespace prefix on FreeBSD
       via  0e22dda vfs_fruit: fix resource fork xattr name
       via  1a79870 vfs_fruit: cleanup metadata and resource xattr name defines
       via  283cfd4 vfs_fruit: correct Netatalk metadata xattr on FreeBSD
       via  c28902d WHATSNEW: Fix obvious typo.
      from  0c2a848 WHATSNEW: Add link to known issues.

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-6-test


- Log -----------------------------------------------------------------
commit 6bc0acfb8dc73a3b096ddf83fda0b36a05b3d8ab
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Feb 14 09:04:41 2017 +1100

    ctdb-scripts: Initialise CTDB_NFS_CALLOUT in statd-callout
    
    Some configurations may set CTDB_NFS_CALLOUT to the empty string.
    They may do this if they allow a choice of NFS implementations.  In
    this case the default call-out for Linux kernel NFS should be used.
    However, statd-callout does not call nfs_callout_init() to set the
    default.  Therefore, statd-callout is unable to restart the lock
    manager, so the grace period is never entered.
    
    statd-callout must call nfs_callout_init() before trying to restart
    the lock manager.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12589
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    Autobuild-User(master): Martin Schwenke <martins at samba.org>
    Autobuild-Date(master): Thu Feb 16 09:21:03 CET 2017 on sn-devel-144
    
    (cherry picked from commit 5e7ae1b1e2fa8137aaa6a2a2f446156ae61f4c84)
    
    Autobuild-User(v4-6-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-6-test): Mon Feb 20 14:44:10 CET 2017 on sn-devel-144

commit 00723fa1213a354248b0cbbe0558739f261a572c
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Feb 7 15:18:02 2017 +1100

    ctdb-tests: Add more comm tests
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12580
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>
    (cherry picked from commit 024a2c20d2bcdbcc43d16d492c7cd2d09b93c8f0)

commit 128428390b06c0f859cdecd25d23f7ab7701f664
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Feb 6 15:54:55 2017 +1100

    ctdb-common: Fix use-after-free error in comm_fd_handler()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12580
    
    comm_write_send() creates a new tevent_req and adds it to the queue
    of requests to be processed.  If this tevent_req is freed, then the
    queue entry is not removed causing use-after-free error.
    
    If the tevent_req returned by comm_write_send() is freed, then that
    request should be removed from the queue and any pending actions based
    on that request should also be removed.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>
    (cherry picked from commit 9db7785fc6ffbaad434ee189c0f46c488358aab5)

commit dd792986e7da9fce7d2e123a4b9d6582c4692e1e
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Feb 14 12:59:58 2017 -0800

    s3: torture: Regression test for smbd trying to open an invalid symlink.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12572
    
    Pair-programmed-with: Ralph Boehme <slow at samba.org>
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Feb 16 22:06:51 CET 2017 on sn-devel-144
    
    (cherry picked from commit 40d813cdb312fd8378db310543e0778193a1a684)

commit 27c25fcaadd2357d48142c5b21767b723130aec6
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Feb 15 15:42:52 2017 -0800

    s3: smbd: Don't loop infinitely on bad-symlink resolution.
    
    In the FILE_OPEN_IF case we have O_CREAT, but not
    O_EXCL. Previously we went into a loop trying first
    ~(O_CREAT|O_EXCL), and if that returned ENOENT
    try (O_CREAT|O_EXCL). We kept looping indefinately
    until we got an error, or the file was created or
    opened.
    
    The big problem here is dangling symlinks. Opening
    without O_NOFOLLOW means both bad symlink
    and missing path return -1, ENOENT from open(). As POSIX
    is pathname based it's not possible to tell
    the difference between these two cases in a
    non-racy way, so change to try only two attempts before
    giving up.
    
    We don't have this problem for the O_NOFOLLOW
    case as we just return NT_STATUS_OBJECT_PATH_NOT_FOUND
    mapped from the ELOOP POSIX error and immediately
    returned.
    
    Unroll the loop logic to two tries instead.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12572
    
    Pair-programmed-with: Ralph Boehme <slow at samba.org>
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit 10c3e3923022485c720f322ca4f0aca5d7501310)

commit 7c74e90ac4eff6a59ef298c112d3c1cf7d50ba1a
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Feb 9 15:05:01 2017 +0100

    s3-vfs: Only walk the directory once in open_and_sort_dir()
    
    On a slow filesystem or network filesystem this can make a huge
    difference.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12571
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 6c3aaccd0eb648e31fd2717aaca0187966e125d5)

commit 91c0bf941747fc27380e299b6286db9a359a9be8
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Jan 31 16:09:55 2017 +0100

    s3/rpc_server/mdssvc: add attribute "kMDItemContentType"
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12545
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed Feb 15 06:20:52 CET 2017 on sn-devel-144
    
    (cherry picked from commit e08110ece699eeb1b9ef688c92bf84c69a6fa5fc)

commit caf33c5d24bef6913296761fcb2eb3d5e06f76a7
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 23 16:19:06 2017 +0100

    s3/smbd: check for invalid access_mask smbd_calculate_access_mask()
    
    This makes us pass "base.createx_access".
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12536
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 326765923f1d384e5cd8b7fda048b459c67a4bf5)

commit 964ecb12ed8e5296d6e496d9a14971850a2888fa
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 23 17:35:51 2017 +0100

    selftest: also run test base.createx_access against ad_dc
    
    Fails currently, will be made to work in the next commit.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12536
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit a3781d1cfe7d5e7df20fc65a9a7653937f03808c)

commit ca34320e1785eb08047d09a51eb40e8d1be0fad4
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Feb 15 12:53:22 2017 +0100

    WHATSNEW: vfs_fruit metadata xattr name on *BSD and mvxattr
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490

commit 6b3f1bed2858e9dd7c3213d25521c0d4a78eb8d5
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Feb 3 14:57:45 2017 +0100

    s3/util: mvxattr, a tool to rename extended attributes
    
    Usage: mvxattr -s STRING -d STRING PATH [PATH ...]
      -s, --from=STRING         xattr source name
      -d, --to=STRING           xattr destination name
      -l, --follow-symlinks     follow symlinks, the default is to ignore them
      -p, --print               print files where the xattr got renamed
      -v, --verbose             print files as they are checked
      -f, --force               force overwriting of destination xattr
    
    Help options:
      -?, --help            Show this help message
      --usage               Display brief usage message
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Fri Feb 10 22:24:59 CET 2017 on sn-devel-144
    
    (cherry picked from commit 32116e015b14cfa697569fce01daf8cde3285970)

commit 6745bf2715f1da0a6835cccb7022518f8dc04321
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Feb 3 18:08:12 2017 +0100

    lib/replace: validate xattr namespace prefix on FreeBSD
    
    We should validate the xattr name string ensuring it either begins with
    "sytem." or "user.". If it doesn't, we should fail the request with
    EINVAL.
    
    The FreeBSD xattr API uses namespaces but doesn't put the namespace name
    as a string prefix at the beginning of the xattr name. It gets passed as
    an additional int arg instead.
    
    On the other hand, our libreplace xattr API expects the caller to put a
    namespace prefix into the xattr name.
    
    Unfortunately the conversion and stripping of the namespace string prefix
    from the xattr name gives the following unexpected result on FreeBSD:
    
    rep_setxattr("foo.bar", ...) => xattr with name "bar"
    
    The code checks if the name begins with "system.", if it doesn't find
    it, it defaults to the user namespace and then does a strchr(name, '.')
    which skips *any* leading string before the first dot.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 738797d8ad6908de457786cc948dcde151e2b9e1)

commit 0e22dda471fe02ecd91fb9ed2c849eea27865e2e
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Feb 12 09:05:50 2017 +0100

    vfs_fruit: fix resource fork xattr name
    
    Fix resource fork xattr name broken in
    e4d1f8354f97ab9007e4c5f7d164937bdc5cd6f1.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Tue Feb 14 21:26:01 CET 2017 on sn-devel-144
    
    (cherry picked from commit 221faba006e84b05004500d2261307f269858a18)

commit 1a7987079f1ae9a5c52eefb65f3a7f626d3deac5
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Feb 3 16:43:26 2017 +0100

    vfs_fruit: cleanup metadata and resource xattr name defines
    
    Just some cleanup, no change in behaviour. This also removes the hokey
    tag. :)
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit e4d1f8354f97ab9007e4c5f7d164937bdc5cd6f1)

commit 283cfd41d60f02e865722d62f20016d2c56981ed
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Feb 3 16:33:00 2017 +0100

    vfs_fruit: correct Netatalk metadata xattr on FreeBSD
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=12490
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 73557605fdf72221e3cbc218fc9782d163029a08)

commit c28902d7e268b79d44733d63e226df5ae5caae7f
Author: Karolin Seeger <kseeger at samba.org>
Date:   Fri Feb 17 08:51:25 2017 +0100

    WHATSNEW: Fix obvious typo.
    
    Thanks to bj at sernet.de for reporting!
    
    Signed-off-by: Karolin Seeger <kseeger at samba.org>

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

Summary of changes:
 WHATSNEW.txt                               |  41 +++-
 ctdb/common/comm.c                         |  46 ++++-
 ctdb/config/statd-callout                  |   1 +
 ctdb/tests/cunit/comm_test_001.sh          |  10 +-
 ctdb/tests/src/comm_test.c                 | 309 +++++++++++++++++++++++++----
 docs-xml/manpages/mvxattr.1.xml            | 100 ++++++++++
 docs-xml/wscript_build                     |   1 +
 lib/replace/xattr.c                        | 105 +++++++---
 selftest/skip                              |   1 +
 source3/modules/vfs_dirsort.c              |  63 +++---
 source3/modules/vfs_fruit.c                |  12 +-
 source3/rpc_server/mdssvc/sparql_mapping.c |   5 +
 source3/selftest/tests.py                  |   6 +-
 source3/smbd/open.c                        | 110 +++++-----
 source3/torture/torture.c                  | 101 ++++++++++
 source3/utils/mvxattr.c                    | 178 +++++++++++++++++
 source3/utils/wscript_build                |   8 +
 source3/wscript                            |   3 +
 18 files changed, 951 insertions(+), 149 deletions(-)
 create mode 100644 docs-xml/manpages/mvxattr.1.xml
 create mode 100644 source3/utils/mvxattr.c


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index d380a86..1063972 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -44,6 +44,26 @@ configured as the default backend.
 To avoid problems in future we advise all users to run 'testparm' after
 changing the smb.conf file!
 
+vfs_fruit Netatalk metadata xattr name on *BSD
+----------------------------------------------
+
+Users on *BSD must rename the metadata xattr used by vfs_fruit when
+using the default setting "fruit:metadata = netatalk".
+
+Due to a glitch in the Samba xattr API compatibility layer for FreeBSD and a
+mistake in vfs_fruit, vfs_fruit ended up using the wrong xattr name when
+configured with "fruit:metadata = netatalk" (default). Instead of the correct
+
+  org.netatalk.Metadata
+
+it used
+
+  netatalk.Metadata
+
+Starting with Samba 4.6 vfs_fruit will use the correct "org.netatalk.Metadata"
+which means existing installations must rename this xattrs. For this purpose
+Samba now includes a new tool `mvxattr`. See below for further details.
+
 
 NEW FEATURES/CHANGES
 ====================
@@ -221,6 +241,23 @@ to retrieve the home directory and login shell from the "Unix
 Attributes" of the user. This supersedes the "winbind nss info"
 parameter with a per-domain configuration option.
 
+mvxattr
+-------
+
+mvxattr is a simple utility to recursively rename extended attributes of all
+files and directories in a directory tree.
+
+  Usage: mvxattr -s STRING -d STRING PATH [PATH ...]
+    -s, --from=STRING         xattr source name
+    -d, --to=STRING           xattr destination name
+    -l, --follow-symlinks     follow symlinks, the default is to ignore them
+    -p, --print               print files where the xattr got renamed
+    -v, --verbose             print files as they are checked
+    -f, --force               force overwriting of destination xattr
+
+  Help options:
+    -?, --help                Show this help message
+    --usage                   Display brief usage message
 
 smb.conf changes
 ================
@@ -240,7 +277,7 @@ KNOWN ISSUES
 https://wiki.samba.org/index.php/Release_Planning_for_Samba_4.6#Release_blocking_bugs
 
 
-CHANGES SINCE 4.5.0rc2
+CHANGES SINCE 4.6.0rc2
 ======================
 
 o  Jeremy Allison <jra at samba.org>
@@ -292,7 +329,7 @@ o  Uri Simchoni <uri at samba.org>
    * BUG 12529: waf: Backport finding of pkg-config.
 
 
-CHANGES SINCE 4.5.0rc1
+CHANGES SINCE 4.6.0rc1
 ======================
 
 o  Amitay Isaacs <amitay at gmail.com>
diff --git a/ctdb/common/comm.c b/ctdb/common/comm.c
index 7f370da..12f4970 100644
--- a/ctdb/common/comm.c
+++ b/ctdb/common/comm.c
@@ -251,14 +251,22 @@ static void comm_read_failed(struct tevent_req *req)
  * Write packets
  */
 
+struct comm_write_entry {
+	struct comm_context *comm;
+	struct tevent_queue_entry *qentry;
+	struct tevent_req *req;
+};
+
 struct comm_write_state {
 	struct tevent_context *ev;
 	struct comm_context *comm;
+	struct comm_write_entry *entry;
 	struct tevent_req *subreq;
 	uint8_t *buf;
 	size_t buflen, nwritten;
 };
 
+static int comm_write_entry_destructor(struct comm_write_entry *entry);
 static void comm_write_trigger(struct tevent_req *req, void *private_data);
 static void comm_write_done(struct tevent_req *subreq);
 
@@ -269,6 +277,7 @@ struct tevent_req *comm_write_send(TALLOC_CTX *mem_ctx,
 {
 	struct tevent_req *req;
 	struct comm_write_state *state;
+	struct comm_write_entry *entry;
 
 	req = tevent_req_create(mem_ctx, &state, struct comm_write_state);
 	if (req == NULL) {
@@ -280,15 +289,38 @@ struct tevent_req *comm_write_send(TALLOC_CTX *mem_ctx,
 	state->buf = buf;
 	state->buflen = buflen;
 
-	if (!tevent_queue_add_entry(comm->queue, ev, req,
-				    comm_write_trigger, NULL)) {
-		talloc_free(req);
-		return NULL;
+	entry = talloc_zero(state, struct comm_write_entry);
+	if (tevent_req_nomem(entry, req)) {
+		return tevent_req_post(req, ev);
 	}
 
+	entry->comm = comm;
+	entry->req = req;
+	entry->qentry = tevent_queue_add_entry(comm->queue, ev, req,
+					       comm_write_trigger, NULL);
+	if (tevent_req_nomem(entry->qentry, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	state->entry = entry;
+	talloc_set_destructor(entry, comm_write_entry_destructor);
+
 	return req;
 }
 
+static int comm_write_entry_destructor(struct comm_write_entry *entry)
+{
+	struct comm_context *comm = entry->comm;
+
+	if (comm->write_req == entry->req) {
+		comm->write_req = NULL;
+		TEVENT_FD_NOT_WRITEABLE(comm->fde);
+	}
+
+	TALLOC_FREE(entry->qentry);
+	return 0;
+}
+
 static void comm_write_trigger(struct tevent_req *req, void *private_data)
 {
 	struct comm_write_state *state = tevent_req_data(
@@ -333,6 +365,8 @@ static void comm_write_done(struct tevent_req *subreq)
 	}
 
 	state->nwritten = nwritten;
+	state->entry->qentry = NULL;
+	TALLOC_FREE(state->entry);
 	tevent_req_done(req);
 }
 
@@ -382,8 +416,8 @@ static void comm_fd_handler(struct tevent_context *ev,
 		struct comm_write_state *write_state;
 
 		if (comm->write_req == NULL) {
-			/* This should never happen */
-			abort();
+			TEVENT_FD_NOT_WRITEABLE(comm->fde);
+			return;
 		}
 
 		write_state = tevent_req_data(comm->write_req,
diff --git a/ctdb/config/statd-callout b/ctdb/config/statd-callout
index 3f2dd39..38f847b 100755
--- a/ctdb/config/statd-callout
+++ b/ctdb/config/statd-callout
@@ -128,6 +128,7 @@ case "$1" in
 	# where the lock manager will respond "strangely" immediately
 	# after restarting it, which causes clients to fail to reclaim
 	# their locks.
+	nfs_callout_init
 	"$CTDB_NFS_CALLOUT" "stop" "nlockmgr" >/dev/null 2>&1
         sleep 2
 	"$CTDB_NFS_CALLOUT" "start" "nlockmgr" >/dev/null 2>&1
diff --git a/ctdb/tests/cunit/comm_test_001.sh b/ctdb/tests/cunit/comm_test_001.sh
index 5d20db2..ac09f5c 100755
--- a/ctdb/tests/cunit/comm_test_001.sh
+++ b/ctdb/tests/cunit/comm_test_001.sh
@@ -2,6 +2,12 @@
 
 . "${TEST_SCRIPTS_DIR}/unit.sh"
 
-ok "100 2048 500 4096 1024 8192 200 16384 300 32768 400 65536 1048576 "
 
-unit_test comm_test
+ok_null
+unit_test comm_test 1
+
+ok_null
+unit_test comm_test 2
+
+ok "100 2048 500 4096 1024 8192 200 16384 300 32768 400 65536 1048576 "
+unit_test comm_test 3
diff --git a/ctdb/tests/src/comm_test.c b/ctdb/tests/src/comm_test.c
index 2189435..5e1d694 100644
--- a/ctdb/tests/src/comm_test.c
+++ b/ctdb/tests/src/comm_test.c
@@ -26,7 +26,218 @@
 #include "common/pkt_write.c"
 #include "common/comm.c"
 
-static void dead_handler(void *private_data)
+/*
+ * Test read_handler and dead_handler
+ */
+
+static void test1_read_handler(uint8_t *buf, size_t buflen,
+			       void *private_data)
+{
+	int *result = (int *)private_data;
+
+	*result = -1;
+}
+
+static void test1_dead_handler(void *private_data)
+{
+	int *result = (int *)private_data;
+
+	*result = 1;
+}
+
+static void test1(void)
+{
+	TALLOC_CTX *mem_ctx;
+	struct tevent_context *ev;
+	struct comm_context *comm;
+	int fd[2];
+	int result = 0;
+	uint32_t data[2];
+	int ret;
+	ssize_t n;
+
+	mem_ctx = talloc_new(NULL);
+	assert(mem_ctx != NULL);
+
+	ev = tevent_context_init(mem_ctx);
+	assert(ev != NULL);
+
+	ret = pipe(fd);
+	assert(ret == 0);
+
+	ret = comm_setup(ev, ev, fd[0], test1_read_handler, &result,
+			 test1_dead_handler, &result, &comm);
+	assert(ret == 0);
+
+	data[0] = 2 * sizeof(uint32_t);
+	data[1] = 0;
+
+	n = write(fd[1], (void *)&data, data[0]);
+	assert(n == data[0]);
+
+	while (result == 0) {
+		tevent_loop_once(ev);
+	}
+
+	assert(result == -1);
+
+	result = 0;
+	close(fd[1]);
+
+	while (result == 0) {
+		tevent_loop_once(ev);
+	}
+
+	assert(result == 1);
+
+	talloc_free(mem_ctx);
+}
+
+/*
+ * Test that the tevent_req returned by comm_write_send() can be free'd.
+ */
+
+struct test2_state {
+	TALLOC_CTX *mem_ctx;
+	bool done;
+};
+
+static void test2_read_handler(uint8_t *buf, size_t buflen,
+			       void *private_data)
+{
+	struct test2_state *state = (struct test2_state *)private_data;
+
+	TALLOC_FREE(state->mem_ctx);
+}
+
+static void test2_dead_handler(void *private_data)
+{
+	abort();
+}
+
+struct test2_write_state {
+	int count;
+};
+
+static void test2_write_done(struct tevent_req *subreq);
+
+static struct tevent_req *test2_write_send(TALLOC_CTX *mem_ctx,
+					   struct tevent_context *ev,
+					   struct comm_context *comm,
+					   uint8_t *buf, size_t buflen)
+{
+	struct tevent_req *req, *subreq;
+	struct test2_write_state *state;
+	int i;
+
+	req = tevent_req_create(mem_ctx, &state, struct test2_write_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	state->count = 0;
+
+	for (i=0; i<10; i++) {
+		subreq = comm_write_send(state, ev, comm, buf, buflen);
+		if (tevent_req_nomem(subreq, req)) {
+			return tevent_req_post(req, ev);
+		}
+		tevent_req_set_callback(subreq, test2_write_done, req);
+	}
+
+	return req;
+}
+
+static void test2_write_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct test2_write_state *state = tevent_req_data(
+		req, struct test2_write_state);
+	bool status;
+	int ret;
+
+	status = comm_write_recv(subreq, &ret);
+	TALLOC_FREE(subreq);
+	if (! status) {
+		tevent_req_error(req, ret);
+		return;
+	}
+
+	state->count += 1;
+
+	if (state->count == 10) {
+		tevent_req_done(req);
+	}
+}
+
+static void test2_timer_handler(struct tevent_context *ev,
+				struct tevent_timer *te,
+				struct timeval cur_time,
+				void *private_data)
+{
+	struct test2_state *state = (struct test2_state *)private_data;
+
+	state->done = true;
+}
+
+static void test2(void)
+{
+	TALLOC_CTX *mem_ctx;
+	struct tevent_context *ev;
+	struct comm_context *comm_reader, *comm_writer;
+	struct test2_state test2_state;
+	struct tevent_req *req;
+	struct tevent_timer *te;
+	int fd[2];
+	uint32_t data[2];
+	int ret;
+
+	mem_ctx = talloc_new(NULL);
+	assert(mem_ctx != NULL);
+
+	test2_state.mem_ctx = talloc_new(mem_ctx);
+	assert(test2_state.mem_ctx != NULL);
+
+	test2_state.done = false;
+
+	ev = tevent_context_init(mem_ctx);
+	assert(ev != NULL);
+
+	ret = pipe(fd);
+	assert(ret == 0);
+
+	ret = comm_setup(ev, ev, fd[0], test2_read_handler, &test2_state,
+			 test2_dead_handler, NULL, &comm_reader);
+	assert(ret == 0);
+
+	ret = comm_setup(ev, ev, fd[1], NULL, NULL, test2_dead_handler, NULL,
+			 &comm_writer);
+	assert(ret == 0);
+
+	data[0] = 2 * sizeof(uint32_t);
+	data[1] = 0;
+
+	req = test2_write_send(test2_state.mem_ctx, ev, comm_writer,
+			       (uint8_t *)data, data[0]);
+	assert(req != NULL);
+
+	te = tevent_add_timer(ev, ev, tevent_timeval_current_ofs(5,0),
+			      test2_timer_handler, &test2_state);
+	assert(te != NULL);
+
+	while (! test2_state.done) {
+		tevent_loop_once(ev);
+	}
+
+	talloc_free(mem_ctx);
+}
+
+/*
+ * Test that data is written and read correctly.
+ */
+
+static void test3_dead_handler(void *private_data)
 {
 	int dead_data = *(int *)private_data;
 
@@ -34,14 +245,14 @@ static void dead_handler(void *private_data)
 
 	if (dead_data == 1) {
 		/* reader */
-		printf("writer closed pipe\n");
+		fprintf(stderr, "writer closed pipe\n");
 	} else {
 		/* writer */
-		printf("reader closed pipe\n");
+		fprintf(stderr, "reader closed pipe\n");
 	}
 }
 
-struct writer_state {
+struct test3_writer_state {
 	struct tevent_context *ev;
 	struct comm_context *comm;
 	uint8_t *buf;
@@ -49,15 +260,15 @@ struct writer_state {
 	int count, id;
 };
 
-static void writer_next(struct tevent_req *subreq);
+static void test3_writer_next(struct tevent_req *subreq);
 
-static struct tevent_req *writer_send(TALLOC_CTX *mem_ctx,
-				      struct tevent_context *ev,
-				      struct comm_context *comm,
-				      size_t *pkt_size, int count)
+static struct tevent_req *test3_writer_send(TALLOC_CTX *mem_ctx,
+					    struct tevent_context *ev,
+					    struct comm_context *comm,
+					    size_t *pkt_size, int count)
 {
 	struct tevent_req *req, *subreq;
-	struct writer_state *state;
+	struct test3_writer_state *state;
 	size_t max_size = 0, buflen;
 	int i;
 
@@ -67,7 +278,7 @@ static struct tevent_req *writer_send(TALLOC_CTX *mem_ctx,
 		}
 	}
 
-	req = tevent_req_create(mem_ctx, &state, struct writer_state);
+	req = tevent_req_create(mem_ctx, &state, struct test3_writer_state);
 	if (req == NULL) {
 		return NULL;
 	}
@@ -95,16 +306,16 @@ static struct tevent_req *writer_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
-	tevent_req_set_callback(subreq, writer_next, req);
+	tevent_req_set_callback(subreq, test3_writer_next, req);
 	return req;
 }
 
-static void writer_next(struct tevent_req *subreq)
+static void test3_writer_next(struct tevent_req *subreq)
 {
 	struct tevent_req *req = tevent_req_callback_data(
 		subreq, struct tevent_req);
-	struct writer_state *state = tevent_req_data(
-		req, struct writer_state);
+	struct test3_writer_state *state = tevent_req_data(
+		req, struct test3_writer_state);
 	bool ret;
 	int err;
 	size_t buflen;
@@ -130,10 +341,10 @@ static void writer_next(struct tevent_req *subreq)
 		return;
 	}
 


-- 
Samba Shared Repository



More information about the samba-cvs mailing list