[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Fri Aug 22 18:49:04 MDT 2014
The branch, master has been updated
via 6174bfa Don't discard result of checking grouptype
via 20ef305 messaging3: Avoid messaging_is_self_send
via 46e9122 lib: Introduce server_id_same_process()
via 1c4284c pthreadpool: Slightly serialize jobs
via 4288c54 messaging3: Add msg_sink/source -- perftest
via ff9a083 selftest/Samba4: avoid warnings about 'path' not specified on 'ntvfs handler = cifs' shares
via 0ddfdb8 torture: Fix cleanup2 to utilize on-demand cleanup
via 513584a torture: Run the cleanup2 test against 2 nodes
via 8593509 brlock: Remove validate_lock_entries
via 1057240 brlock: Do auto-cleanup at conflict time
from 815bde2 s3: smbd: POSIX ACLs. Remove incorrect check for SECINFO_PROTECTED_DACL in incoming security_information flags in posix_get_nt_acl_common().
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 6174bfafe7c8d3e424869c08077ae1deb002de03
Author: Roel van Meer <roel at 1afa.com>
Date: Fri Aug 22 15:11:04 2014 +0200
Don't discard result of checking grouptype
The pdb_samba_dsdb_getgrfilter() function first determines the security type
of a group and sets map->sid_name_use accordingly. A little later, this
variable is set again, undoing the previous work.
https://bugzilla.samba.org/show_bug.cgi?id=10777
Reviewed-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Simo Sorce <idra at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Sat Aug 23 02:48:52 CEST 2014 on sn-devel-104
commit 20ef305cfa8af5437ded8bd093e4f9c487ee82a7
Author: Volker Lendecke <vl at samba.org>
Date: Thu Aug 21 18:41:49 2014 +0000
messaging3: Avoid messaging_is_self_send
This was a bad API, and it was used in a buggy way: In
messaging_dispatch_rec we always did the defer, we referenced the
destination pid, not the source. In messaging_send_iov this is the right
thing to do to reference the destination, but when we have arrived in
messaging_dispatch_rec we should compare source and destination.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 46e912210d62baf895c3e526be5109724475b536
Author: Volker Lendecke <vl at samba.org>
Date: Thu Aug 21 18:36:33 2014 +0000
lib: Introduce server_id_same_process()
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 1c4284c7395f23cefa61a407db74cf5067aee2aa
Author: Volker Lendecke <vl at samba.org>
Date: Thu Aug 21 19:55:06 2014 +0000
pthreadpool: Slightly serialize jobs
Using the new msg_source program with 1.500 instances against a single
msg_sink I found the msg_source process to spawn two worker threads for
synchronously sending the data towards the receiving socket. This should
not happen: Per destination node we only create one queue. We strictly
only add pthreadpool jobs one after the other, so a single helper thread
should be perfectly sufficient.
It turned out that under heavy overload the main sending thread was
scheduled before the thread that just had finished its send() job. So
the helper thread was not able to increment the pool->num_idle variable
indicating that we don't have to create a new thread when the new job
is added.
This patch moves the signalling write under the mutex. This means that
indicating readiness via the pipe and the pool->num_idle variable happen both
under the same mutex lock and thus are atomic. No superfluous threads anymore.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 4288c5496bcfa530066d5e8e4927472715b71465
Author: Volker Lendecke <vl at samba.org>
Date: Thu Aug 21 14:32:07 2014 +0000
messaging3: Add msg_sink/source -- perftest
With this pair of programs I did some performance tests of the messaging
system. Guess what -- I found two bugs :-)
See the subsequent patches.
With 1500 msg_source processes I can generate message overload: A
Intel(R) Xeon(R) CPU L5640 @ 2.27GHz
can receive roughly 100k messages per second. When using
messaging_read_send/recv user/system time is roughly even, a bit more
work done in user space. When using messaging_register, due to less
malloc activity, user space chews a lot less.
By the way: 1.500 helper threads in a blocking sendto() against a single
datagram socket reading as fast as it can (with epoll_wait in between)
only drove the loadavg to 12 on a 24-core machine. So I guess unix domain
datagram sockets are pretty well protected against overload. No thundering
herd or so. Interestingly "top" showed msg_sink at less than 90% CPU,
although it was clearly the bottleneck. But that must be a "top" artifact.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit ff9a083363b3749e0f9e346ea31e95c5e35e94ff
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 6 16:54:43 2014 +0200
selftest/Samba4: avoid warnings about 'path' not specified on 'ntvfs handler = cifs' shares
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 0ddfdb83e8a5aacc16994e2a380101723035c576
Author: Volker Lendecke <vl at samba.org>
Date: Wed Aug 20 09:53:28 2014 +0000
torture: Fix cleanup2 to utilize on-demand cleanup
Now we check the cleanup when conflicts happen, not when we first open
the file. This means we don't have to re-open the connection to make
cleanup happen.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 513584a3b1f7d46801d43da990594b1dca85ec11
Author: Volker Lendecke <vl at samba.org>
Date: Wed Aug 20 09:52:39 2014 +0000
torture: Run the cleanup2 test against 2 nodes
This enables testing the brlock cleanup across ctdb
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 85935097b9dd877791ed7447fe4314c6736c0414
Author: Volker Lendecke <vl at samba.org>
Date: Wed Aug 20 09:07:14 2014 +0000
brlock: Remove validate_lock_entries
This is now only called during brl_forall. It does not really hurt if we list
dead processes here. If the upper layers really care, they can filter it out
themselves. The real lock conflicts are not removed on-demand.
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 105724073300af03eb0835b3c93d9b2e2bfacb07
Author: Volker Lendecke <vl at samba.org>
Date: Tue Aug 19 12:36:55 2014 +0000
brlock: Do auto-cleanup at conflict time
This avoids the need to do sweeping validate_lock_entries calls
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
lib/util/samba_util.h | 2 +
lib/util/server_id.c | 12 +-
selftest/target/Samba4.pm | 2 +
source3/include/vfs.h | 1 -
source3/lib/messages.c | 15 +-
source3/lib/pthreadpool/pthreadpool.c | 2 +-
source3/locking/brlock.c | 187 ++++++----------------
source3/locking/locking.c | 10 ++
source3/locking/proto.h | 2 +-
source3/passdb/pdb_samba_dsdb.c | 2 -
source3/torture/msg_sink.c | 284 +++++++++++++++++++++++++++++++++
source3/torture/msg_source.c | 157 ++++++++++++++++++
source3/torture/test_cleanup.c | 21 +--
source3/wscript_build | 14 ++
14 files changed, 535 insertions(+), 176 deletions(-)
create mode 100644 source3/torture/msg_sink.c
create mode 100644 source3/torture/msg_source.c
Changeset truncated at 500 lines:
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index 233b5fd..f1f4c2d 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -985,6 +985,8 @@ struct server_id;
struct server_id_buf { char buf[48]; }; /* probably a bit too large ... */
char *server_id_str_buf(struct server_id id, struct server_id_buf *dst);
+bool server_id_same_process(const struct server_id *p1,
+ const struct server_id *p2);
bool server_id_equal(const struct server_id *p1, const struct server_id *p2);
char *server_id_str(TALLOC_CTX *mem_ctx, const struct server_id *id);
struct server_id server_id_from_string(uint32_t local_vnn,
diff --git a/lib/util/server_id.c b/lib/util/server_id.c
index e0a05a7..7d3de2f 100644
--- a/lib/util/server_id.c
+++ b/lib/util/server_id.c
@@ -20,9 +20,15 @@
#include "includes.h"
#include "librpc/gen_ndr/server_id.h"
+bool server_id_same_process(const struct server_id *p1,
+ const struct server_id *p2)
+{
+ return ((p1->pid == p2->pid) && (p1->vnn == p2->vnn));
+}
+
bool server_id_equal(const struct server_id *p1, const struct server_id *p2)
{
- if (p1->pid != p2->pid) {
+ if (!server_id_same_process(p1, p2)) {
return false;
}
@@ -30,10 +36,6 @@ bool server_id_equal(const struct server_id *p1, const struct server_id *p2)
return false;
}
- if (p1->vnn != p2->vnn) {
- return false;
- }
-
if (p1->unique_id != p2->unique_id) {
return false;
}
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index ec0f439..ffaf2be 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -853,6 +853,7 @@ sub provision($$$$$$$$$)
posix:writetimeupdatedelay = 50000
[cifs]
+ path = $ctx->{share}/_ignore_cifs_
read only = no
ntvfs handler = cifs
cifs:server = $ctx->{netbiosname}
@@ -999,6 +1000,7 @@ sub provision_rpc_proxy($$$)
dcerpc_remote:interfaces = rpcecho
[cifs_to_dc]
+ path = /tmp/_ignore_cifs_to_dc_/_none_
read only = no
ntvfs handler = cifs
cifs:server = $dcvars->{SERVER}
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index a81fb6c..3702b75 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -236,7 +236,6 @@ typedef struct files_struct {
bool modified;
bool is_directory;
bool aio_write_behind;
- bool lockdb_clean;
bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */
bool delete_on_close;
bool posix_open;
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 25d3f01..80ecec4 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -403,13 +403,6 @@ void messaging_deregister(struct messaging_context *ctx, uint32_t msg_type,
}
}
-static bool messaging_is_self_send(const struct messaging_context *msg_ctx,
- const struct server_id *dst)
-{
- return ((msg_ctx->id.vnn == dst->vnn) &&
- (msg_ctx->id.pid == dst->pid));
-}
-
/*
Send a message to a particular server
*/
@@ -455,10 +448,14 @@ NTSTATUS messaging_send_iov(struct messaging_context *msg_ctx,
return NT_STATUS_OK;
}
- if (messaging_is_self_send(msg_ctx, &server)) {
+ if (server_id_same_process(&msg_ctx->id, &server)) {
struct messaging_rec rec;
uint8_t *buf;
+ /*
+ * Self-send, directly dispatch
+ */
+
buf = iov_buf(talloc_tos(), iov, iovlen);
if (buf == NULL) {
return NT_STATUS_NO_MEMORY;
@@ -827,7 +824,7 @@ void messaging_dispatch_rec(struct messaging_context *msg_ctx,
continue;
}
- if (messaging_is_self_send(msg_ctx, &rec->dest)) {
+ if (server_id_same_process(&rec->src, &rec->dest)) {
/*
* This is a self-send. We are called here from
* messaging_send(), and we don't want to directly
diff --git a/source3/lib/pthreadpool/pthreadpool.c b/source3/lib/pthreadpool/pthreadpool.c
index 4436ab3..d683578 100644
--- a/source3/lib/pthreadpool/pthreadpool.c
+++ b/source3/lib/pthreadpool/pthreadpool.c
@@ -536,11 +536,11 @@ static void *pthreadpool_server(void *arg)
assert(res == 0);
job.fn(job.private_data);
- written = write(sig_pipe, &job.id, sizeof(job.id));
res = pthread_mutex_lock(&pool->mutex);
assert(res == 0);
+ written = write(sig_pipe, &job.id, sizeof(job.id));
if (written != sizeof(int)) {
pthreadpool_server_exit(pool);
pthread_mutex_unlock(&pool->mutex);
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index 84849e6..295e147 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -418,6 +418,11 @@ NTSTATUS brl_lock_windows_default(struct byte_range_lock *br_lck,
for (i=0; i < br_lck->num_locks; i++) {
/* Do any Windows or POSIX locks conflict ? */
if (brl_conflict(&locks[i], plock)) {
+ if (!serverid_exists(&locks[i].context.pid)) {
+ locks[i].context.pid.pid = 0;
+ br_lck->modified = true;
+ continue;
+ }
/* Remember who blocked us. */
plock->context.smblctx = locks[i].context.smblctx;
return brl_lock_failed(fsp,plock,blocking_lock);
@@ -822,6 +827,11 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
if (curr_lock->lock_flav == WINDOWS_LOCK) {
/* Do any Windows flavour locks conflict ? */
if (brl_conflict(curr_lock, plock)) {
+ if (!serverid_exists(&curr_lock->context.pid)) {
+ curr_lock->context.pid.pid = 0;
+ br_lck->modified = true;
+ continue;
+ }
/* No games with error messages. */
TALLOC_FREE(tp);
/* Remember who blocked us. */
@@ -836,6 +846,11 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
/* POSIX conflict semantics are different. */
if (brl_conflict_posix(curr_lock, plock)) {
+ if (!serverid_exists(&curr_lock->context.pid)) {
+ curr_lock->context.pid.pid = 0;
+ br_lck->modified = true;
+ continue;
+ }
/* Can't block ourselves with POSIX locks. */
/* No games with error messages. */
TALLOC_FREE(tp);
@@ -1345,12 +1360,12 @@ bool brl_unlock(struct messaging_context *msg_ctx,
Returns True if the region required is currently unlocked, False if locked.
****************************************************************************/
-bool brl_locktest(const struct byte_range_lock *br_lck,
+bool brl_locktest(struct byte_range_lock *br_lck,
const struct lock_struct *rw_probe)
{
bool ret = True;
unsigned int i;
- const struct lock_struct *locks = br_lck->lock_data;
+ struct lock_struct *locks = br_lck->lock_data;
files_struct *fsp = br_lck->fsp;
/* Make sure existing locks don't conflict */
@@ -1359,6 +1374,17 @@ bool brl_locktest(const struct byte_range_lock *br_lck,
* Our own locks don't conflict.
*/
if (brl_conflict_other(&locks[i], rw_probe)) {
+ if (br_lck->record == NULL) {
+ /* readonly */
+ return false;
+ }
+
+ if (!serverid_exists(&locks[i].context.pid)) {
+ locks[i].context.pid.pid = 0;
+ br_lck->modified = true;
+ continue;
+ }
+
return False;
}
}
@@ -1673,7 +1699,6 @@ bool brl_reconnect_disconnected(struct files_struct *fsp)
* and thereby remove our own (disconnected) entries but reactivate
* them instead.
*/
- fsp->lockdb_clean = true;
br_lck = brl_get_locks(talloc_tos(), fsp);
if (br_lck == NULL) {
@@ -1724,80 +1749,6 @@ bool brl_reconnect_disconnected(struct files_struct *fsp)
return true;
}
-/****************************************************************************
- Ensure this set of lock entries is valid.
-****************************************************************************/
-static bool validate_lock_entries(unsigned int *pnum_entries, struct lock_struct **pplocks,
- bool keep_disconnected)
-{
- unsigned int i;
- struct lock_struct *locks = *pplocks;
- unsigned int num_entries = *pnum_entries;
- TALLOC_CTX *frame;
- struct server_id *ids;
- bool *exists;
-
- if (num_entries == 0) {
- return true;
- }
-
- frame = talloc_stackframe();
-
- ids = talloc_array(frame, struct server_id, num_entries);
- if (ids == NULL) {
- DEBUG(0, ("validate_lock_entries: "
- "talloc_array(struct server_id, %u) failed\n",
- num_entries));
- talloc_free(frame);
- return false;
- }
-
- exists = talloc_array(frame, bool, num_entries);
- if (exists == NULL) {
- DEBUG(0, ("validate_lock_entries: "
- "talloc_array(bool, %u) failed\n",
- num_entries));
- talloc_free(frame);
- return false;
- }
-
- for (i = 0; i < num_entries; i++) {
- ids[i] = locks[i].context.pid;
- }
-
- if (!serverids_exist(ids, num_entries, exists)) {
- DEBUG(3, ("validate_lock_entries: serverids_exists failed\n"));
- talloc_free(frame);
- return false;
- }
-
- i = 0;
-
- while (i < num_entries) {
- if (exists[i]) {
- i++;
- continue;
- }
-
- if (keep_disconnected &&
- server_id_is_disconnected(&ids[i]))
- {
- i++;
- continue;
- }
-
- /* This process no longer exists */
-
- brl_delete_lock_struct(locks, num_entries, i);
- num_entries -= 1;
- }
- TALLOC_FREE(frame);
-
- *pnum_entries = num_entries;
-
- return True;
-}
-
struct brl_forall_cb {
void (*fn)(struct file_id id, struct server_id pid,
enum brl_type lock_type,
@@ -1819,7 +1770,6 @@ static int brl_traverse_fn(struct db_record *rec, void *state)
struct file_id *key;
unsigned int i;
unsigned int num_locks = 0;
- unsigned int orig_num_locks = 0;
TDB_DATA dbkey;
TDB_DATA value;
@@ -1836,25 +1786,7 @@ static int brl_traverse_fn(struct db_record *rec, void *state)
}
key = (struct file_id *)dbkey.dptr;
- orig_num_locks = num_locks = value.dsize/sizeof(*locks);
-
- /* Ensure the lock db is clean of entries from invalid processes. */
-
- if (!validate_lock_entries(&num_locks, &locks, true)) {
- TALLOC_FREE(locks);
- return -1; /* Terminate traversal */
- }
-
- if (orig_num_locks != num_locks) {
- if (num_locks) {
- TDB_DATA data;
- data.dptr = (uint8_t *)locks;
- data.dsize = num_locks*sizeof(struct lock_struct);
- dbwrap_record_store(rec, data, TDB_REPLACE);
- } else {
- dbwrap_record_delete(rec);
- }
- }
+ num_locks = value.dsize/sizeof(*locks);
if (cb->fn) {
for ( i=0; i<num_locks; i++) {
@@ -1910,11 +1842,29 @@ int brl_forall(void (*fn)(struct file_id id, struct server_id pid,
static void byte_range_lock_flush(struct byte_range_lock *br_lck)
{
size_t data_len;
+ unsigned i;
+ struct lock_struct *locks = br_lck->lock_data;
+
if (!br_lck->modified) {
DEBUG(10, ("br_lck not modified\n"));
goto done;
}
+ i = 0;
+
+ while (i < br_lck->num_locks) {
+ if (locks[i].context.pid.pid == 0) {
+ /*
+ * Autocleanup, the process conflicted and does not
+ * exist anymore.
+ */
+ locks[i] = locks[br_lck->num_locks-1];
+ br_lck->num_locks -= 1;
+ } else {
+ i += 1;
+ }
+ }
+
data_len = br_lck->num_locks * sizeof(struct lock_struct);
if (br_lck->have_read_oplocks) {
@@ -2025,37 +1975,6 @@ struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, files_struct *fsp)
br_lck->have_read_oplocks = (data.dptr[data.dsize-1] == 1);
}
- if (!fsp->lockdb_clean) {
- int orig_num_locks = br_lck->num_locks;
-
- /*
- * This is the first time we access the byte range lock
- * record with this fsp. Go through and ensure all entries
- * are valid - remove any that don't.
- * This makes the lockdb self cleaning at low cost.
- *
- * Note: Disconnected entries belong to disconnected
- * durable handles. So at this point, we have a new
- * handle on the file and the disconnected durable has
- * already been closed (we are not a durable reconnect).
- * So we need to clean the disconnected brl entry.
- */
-
- if (!validate_lock_entries(&br_lck->num_locks,
- &br_lck->lock_data, false)) {
- TALLOC_FREE(br_lck);
- return NULL;
- }
-
- /* Ensure invalid locks are cleaned up in the destructor. */
- if (orig_num_locks != br_lck->num_locks) {
- br_lck->modified = True;
- }
-
- /* Mark the lockdb as "clean" as seen from this open file. */
- fsp->lockdb_clean = True;
- }
-
if (DEBUGLEVEL >= 10) {
unsigned int i;
struct lock_struct *locks = br_lck->lock_data;
@@ -2121,18 +2040,6 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp)
return fsp->brlock_rec;
}
- if (!fsp->lockdb_clean) {
- /*
- * Fetch the record in R/W mode to give validate_lock_entries
- * a chance to kick in once.
- */
- rw = brl_get_locks(talloc_tos(), fsp);
- if (rw == NULL) {
- return NULL;
- }
- fsp->lockdb_clean = true;
- }
-
if (rw != NULL) {
size_t lock_data_size;
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 0a99449..a320068 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -137,6 +137,16 @@ bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
}
ret = brl_locktest(br_lck, plock);
+ if (!ret) {
+ /*
+ * We got a lock conflict. Retry with rw locks to enable
+ * autocleanup. This is the slow path anyway.
+ */
+ br_lck = brl_get_locks(talloc_tos(), fsp);
+ ret = brl_locktest(br_lck, plock);
+ TALLOC_FREE(br_lck);
+ }
+
DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
"len=%ju %s for fnum %ju file %s\n",
lock_flav_name(plock->lock_flav),
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index 722779f..46eec2a 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -58,7 +58,7 @@ bool brl_unlock(struct messaging_context *msg_ctx,
bool brl_unlock_windows_default(struct messaging_context *msg_ctx,
struct byte_range_lock *br_lck,
const struct lock_struct *plock);
-bool brl_locktest(const struct byte_range_lock *br_lck,
+bool brl_locktest(struct byte_range_lock *br_lck,
const struct lock_struct *rw_probe);
NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
uint64_t *psmblctx,
diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c
index b04e7b2..87320e8 100644
--- a/source3/passdb/pdb_samba_dsdb.c
+++ b/source3/passdb/pdb_samba_dsdb.c
@@ -944,8 +944,6 @@ static NTSTATUS pdb_samba_dsdb_getgrfilter(struct pdb_methods *m, GROUP_MAP *map
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- map->sid_name_use = SID_NAME_DOM_GRP;
-
ZERO_STRUCT(id_map);
id_map.sid = sid;
id_maps[0] = &id_map;
diff --git a/source3/torture/msg_sink.c b/source3/torture/msg_sink.c
new file mode 100644
index 0000000..158fe3c
--- /dev/null
+++ b/source3/torture/msg_sink.c
@@ -0,0 +1,284 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Receive and count messages
+ * Copyright (C) Volker Lendecke 2014
+ *
+ * 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/>.
+ */
+
+#include "replace.h"
+#include "includes.h"
+#include "messages.h"
+#include "lib/util/tevent_unix.h"
+#include <stdio.h>
+
+struct sink_state {
--
Samba Shared Repository
More information about the samba-cvs
mailing list