[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Tue Apr 17 03:55:03 MDT 2012


The branch, master has been updated
       via  8ed7ff4 s3: Add smbstatus -N to output the notify db
       via  ee4f2ab s3: Add "notify-cleanup" to smbcontrol
       via  843432d s3: New notify implementation
       via  ae691cd s3: Add two notify benchmark tests
       via  842b86c s3: Make torture_nprocs globally available
       via  0b501e8 s3: Make ctdbd_messaging_send_blob available in non-clustered mode
       via  a03a74c s3: Make messaging_ctdbd_connection available in non-clustered mode
       via  b23b357 s3: Implement tevent_barrier
       via  d705bae s3: Start a list of ctdb srvid assigments
       via  05ff425 s3: Introduce ctdb_messaging_send_blob
       via  74baae7 s3: Add msg_channel
       via  4171259 s3: Add messaging_tdb_event()
       via  48a485b s3: Add a second ctdb connect library
       via  94cf5cc s3: Add dbwrap_try_fetch_locked
       via  bd91785 s3: Add dbwrap_cache
       via  ba8f19c s3: Open up 3 levels of dbwrap_lock_order
       via  d2fe0bf s3: Increase debuglevel for unknown child msgs
       via  1e1b6f7 s3: Add infrastructure for background jobs
       via  a49ac23 s3: Return CTDB_PATH from lp_ctdbd_socket()
       via  6235b76 tdb-compat: Add tdb_chainlock_nonblock
      from  4460ba5 s4:ldapcmp.py: pass down outf and errf

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


- Log -----------------------------------------------------------------
commit 8ed7ff483cc55091138f1e61cfc7573f2f8a0015
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 14:51:09 2012 +0200

    s3: Add smbstatus -N to output the notify db
    
    Autobuild-User: Volker Lendecke <vl at samba.org>
    Autobuild-Date: Tue Apr 17 11:54:35 CEST 2012 on sn-devel-104

commit ee4f2abbda32c4712d0cbc0be171c31d1559a263
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 14:49:21 2012 +0200

    s3: Add "notify-cleanup" to smbcontrol
    
    This triggers a notify cleanup run which would normally only run periodically

commit 843432d56f9114a4d0d3021a772953dc5a1193dd
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 14:51:43 2012 +0200

    s3: New notify implementation
    
    From notify_internal.c:
    
            /*
             * The notify database is split up into two databases: One
             * relatively static index db and the real notify db with the
             * volatile entries.
             */
    
    This change is necessary to make notify scale better in a cluster

commit ae691cd9cc5f00a1d4465d233cdd9f5b580b2c39
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 14:35:12 2012 +0200

    s3: Add two notify benchmark tests

commit 842b86c45ff656aab531530646a4e935e53166e4
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 14:29:33 2012 +0200

    s3: Make torture_nprocs globally available

commit 0b501e823f07b14e4819b817f40cc30da09be1e1
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 11:56:06 2012 +0200

    s3: Make ctdbd_messaging_send_blob available in non-clustered mode
    
    This will avoid the need for some #ifdefs

commit a03a74c35388ed23681a2381252a85bef7cafbe7
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 4 11:27:08 2012 +0200

    s3: Make messaging_ctdbd_connection available in non-clustered mode
    
    This might make some #ifdef CLUSTER_SUPPORT unnecessary in the future

commit b23b35755750589b201a3f4e85521459f575945c
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Apr 3 15:26:22 2012 +0200

    s3: Implement tevent_barrier
    
    This will help notify torture tests: A tevent barrier can be waited on with
    tevent_barrier_wait_send/recv. The barrier is initialized with a number of
    requests that it will accept waiting. When that number is reached, all those
    requests will be released and their callback will be called. The barrier will
    be free for re-use again.

commit d705bae65b70f6fcc711bdb72a1c2b55395f7d6c
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 30 11:37:15 2012 +0200

    s3: Start a list of ctdb srvid assigments

commit 05ff425c1749452179d79b96721c8ac18d886fba
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 30 11:10:47 2012 +0200

    s3: Introduce ctdb_messaging_send_blob
    
    Send a raw blob without the messaging.idl wrap

commit 74baae782f09fd8f22af133b820680e37049f5b0
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Feb 15 13:56:23 2012 +0100

    s3: Add msg_channel
    
    This is a tevent_based variant of messaging_register

commit 41712599e0f33096ccc81e7cd520e66dcf91a424
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Feb 15 13:53:07 2012 +0100

    s3: Add messaging_tdb_event()
    
    This is a void* that represents a signal handler attached to some
    custom tevent_context. This is necessary to make the tdb based
    messaging infrastructure trigger its business when we are sitting in
    tevent_loop_once for an event context that is not the main one in the
    messaging context.

commit 48a485b6396ba020df1c47cbecd6c9fe442ac8a5
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Feb 15 12:26:59 2012 +0100

    s3: Add a second ctdb connect library
    
    The existing one is not async at all.

commit 94cf5cc284ba908675ed5fd573dd101d7b9bad02
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Mar 27 14:31:04 2012 +0200

    s3: Add dbwrap_try_fetch_locked
    
    This is designed to spread the load on individual ctdb records to allow upper
    layers to do backoff mechanisms. In the ctdb case, do not get the record if a
    local lock is already taken. If we are not dmaster, do at most one migrate
    attempt.
    
    For the tdb case, this is a nonblocking fetch_locked. If someone else has the
    lock, give up.

commit bd9178506ed8796a0aa7e4e757f2adc20dcae4f8
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Mar 24 13:49:40 2012 +0100

    s3: Add dbwrap_cache
    
    This is a caching layer for the notify database and potentially for the brlock
    database. It caches the parse_record operation as long as the underlying seqnum
    does not change.

commit ba8f19c556724aaa2de71473234f8bab1f301a7f
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Mar 18 14:47:37 2012 +0100

    s3: Open up 3 levels of dbwrap_lock_order

commit d2fe0bf776dc17b66dcd3ff907c1ff5a43eceeb6
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Apr 13 16:03:26 2012 +0200

    s3: Increase debuglevel for unknown child msgs
    
    Now that we have forked background jobs, this spams log.smbd

commit 1e1b6f79b3ef4ac684df4f7dfbbf949e6c8976a9
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 23 13:43:39 2012 +0100

    s3: Add infrastructure for background jobs

commit a49ac23a10bfe4098cb46b39d3152571a2562a38
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 30 15:37:33 2012 +0200

    s3: Return CTDB_PATH from lp_ctdbd_socket()
    
    All callers had that fallback

commit 6235b761f6eab3ec3d8492ba146e8d9efe6944a6
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Apr 16 15:23:06 2012 +0200

    tdb-compat: Add tdb_chainlock_nonblock

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

Summary of changes:
 lib/tdb_compat/tdb_compat.c         |   24 +
 lib/tdb_compat/tdb_compat.h         |    2 +
 librpc/idl/notify.idl               |   13 +
 source3/Makefile.in                 |    9 +
 source3/include/ctdb_srvids.h       |   40 +
 source3/include/ctdbd_conn.h        |    3 +
 source3/include/messages.h          |    3 +
 source3/include/proto.h             |    1 +
 source3/include/smb.h               |    2 +-
 source3/lib/background.c            |  233 +++++
 source3/lib/background.h            |   39 +
 source3/lib/ctdb_conn.c             |  603 +++++++++++++
 source3/lib/ctdb_conn.h             |   75 ++
 source3/lib/ctdbd_conn.c            |   55 +-
 source3/lib/dbwrap/dbwrap.c         |   27 +-
 source3/lib/dbwrap/dbwrap.h         |    3 +
 source3/lib/dbwrap/dbwrap_cache.c   |  211 +++++
 source3/lib/dbwrap/dbwrap_cache.h   |   32 +
 source3/lib/dbwrap/dbwrap_ctdb.c    |   36 +-
 source3/lib/dbwrap/dbwrap_file.c    |    1 +
 source3/lib/dbwrap/dbwrap_open.c    |   19 +-
 source3/lib/dbwrap/dbwrap_open.h    |    3 +-
 source3/lib/dbwrap/dbwrap_private.h |    3 +
 source3/lib/dbwrap/dbwrap_rbt.c     |    1 +
 source3/lib/dbwrap/dbwrap_tdb.c     |   41 +-
 source3/lib/messages_ctdbd.c        |    9 +
 source3/lib/messages_local.c        |   10 +
 source3/lib/msg_channel.c           |  369 ++++++++
 source3/lib/msg_channel.h           |   45 +
 source3/lib/tevent_barrier.c        |  197 +++++
 source3/lib/tevent_barrier.h        |   37 +
 source3/librpc/idl/messaging.idl    |    3 +
 source3/param/loadparm.c            |   18 +-
 source3/smbd/files.c                |    4 -
 source3/smbd/notify.c               |   36 +-
 source3/smbd/notify_internal.c      | 1666 ++++++++++++++++++++---------------
 source3/smbd/proto.h                |   27 +-
 source3/smbd/server.c               |  102 +++-
 source3/torture/proto.h             |    4 +
 source3/torture/test_ctdbconn.c     |  247 ++++++
 source3/torture/test_msg.c          |  131 +++
 source3/torture/test_notify.c       |  720 +++++++++++++++
 source3/torture/torture.c           |   42 +-
 source3/utils/smbcontrol.c          |   13 +
 source3/utils/status.c              |   40 +
 source3/wscript_build               |   11 +-
 46 files changed, 4375 insertions(+), 835 deletions(-)
 create mode 100644 source3/include/ctdb_srvids.h
 create mode 100644 source3/lib/background.c
 create mode 100644 source3/lib/background.h
 create mode 100644 source3/lib/ctdb_conn.c
 create mode 100644 source3/lib/ctdb_conn.h
 create mode 100644 source3/lib/dbwrap/dbwrap_cache.c
 create mode 100644 source3/lib/dbwrap/dbwrap_cache.h
 create mode 100644 source3/lib/msg_channel.c
 create mode 100644 source3/lib/msg_channel.h
 create mode 100644 source3/lib/tevent_barrier.c
 create mode 100644 source3/lib/tevent_barrier.h
 create mode 100644 source3/torture/test_ctdbconn.c
 create mode 100644 source3/torture/test_msg.c
 create mode 100644 source3/torture/test_notify.c


Changeset truncated at 500 lines:

diff --git a/lib/tdb_compat/tdb_compat.c b/lib/tdb_compat/tdb_compat.c
index 0406eff..7fd3caf 100644
--- a/lib/tdb_compat/tdb_compat.c
+++ b/lib/tdb_compat/tdb_compat.c
@@ -38,6 +38,30 @@ enum TDB_ERROR tdb_transaction_start_nonblock(struct tdb_context *tdb)
 	return ecode;
 }
 
+enum TDB_ERROR tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key)
+{
+	union tdb_attribute locking, orig;
+	enum TDB_ERROR ecode;
+
+	orig.base.attr = TDB_ATTRIBUTE_FLOCK;
+	ecode = tdb_get_attribute(tdb, &orig);
+	if (ecode != TDB_SUCCESS)
+		return ecode;
+
+	/* Replace locking function with our own. */
+	locking = orig;
+	locking.flock.data = &orig;
+	locking.flock.lock = lock_nonblock;
+
+	ecode = tdb_set_attribute(tdb, &locking);
+	if (ecode != TDB_SUCCESS)
+		return ecode;
+
+	ecode = tdb_chainlock(tdb, key);
+	tdb_unset_attribute(tdb, TDB_ATTRIBUTE_FLOCK);
+	return ecode;
+}
+
 /* For TDB1 tdbs, read traverse vs normal matters: write traverse
    locks the entire thing! */
 int64_t tdb_traverse_read_(struct tdb_context *tdb,
diff --git a/lib/tdb_compat/tdb_compat.h b/lib/tdb_compat/tdb_compat.h
index 0d58075..e0a2bf8 100644
--- a/lib/tdb_compat/tdb_compat.h
+++ b/lib/tdb_compat/tdb_compat.h
@@ -87,6 +87,8 @@ int tdb_reopen_all(int parent_longlived);
 
 /* tdb2 does nonblocking functions via attibutes. */
 enum TDB_ERROR tdb_transaction_start_nonblock(struct tdb_context *tdb);
+enum TDB_ERROR tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key);
+
 
 /* Convenient (typesafe) wrapper for tdb open with logging */
 #define tdb_open_compat(name, hsize, tdb_fl, open_fl, mode, log_fn, log_data) \
diff --git a/librpc/idl/notify.idl b/librpc/idl/notify.idl
index 8450106..ec81e8c 100644
--- a/librpc/idl/notify.idl
+++ b/librpc/idl/notify.idl
@@ -32,6 +32,13 @@ interface notify
 		notify_entry entries[num_entries];
 	} notify_entry_array;
 
+	typedef [public] struct {
+		server_id server;
+		uint32 filter; /* filter to apply in this directory */
+		uint32 subdir_filter; /* filter to apply in child directories */
+		pointer private_data;
+	} notify_db_entry;
+
 	/*
 	  to allow for efficient search for matching entries, we
 	  divide them by the directory depth, with a separate array
@@ -62,6 +69,12 @@ interface notify
 		pointer private_data;
 	} notify_event;
 
+	typedef [public] struct {
+		uint32 action;
+		uint32 filter;
+		utf8string path;
+	} notify_remote_event;
+
 	typedef [v1_enum] enum {
 		FILE_ACTION_ADDED		= 0x00000001,
 		FILE_ACTION_REMOVED		= 0x00000002,
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 21d3bf9..d48ce37 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -262,6 +262,7 @@ TDB_LIB_OBJ = lib/util_tdb.o ../lib/util/util_tdb.o \
 	  lib/dbwrap/dbwrap_tdb.o \
 	  lib/dbwrap/dbwrap_ctdb.o \
 	  lib/g_lock.o \
+	  lib/dbwrap/dbwrap_cache.o \
 	  lib/dbwrap/dbwrap_rbt.o
 
 TDB_VALIDATE_OBJ = lib/tdb_validate.o
@@ -418,6 +419,7 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \
 		   ../lib/util/become_daemon.o ../lib/util/system.o \
 		   ../lib/util/tevent_unix.o ../lib/util/tevent_ntstatus.o \
 		   ../lib/util/tevent_werror.o \
+		   lib/tevent_barrier.o \
 		   ../lib/util/smb_threads.o ../lib/util/util_id.o \
 		   ../lib/util/blocking.o ../lib/util/rfc1738.o \
 		   ../lib/util/select.o ../lib/util/util_pw.o ../lib/util/server_id.o
@@ -432,6 +434,8 @@ CRYPTO_OBJ = ../lib/crypto/crc32.o @CRYPTO_MD5_OBJ@ \
 LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) $(LIBTSOCKET_OBJ) \
 	  lib/messages.o librpc/gen_ndr/ndr_messaging.o lib/messages_local.o \
 	  lib/messages_ctdbd.o lib/ctdb_packet.o lib/ctdbd_conn.o \
+	  lib/ctdb_conn.o \
+	  lib/msg_channel.o \
 	  lib/id_cache.o \
 	  ../lib/socket/interfaces.o lib/memcache.o \
 	  lib/talloc_dict.o \
@@ -942,6 +946,7 @@ SMBD_OBJ_SRV = smbd/server_reload.o \
 	       lib/sysquotas_xfs.o lib/sysquotas_4A.o \
 	       lib/sysquotas_nfs.o \
 	       lib/smbd_shim.o \
+	       lib/background.o \
 	       smbd/fake_file.o \
 	       smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \
 	       $(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
@@ -1033,6 +1038,7 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(PRINTBASE_OBJ) $(LIBSMB_O
 
 STATUS_OBJ = utils/status.o utils/status_profile.o \
 	     $(LOCKING_OBJ) $(PARAM_OBJ) \
+	     smbd/notify_internal.o librpc/gen_ndr/ndr_notify.o \
              $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
 	     $(LIBSMB_ERR_OBJ) $(FNAME_UTIL_OBJ)
 
@@ -1271,6 +1277,9 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta
 		torture/test_chain3.o \
 		torture/test_authinfo_structs.o \
 		torture/test_cleanup.o \
+		torture/test_ctdbconn.o \
+		torture/test_msg.o \
+		torture/test_notify.o \
 		torture/t_strappend.o
 
 SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) $(TLDAP_OBJ) \
diff --git a/source3/include/ctdb_srvids.h b/source3/include/ctdb_srvids.h
new file mode 100644
index 0000000..500b506
--- /dev/null
+++ b/source3/include/ctdb_srvids.h
@@ -0,0 +1,40 @@
+/*
+   Unix SMB/CIFS implementation.
+   Samba3 ctdb srvid assignments
+   Copyright (C) Volker Lendecke 2012
+
+   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/>.
+*/
+
+/*
+ * ctdb has reserved all srvids starting with 0xFE for Samba. Here we list our
+ * static assignments that are supposed to be globally unique.
+ */
+
+/*
+ * ctdb_protocol.h already has the following definition, used in the g_lock
+ * implementation. Waiters for a g_lock register this to receive notifications
+ * when g_lock holders die.
+ */
+
+#if 0
+#define CTDB_SRVID_SAMBA_NOTIFY  0xFE00000000000000LL
+#endif
+
+/*
+ * SRVID for notify_internal.c: On every node, one process registers this
+ * SRVID. It receives filechangenotify notifications and multicasts them
+ * locally according to the non-clustered local notify.tdb
+ */
+#define CTDB_SRVID_SAMBA_NOTIFY_PROXY  0xFE00000000000001LL
diff --git a/source3/include/ctdbd_conn.h b/source3/include/ctdbd_conn.h
index 2035e8d..b1a58cb 100644
--- a/source3/include/ctdbd_conn.h
+++ b/source3/include/ctdbd_conn.h
@@ -40,6 +40,9 @@ int ctdbd_conn_get_fd(struct ctdbd_connection *conn);
 NTSTATUS ctdbd_messaging_send(struct ctdbd_connection *conn,
 			      uint32 dst_vnn, uint64 dst_srvid,
 			      struct messaging_rec *msg);
+NTSTATUS ctdbd_messaging_send_blob(struct ctdbd_connection *conn,
+				   uint32 dst_vnn, uint64 dst_srvid,
+				   const uint8_t *buf, size_t buflen);
 
 bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32 vnn,
 			  pid_t pid);
diff --git a/source3/include/messages.h b/source3/include/messages.h
index 2161a77..4b45901 100644
--- a/source3/include/messages.h
+++ b/source3/include/messages.h
@@ -98,6 +98,9 @@ NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx,
 
 bool messaging_tdb_parent_init(TALLOC_CTX *mem_ctx);
 
+void *messaging_tdb_event(TALLOC_CTX *mem_ctx, struct messaging_context *msg,
+			  struct tevent_context *ev);
+
 NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx,
 			      TALLOC_CTX *mem_ctx,
 			      struct messaging_backend **presult);
diff --git a/source3/include/proto.h b/source3/include/proto.h
index dae69b7..035d87e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1293,6 +1293,7 @@ int lp_cups_encrypt(void);
 char *lp_iprint_server(void);
 int lp_cups_connection_timeout(void);
 const char *lp_ctdbd_socket(void);
+const char *_lp_ctdbd_socket(void);
 const char **lp_cluster_addresses(void);
 bool lp_clustering(void);
 int lp_ctdb_timeout(void);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 758ad99..b5c674d 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -182,7 +182,7 @@ struct notify_change {
 };
 
 struct notify_mid_map;
-struct notify_entry;
+struct notify_db_entry;
 struct notify_event;
 struct notify_change_request;
 struct sys_notify_backend;
diff --git a/source3/lib/background.c b/source3/lib/background.c
new file mode 100644
index 0000000..aa2a77d
--- /dev/null
+++ b/source3/lib/background.c
@@ -0,0 +1,233 @@
+/*
+   Unix SMB/CIFS implementation.
+   Regular background jobs as forked helpers
+   Copyright (C) Volker Lendecke 2012
+
+   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 "includes.h"
+#include "lib/util/tevent_ntstatus.h"
+#include "lib/async_req/async_sock.h"
+#include "include/messages.h"
+#include "background.h"
+
+struct background_job_state {
+	struct tevent_context *ev;
+	struct messaging_context *msg;
+	uint32_t *trigger_msgs;
+	size_t num_trigger_msgs;
+	bool parent_longlived;
+	int (*fn)(void *private_data);
+	void *private_data;
+
+	struct tevent_req *wakeup_req;
+	int pipe_fd;
+};
+
+static int background_job_state_destructor(struct background_job_state *s);
+static void background_job_waited(struct tevent_req *subreq);
+static void background_job_done(struct tevent_req *subreq);
+static void background_job_trigger(
+	struct messaging_context *msg, void *private_data, uint32_t msg_type,
+	struct server_id server_id, DATA_BLOB *data);
+
+struct tevent_req *background_job_send(TALLOC_CTX *mem_ctx,
+				       struct tevent_context *ev,
+				       struct messaging_context *msg,
+				       uint32_t *trigger_msgs,
+				       size_t num_trigger_msgs,
+				       time_t initial_wait_sec,
+				       int (*fn)(void *private_data),
+				       void *private_data)
+{
+	struct tevent_req *req, *subreq;
+	struct background_job_state *state;
+	size_t i;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct background_job_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	state->ev = ev;
+	state->msg = msg;
+
+	if (num_trigger_msgs != 0) {
+		state->trigger_msgs = (uint32_t *)talloc_memdup(
+			state, trigger_msgs,
+			sizeof(uint32_t) * num_trigger_msgs);
+		if (tevent_req_nomem(state->trigger_msgs, req)) {
+			return tevent_req_post(req, ev);
+		}
+		state->num_trigger_msgs = num_trigger_msgs;
+	}
+
+	state->fn = fn;
+	state->private_data = private_data;
+
+	state->pipe_fd = -1;
+	talloc_set_destructor(state, background_job_state_destructor);
+
+	for (i=0; i<num_trigger_msgs; i++) {
+		NTSTATUS status;
+		status = messaging_register(msg, state, trigger_msgs[i],
+					    background_job_trigger);
+		if (tevent_req_nterror(req, status)) {
+			return tevent_req_post(req, ev);
+		}
+	}
+
+	subreq = tevent_wakeup_send(
+		state, state->ev, timeval_current_ofs(initial_wait_sec, 0));
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, background_job_waited, req);
+	state->wakeup_req = subreq;
+	return req;
+}
+
+static int background_job_state_destructor(struct background_job_state *state)
+{
+	size_t i;
+	if (state->pipe_fd != -1) {
+		close(state->pipe_fd);
+		state->pipe_fd = -1;
+	}
+	for (i=0; i<state->num_trigger_msgs; i++) {
+		messaging_deregister(state->msg, state->trigger_msgs[i],
+				     state);
+	}
+	return 0;
+}
+
+static void background_job_trigger(
+	struct messaging_context *msg, void *private_data, uint32_t msg_type,
+	struct server_id server_id, DATA_BLOB *data)
+{
+	struct background_job_state *state = talloc_get_type_abort(
+		private_data, struct background_job_state);
+
+	if (state->wakeup_req != NULL) {
+		tevent_req_set_endtime(state->wakeup_req, state->ev,
+				       timeval_zero());
+	}
+}
+
+static void background_job_waited(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct background_job_state *state = tevent_req_data(
+		req, struct background_job_state);
+	int fds[2];
+	int res;
+	bool ret;
+
+	ret = tevent_wakeup_recv(subreq);
+	TALLOC_FREE(subreq);
+	state->wakeup_req = NULL;
+	if (!ret) {
+		tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+		return;
+	}
+
+	res = pipe(fds);
+	if (res == -1) {
+		tevent_req_nterror(req, map_nt_error_from_unix(errno));
+		return;
+	}
+
+	res = fork();
+	if (res == -1) {
+		int err = errno;
+		close(fds[0]);
+		close(fds[1]);
+		tevent_req_nterror(req, map_nt_error_from_unix(err));
+		return;
+	}
+
+	if (res == 0) {
+		/* child */
+
+		NTSTATUS status;
+		ssize_t written;
+
+		close(fds[0]);
+
+		status = reinit_after_fork(state->msg, state->ev, true);
+		if (NT_STATUS_IS_OK(status)) {
+			res = state->fn(state->private_data);
+		} else {
+			res = -1;
+		}
+		written = write(fds[1], &res, sizeof(res));
+		if (written == -1) {
+			_exit(1);
+		}
+		_exit(0);
+	}
+
+	/* parent */
+
+	close(fds[1]);
+	state->pipe_fd = fds[0];
+
+	subreq = read_packet_send(state, state->ev, state->pipe_fd,
+				  sizeof(int), NULL, NULL);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq, background_job_done, req);
+}
+
+static void background_job_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct background_job_state *state = tevent_req_data(
+		req, struct background_job_state);
+	ssize_t ret;
+	uint8_t *buf;
+	int err;
+	int wait_secs;
+
+	ret = read_packet_recv(subreq, talloc_tos(), &buf, &err);
+	TALLOC_FREE(subreq);
+	if (ret == -1) {
+		tevent_req_nterror(req, map_nt_error_from_unix(err));
+		return;
+	}
+	close(state->pipe_fd);
+	state->pipe_fd = -1;
+	memcpy(&wait_secs, buf, sizeof(wait_secs));
+	if (wait_secs == -1) {
+		tevent_req_done(req);
+		return;
+	}
+	subreq = tevent_wakeup_send(
+		state, state->ev, timeval_current_ofs(wait_secs, 0));
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq, background_job_waited, req);
+	state->wakeup_req = subreq;
+}
+
+NTSTATUS background_job_recv(struct tevent_req *req)
+{
+	return tevent_req_simple_recv_ntstatus(req);
+}
diff --git a/source3/lib/background.h b/source3/lib/background.h
new file mode 100644
index 0000000..ccfd62b
--- /dev/null
+++ b/source3/lib/background.h
@@ -0,0 +1,39 @@
+/*
+   Unix SMB/CIFS implementation.
+   Regular background jobs as forked helpers
+   Copyright (C) Volker Lendecke 2012
+
+   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/>.
+*/
+
+#ifndef _LIB_BACKGROUND_H_
+#define _LIB_BACKGROUND_H_
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list