The Samba-Bugzilla – Attachment 8944 Details for
Bug 9930
smbd did not cleanup disonnected durable handles
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
packport the scavenger daemon from master
scavenger-backport.patch (text/plain), 43.34 KB, created by
Gregor Beck (550 Unknown user)
on 2013-06-05 13:41:55 UTC
(
hide
)
Description:
packport the scavenger daemon from master
Filename:
MIME Type:
Creator:
Gregor Beck (550 Unknown user)
Created:
2013-06-05 13:41:55 UTC
Size:
43.34 KB
patch
obsolete
>From 436d8fb4045a3be105efac5e53288af280ddf934 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 18 Feb 2013 08:54:51 +0100 >Subject: [PATCH 01/10] lib/util: add samba_tevent_context_init() > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit f7aa60175ad7a3517db32f45f06dfbf6486dff69) >--- > lib/util/samba_util.h | 6 +++++ > lib/util/tevent_debug.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++ > lib/util/wscript_build | 5 ++-- > source3/Makefile.in | 2 +- > 4 files changed, 77 insertions(+), 3 deletions(-) > create mode 100644 lib/util/tevent_debug.c > >diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h >index 4a6dd3b..d552a00 100644 >--- a/lib/util/samba_util.h >+++ b/lib/util/samba_util.h >@@ -916,4 +916,10 @@ void server_id_set_disconnected(struct server_id *id); > */ > bool server_id_is_disconnected(const struct server_id *id); > >+/* >+ * Samba code should use samba_tevent_context_init() instead of >+ * tevent_context_init() in order to get the debug output. >+ */ >+struct tevent_context *samba_tevent_context_init(TALLOC_CTX *mem_ctx); >+ > #endif /* _SAMBA_UTIL_H_ */ >diff --git a/lib/util/tevent_debug.c b/lib/util/tevent_debug.c >new file mode 100644 >index 0000000..3a5a313 >--- /dev/null >+++ b/lib/util/tevent_debug.c >@@ -0,0 +1,67 @@ >+/* >+ Unix SMB/CIFS implementation. >+ Copyright (C) Andrew Tridgell 2003 >+ >+ 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 <tevent.h> >+ >+static void samba_tevent_debug(void *context, >+ enum tevent_debug_level level, >+ const char *fmt, >+ va_list ap) PRINTF_ATTRIBUTE(3,0); >+ >+static void samba_tevent_debug(void *context, >+ enum tevent_debug_level level, >+ const char *fmt, >+ va_list ap) >+{ >+ int samba_level = -1; >+ char *s = NULL; >+ switch (level) { >+ case TEVENT_DEBUG_FATAL: >+ samba_level = 0; >+ break; >+ case TEVENT_DEBUG_ERROR: >+ samba_level = 1; >+ break; >+ case TEVENT_DEBUG_WARNING: >+ samba_level = 2; >+ break; >+ case TEVENT_DEBUG_TRACE: >+ samba_level = 50; >+ break; >+ }; >+ >+ if (CHECK_DEBUGLVL(samba_level)) { >+ vasprintf(&s, fmt, ap); >+ if (!s) return; >+ DEBUG(samba_level, ("samba_tevent: %s", s)); >+ free(s); >+ } >+} >+ >+struct tevent_context *samba_tevent_context_init(TALLOC_CTX *mem_ctx) >+{ >+ struct tevent_context *ev; >+ >+ ev = tevent_context_init(mem_ctx); >+ if (ev) { >+ tevent_set_debug(ev, samba_tevent_debug, NULL); >+ } >+ >+ return ev; >+} >diff --git a/lib/util/wscript_build b/lib/util/wscript_build >index ddaf90f..db6cf14 100755 >--- a/lib/util/wscript_build >+++ b/lib/util/wscript_build >@@ -7,9 +7,10 @@ bld.SAMBA_LIBRARY('samba-util', > signal.c system.c params.c util.c util_id.c util_net.c > util_strlist.c util_paths.c idtree.c debug.c fault.c base64.c > util_str.c util_str_common.c substitute.c ms_fnmatch.c >- server_id.c dprintf.c parmlist.c bitmap.c pidfile.c''', >+ server_id.c dprintf.c parmlist.c bitmap.c pidfile.c >+ tevent_debug.c''', > deps='DYNCONFIG', >- public_deps='talloc execinfo uid_wrapper pthread LIBCRYPTO charset util_setid', >+ public_deps='talloc tevent execinfo uid_wrapper pthread LIBCRYPTO charset util_setid', > public_headers='debug.h attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h samba_util.h string_wrappers.h', > header_path= [ ('dlinklist.h samba_util.h', '.'), ('*', 'util') ], > local_include=False, >diff --git a/source3/Makefile.in b/source3/Makefile.in >index 55505df..4b04a97 100644 >--- a/source3/Makefile.in >+++ b/source3/Makefile.in >@@ -480,7 +480,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) $(LIBTSOCKET_OBJ) \ > ../lib/util/charset/iconv.o ../lib/util/charset/weird.o \ > ../lib/util/charset/charset_macosxfs.o intl/lang_tdb.o \ > lib/adt_tree.o lib/gencache.o \ >- ../lib/util/modules.o lib/events.o @LIBTEVENT_OBJ0@ \ >+ ../lib/util/modules.o lib/events.o ../lib/util/tevent_debug.o @LIBTEVENT_OBJ0@ \ > @CCAN_OBJ@ \ > lib/server_contexts.o \ > lib/server_prefork.o \ >-- >1.7.9.5 > > >From b176e7293ed6b5c4055c8b6b1d29c732ff10595c Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 5 Mar 2013 15:54:44 +0100 >Subject: [PATCH 02/10] lib: Add prctl_set_comment to utils. > >Reviewed-by: David Disseldorp <ddiss@samba.org> >(cherry picked from commit f9fb3faaef4c15b7c4c3748b0e93fa3061b573c3) >--- > lib/util/util_process.c | 34 ++++++++++++++++++++++++++++++++++ > lib/util/util_process.h | 35 +++++++++++++++++++++++++++++++++++ > lib/util/wscript_build | 2 +- > source3/Makefile.in | 2 +- > 4 files changed, 71 insertions(+), 2 deletions(-) > create mode 100644 lib/util/util_process.c > create mode 100644 lib/util/util_process.h > >diff --git a/lib/util/util_process.c b/lib/util/util_process.c >new file mode 100644 >index 0000000..6036e27 >--- /dev/null >+++ b/lib/util/util_process.c >@@ -0,0 +1,34 @@ >+/* >+ * Unix SMB/CIFS implementation. >+ * >+ * Process utils. >+ * >+ * Copyright (c) 2013 Andreas Schneider <asn@samba.org> >+ * >+ * 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 "util_process.h" >+ >+#ifdef HAVE_SYS_PRCTL_H >+#include <sys/prctl.h> >+#endif >+ >+int prctl_set_comment(const char *comment) >+{ >+#if defined(HAVE_PRCTL) && defined(PR_SET_NAME) >+ return prctl(PR_SET_NAME, (unsigned long) comment, 0, 0, 0); >+#endif >+ return 0; >+} >diff --git a/lib/util/util_process.h b/lib/util/util_process.h >new file mode 100644 >index 0000000..6e1ef07 >--- /dev/null >+++ b/lib/util/util_process.h >@@ -0,0 +1,35 @@ >+/* >+ * Unix SMB/CIFS implementation. >+ * >+ * Process utils. >+ * >+ * Copyright (c) 2013 Andreas Schneider <asn@samba.org> >+ * >+ * 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 _SAMBA_UTIL_PROCESS_H >+#define _SAMBA_UTIL_PROCESS_H >+ >+/** >+ * @brief Set the process comment name. >+ * >+ * @param[in] comment The comment to set which shouldn't be longer than 16 >+ * 16 characters (including \0). >+ * >+ * @return -1 on error, 0 on success. >+ */ >+int prctl_set_comment(const char *comment); >+ >+#endif >diff --git a/lib/util/wscript_build b/lib/util/wscript_build >index db6cf14..39bf4a9 100755 >--- a/lib/util/wscript_build >+++ b/lib/util/wscript_build >@@ -8,7 +8,7 @@ bld.SAMBA_LIBRARY('samba-util', > util_strlist.c util_paths.c idtree.c debug.c fault.c base64.c > util_str.c util_str_common.c substitute.c ms_fnmatch.c > server_id.c dprintf.c parmlist.c bitmap.c pidfile.c >- tevent_debug.c''', >+ tevent_debug.c util_process.c''', > deps='DYNCONFIG', > public_deps='talloc tevent execinfo uid_wrapper pthread LIBCRYPTO charset util_setid', > public_headers='debug.h attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h samba_util.h string_wrappers.h', >diff --git a/source3/Makefile.in b/source3/Makefile.in >index 4b04a97..c2eef8b 100644 >--- a/source3/Makefile.in >+++ b/source3/Makefile.in >@@ -429,7 +429,7 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ > ../lib/util/genrand.o ../lib/util/util_net.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/util/tevent_werror.o ../lib/util/util_process.o\ > lib/tevent_barrier.o \ > ../lib/util/smb_threads.o ../lib/util/util_id.o \ > ../lib/util/blocking.o ../lib/util/rfc1738.o \ >-- >1.7.9.5 > > >From a98059f546a4f1a2c4c6e44999d1e5614be23c16 Mon Sep 17 00:00:00 2001 >From: Gregor Beck <gbeck@sernet.de> >Date: Tue, 12 Mar 2013 15:10:51 +0100 >Subject: [PATCH 03/10] s3:locking: no need to make a file_id passed by value > a constant > >Signed-off-by: Gregor Beck <gbeck@sernet.de> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 3d3e7e837a339dfc1aaf4d7fc52f95f3f6a80173) >--- > source3/locking/proto.h | 6 +++--- > source3/locking/share_mode_lock.c | 17 +++++++---------- > 2 files changed, 10 insertions(+), 13 deletions(-) > >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index 69c78e3..1d8eb73 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -150,15 +150,15 @@ bool locking_init_readonly(void); > bool locking_end(void); > char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e); > struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx, >- const struct file_id id); >+ struct file_id id); > struct share_mode_lock *get_share_mode_lock( > TALLOC_CTX *mem_ctx, >- const struct file_id id, >+ struct file_id id, > const char *servicepath, > const struct smb_filename *smb_fname, > const struct timespec *old_write_time); > struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, >- const struct file_id id); >+ struct file_id id); > bool rename_share_filename(struct messaging_context *msg_ctx, > struct share_mode_lock *lck, > const char *servicepath, >diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c >index 4f26099..2d7ca39 100644 >--- a/source3/locking/share_mode_lock.c >+++ b/source3/locking/share_mode_lock.c >@@ -104,10 +104,9 @@ bool locking_end(void) > Form a static locking key for a dev/inode pair. > ******************************************************************/ > >-static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp) >+static TDB_DATA locking_key(const struct file_id *id) > { >- *tmp = *id; >- return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp)); >+ return make_tdb_data((const uint8_t *)id, sizeof(*id)); > } > > /******************************************************************* >@@ -286,15 +285,14 @@ fail: > ********************************************************************/ > > static struct share_mode_lock *get_share_mode_lock_internal( >- TALLOC_CTX *mem_ctx, const struct file_id id, >+ TALLOC_CTX *mem_ctx, struct file_id id, > const char *servicepath, const struct smb_filename *smb_fname, > const struct timespec *old_write_time) > { > struct share_mode_lock *lck; > struct share_mode_data *d; >- struct file_id tmp; > struct db_record *rec; >- TDB_DATA key = locking_key(&id, &tmp); >+ TDB_DATA key = locking_key(&id); > TDB_DATA value; > > rec = dbwrap_fetch_locked(lock_db, mem_ctx, key); >@@ -351,7 +349,7 @@ static int the_lock_destructor(struct share_mode_lock *l) > > struct share_mode_lock *get_share_mode_lock( > TALLOC_CTX *mem_ctx, >- const struct file_id id, >+ struct file_id id, > const char *servicepath, > const struct smb_filename *smb_fname, > const struct timespec *old_write_time) >@@ -404,11 +402,10 @@ static void fetch_share_mode_unlocked_parser( > ********************************************************************/ > > struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, >- const struct file_id id) >+ struct file_id id) > { > struct share_mode_lock *lck; >- struct file_id tmp; >- TDB_DATA key = locking_key(&id, &tmp); >+ TDB_DATA key = locking_key(&id); > NTSTATUS status; > > lck = talloc(mem_ctx, struct share_mode_lock); >-- >1.7.9.5 > > >From 4a2b5ae46e2eedda1c0b6c40db084ce88e3d3c0e Mon Sep 17 00:00:00 2001 >From: Gregor Beck <gbeck@sernet.de> >Date: Wed, 20 Mar 2013 10:22:06 +0100 >Subject: [PATCH 04/10] s3:locking: improve debug output of > parse_share_modes() > >Signed-off-by: Gregor Beck <gbeck@sernet.de> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 0ac0b35dad796d10cf04ab77a53a926420cc0589) >--- > source3/locking/share_mode_lock.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c >index 2d7ca39..56637ed 100644 >--- a/source3/locking/share_mode_lock.c >+++ b/source3/locking/share_mode_lock.c >@@ -132,7 +132,8 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx, > ndr_err = ndr_pull_struct_blob( > &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data); > if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- DEBUG(1, ("ndr_pull_share_mode_lock failed\n")); >+ DEBUG(1, ("ndr_pull_share_mode_lock failed: %s\n", >+ ndr_errstr(ndr_err))); > goto fail; > } > >-- >1.7.9.5 > > >From dfdc3d4b81aa09d893735708e140a173b94bc5fd Mon Sep 17 00:00:00 2001 >From: Gregor Beck <gbeck@sernet.de> >Date: Wed, 13 Mar 2013 11:35:37 +0100 >Subject: [PATCH 05/10] s3:locking: add function > share_mode_cleanup_disconnected() > >For a given file, clean share mode entries for a given persistent file id. > >Pair-Programmed-With: Michael Adam <obnox@samba.org> >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Gregor Beck <gbeck@sernet.de> >Signed-off-by: Michael Adam <obnox@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit f608bedfca4118b7e3606802df40e266bcc099d8) >--- > source3/locking/proto.h | 3 ++ > source3/locking/share_mode_lock.c | 99 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 102 insertions(+) > >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index 1d8eb73..bb7255d 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -202,6 +202,9 @@ bool set_write_time(struct file_id fileid, struct timespec write_time); > int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, > const char *, void *), > void *private_data); >+bool share_mode_cleanup_disconnected(struct file_id id, >+ uint64_t open_persistent_id); >+ > > /* The following definitions come from locking/posix.c */ > >diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c >index 56637ed..04ff247 100644 >--- a/source3/locking/share_mode_lock.c >+++ b/source3/locking/share_mode_lock.c >@@ -501,3 +501,102 @@ int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, > return count; > } > } >+ >+bool share_mode_cleanup_disconnected(struct file_id fid, >+ uint64_t open_persistent_id) >+{ >+ bool ret = false; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ unsigned n; >+ struct share_mode_data *data; >+ struct share_mode_lock *lck; >+ bool ok; >+ >+ lck = get_existing_share_mode_lock(frame, fid); >+ if (lck == NULL) { >+ DEBUG(5, ("share_mode_cleanup_disconnected: " >+ "Could not fetch share mode entry for %s\n", >+ file_id_string(frame, &fid))); >+ goto done; >+ } >+ data = lck->data; >+ >+ for (n=0; n < data->num_share_modes; n++) { >+ struct share_mode_entry *entry = &data->share_modes[n]; >+ >+ if (!server_id_is_disconnected(&entry->pid)) { >+ DEBUG(5, ("share_mode_cleanup_disconnected: " >+ "file (file-id='%s', servicepath='%s', " >+ "base_name='%s%s%s') " >+ "is used by server %s ==> do not cleanup\n", >+ file_id_string(frame, &fid), >+ data->servicepath, >+ data->base_name, >+ (data->stream_name == NULL) >+ ? "" : "', stream_name='", >+ (data->stream_name == NULL) >+ ? "" : data->stream_name, >+ server_id_str(frame, &entry->pid))); >+ goto done; >+ } >+ if (open_persistent_id != entry->share_file_id) { >+ DEBUG(5, ("share_mode_cleanup_disconnected: " >+ "entry for file " >+ "(file-id='%s', servicepath='%s', " >+ "base_name='%s%s%s') " >+ "has share_file_id %llu but expected %llu" >+ "==> do not cleanup\n", >+ file_id_string(frame, &fid), >+ data->servicepath, >+ data->base_name, >+ (data->stream_name == NULL) >+ ? "" : "', stream_name='", >+ (data->stream_name == NULL) >+ ? "" : data->stream_name, >+ (unsigned long long)entry->share_file_id, >+ (unsigned long long)open_persistent_id)); >+ goto done; >+ } >+ } >+ >+ ok = brl_cleanup_disconnected(fid, open_persistent_id); >+ if (!ok) { >+ DEBUG(10, ("share_mode_cleanup_disconnected: " >+ "failed to clean up byte range locks associated " >+ "with file (file-id='%s', servicepath='%s', " >+ "base_name='%s%s%s') and open_persistent_id %llu " >+ "==> do not cleanup\n", >+ file_id_string(frame, &fid), >+ data->servicepath, >+ data->base_name, >+ (data->stream_name == NULL) >+ ? "" : "', stream_name='", >+ (data->stream_name == NULL) >+ ? "" : data->stream_name, >+ (unsigned long long)open_persistent_id)); >+ goto done; >+ } >+ >+ DEBUG(10, ("share_mode_cleanup_disconnected: " >+ "cleaning up %u entries for file " >+ "(file-id='%s', servicepath='%s', " >+ "base_name='%s%s%s') " >+ "from open_persistent_id %llu\n", >+ data->num_share_modes, >+ file_id_string(frame, &fid), >+ data->servicepath, >+ data->base_name, >+ (data->stream_name == NULL) >+ ? "" : "', stream_name='", >+ (data->stream_name == NULL) >+ ? "" : data->stream_name, >+ (unsigned long long)open_persistent_id)); >+ >+ data->num_share_modes = 0; >+ data->modified = true; >+ >+ ret = true; >+done: >+ talloc_free(frame); >+ return ret; >+} >-- >1.7.9.5 > > >From 8baf2caec86482082719f5c8aa5cc56af030aa7e Mon Sep 17 00:00:00 2001 >From: Gregor Beck <gbeck@sernet.de> >Date: Thu, 7 Feb 2013 15:26:37 +0100 >Subject: [PATCH 06/10] s3:smbd: add a scavenger process for disconnected > durable handles > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Gregor Beck <gbeck@sernet.de> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >--- > lib/util/debug.c | 1 + > lib/util/debug.h | 3 +- > source3/Makefile.in | 1 + > source3/librpc/idl/messaging.idl | 1 + > source3/smbd/scavenger.c | 531 ++++++++++++++++++++++++++++++++++++++ > source3/smbd/scavenger.h | 31 +++ > source3/smbd/server.c | 5 + > source3/wscript_build | 1 + > 8 files changed, 573 insertions(+), 1 deletion(-) > create mode 100644 source3/smbd/scavenger.c > create mode 100644 source3/smbd/scavenger.h > >diff --git a/lib/util/debug.c b/lib/util/debug.c >index 7509f90..6207b61 100644 >--- a/lib/util/debug.c >+++ b/lib/util/debug.c >@@ -176,6 +176,7 @@ static const char *default_classname_table[] = { > "msdfs", /* DBGC_MSDFS */ > "dmapi", /* DBGC_DMAPI */ > "registry", /* DBGC_REGISTRY */ >+ "scavenger", /* DBGC_SCAVENGER */ > NULL > }; > >diff --git a/lib/util/debug.h b/lib/util/debug.h >index 2566418..c61fd13 100644 >--- a/lib/util/debug.h >+++ b/lib/util/debug.h >@@ -79,9 +79,10 @@ bool dbghdr( int level, const char *location, const char *func); > #define DBGC_MSDFS 17 > #define DBGC_DMAPI 18 > #define DBGC_REGISTRY 19 >+#define DBGC_SCAVENGER 20 > > /* Always ensure this is updated when new fixed classes area added, to ensure the array in debug.c is the right size */ >-#define DBGC_MAX_FIXED 19 >+#define DBGC_MAX_FIXED 20 > > /* So you can define DBGC_CLASS before including debug.h */ > #ifndef DBGC_CLASS >diff --git a/source3/Makefile.in b/source3/Makefile.in >index c2eef8b..3cae2cf 100644 >--- a/source3/Makefile.in >+++ b/source3/Makefile.in >@@ -984,6 +984,7 @@ SMBD_OBJ_SRV = smbd/server_reload.o \ > smbd/smbXsrv_tcon.o \ > smbd/smbXsrv_open.o \ > smbd/durable.o \ >+ smbd/scavenger.o \ > $(MANGLE_OBJ) @VFS_STATIC@ > > SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ >diff --git a/source3/librpc/idl/messaging.idl b/source3/librpc/idl/messaging.idl >index df1f321..c262889 100644 >--- a/source3/librpc/idl/messaging.idl >+++ b/source3/librpc/idl/messaging.idl >@@ -87,6 +87,7 @@ interface messaging > > /* Trigger a notify cleanup run */ > MSG_SMB_NOTIFY_CLEANUP = 0x0314, >+ MSG_SMB_SCAVENGER = 0x0315, > > /* winbind messages */ > MSG_WINBIND_FINISHED = 0x0401, >diff --git a/source3/smbd/scavenger.c b/source3/smbd/scavenger.c >new file mode 100644 >index 0000000..fe4e56e >--- /dev/null >+++ b/source3/smbd/scavenger.c >@@ -0,0 +1,531 @@ >+/* >+ Unix SMB/CIFS implementation. >+ smbd scavenger daemon >+ >+ Copyright (C) Gregor Beck 2013 >+ >+ 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 "messages.h" >+#include "serverid.h" >+#include "smbd/globals.h" >+#include "smbd/scavenger.h" >+#include "locking/proto.h" >+#include "lib/util/util_process.h" >+ >+#undef DBGC_CLASS >+#define DBGC_CLASS DBGC_SCAVENGER >+ >+struct smbd_scavenger_state { >+ struct tevent_context *ev; >+ struct messaging_context *msg; >+ struct server_id parent_id; >+ struct server_id *scavenger_id; >+ bool am_scavenger; >+}; >+ >+static struct smbd_scavenger_state *smbd_scavenger_state = NULL; >+ >+struct scavenger_message { >+ struct file_id file_id; >+ uint64_t open_persistent_id; >+ NTTIME until; >+}; >+ >+static int smbd_scavenger_main(struct smbd_scavenger_state *state) >+{ >+ DEBUG(10, ("scavenger: %s started, parent: %s\n", >+ server_id_str(talloc_tos(), state->scavenger_id), >+ server_id_str(talloc_tos(), &state->parent_id))); >+ >+ while (true) { >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int ret; >+ >+ ret = tevent_loop_once(state->ev); >+ if (ret != 0) { >+ DEBUG(2, ("tevent_loop_once failed: %s\n", >+ strerror(errno))); >+ TALLOC_FREE(frame); >+ return 1; >+ } >+ >+ DEBUG(10, ("scavenger: %s event loop iteration\n", >+ server_id_str(talloc_tos(), state->scavenger_id))); >+ TALLOC_FREE(frame); >+ } >+ >+ return 0; >+} >+ >+static void smbd_scavenger_done(struct tevent_context *event_ctx, struct tevent_fd *fde, >+ uint16_t flags, void *private_data) >+{ >+ struct smbd_scavenger_state *state = talloc_get_type_abort( >+ private_data, struct smbd_scavenger_state); >+ >+ DEBUG(2, ("scavenger: %s died\n", >+ server_id_str(talloc_tos(), state->scavenger_id))); >+ >+ TALLOC_FREE(state->scavenger_id); >+} >+ >+static void smbd_scavenger_parent_dead(struct tevent_context *event_ctx, >+ struct tevent_fd *fde, >+ uint16_t flags, void *private_data) >+{ >+ struct smbd_scavenger_state *state = talloc_get_type_abort( >+ private_data, struct smbd_scavenger_state); >+ >+ DEBUG(2, ("scavenger: %s parent %s died\n", >+ server_id_str(talloc_tos(), state->scavenger_id), >+ server_id_str(talloc_tos(), &state->parent_id))); >+ >+ exit_server("smbd_scavenger_parent_dead"); >+} >+ >+static void scavenger_sig_term_handler(struct tevent_context *ev, >+ struct tevent_signal *se, >+ int signum, >+ int count, >+ void *siginfo, >+ void *private_data) >+{ >+ exit_server_cleanly("termination signal"); >+} >+ >+static void scavenger_setup_sig_term_handler(struct tevent_context *ev_ctx) >+{ >+ struct tevent_signal *se; >+ >+ se = tevent_add_signal(ev_ctx, >+ ev_ctx, >+ SIGTERM, 0, >+ scavenger_sig_term_handler, >+ NULL); >+ if (se == NULL) { >+ exit_server("failed to setup SIGTERM handler"); >+ } >+} >+ >+static bool smbd_scavenger_running(struct smbd_scavenger_state *state) >+{ >+ if (state->scavenger_id == NULL) { >+ return false; >+ } >+ >+ return serverid_exists(state->scavenger_id); >+} >+ >+static int smbd_scavenger_server_id_destructor(struct server_id *id) >+{ >+ serverid_deregister(*id); >+ return 0; >+} >+ >+static bool scavenger_say_hello(int fd, struct server_id self) >+{ >+ const uint8_t *msg = (const uint8_t *)&self; >+ size_t remaining = sizeof(self); >+ size_t ofs = 0; >+ >+ while (remaining > 0) { >+ ssize_t ret; >+ >+ ret = sys_write(fd, msg + ofs, remaining); >+ if (ret == -1) { >+ DEBUG(2, ("Failed to write to pipe: %s\n", >+ strerror(errno))); >+ return false; >+ } >+ remaining -= ret; >+ } >+ >+ DEBUG(4, ("scavenger_say_hello: self[%s]\n", >+ server_id_str(talloc_tos(), &self))); >+ return true; >+} >+ >+static bool scavenger_wait_hello(int fd, struct server_id *child) >+{ >+ uint8_t *msg = (uint8_t *)child; >+ size_t remaining = sizeof(*child); >+ size_t ofs = 0; >+ >+ while (remaining > 0) { >+ ssize_t ret; >+ >+ ret = sys_read(fd, msg + ofs, remaining); >+ if (ret == -1) { >+ DEBUG(2, ("Failed to read from pipe: %s\n", >+ strerror(errno))); >+ return false; >+ } >+ remaining -= ret; >+ } >+ >+ DEBUG(4, ("scavenger_say_hello: child[%s]\n", >+ server_id_str(talloc_tos(), child))); >+ return true; >+} >+ >+static bool smbd_scavenger_start(struct smbd_scavenger_state *state) >+{ >+ struct server_id self = messaging_server_id(state->msg); >+ struct tevent_fd *fde = NULL; >+ int fds[2]; >+ int ret; >+ uint64_t unique_id; >+ bool ok; >+ >+ SMB_ASSERT(server_id_equal(&state->parent_id, &self)); >+ >+ if (smbd_scavenger_running(state)) { >+ DEBUG(10, ("scavenger %s already running\n", >+ server_id_str(talloc_tos(), >+ state->scavenger_id))); >+ return true; >+ } >+ >+ if (state->scavenger_id != NULL) { >+ DEBUG(10, ("scavenger zombie %s, cleaning up\n", >+ server_id_str(talloc_tos(), >+ state->scavenger_id))); >+ TALLOC_FREE(state->scavenger_id); >+ } >+ >+ state->scavenger_id = talloc_zero(state, struct server_id); >+ if (state->scavenger_id == NULL) { >+ DEBUG(2, ("Out of memory\n")); >+ goto fail; >+ } >+ talloc_set_destructor(state->scavenger_id, >+ smbd_scavenger_server_id_destructor); >+ >+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); >+ if (ret == -1) { >+ DEBUG(2, ("socketpair failed: %s", strerror(errno))); >+ goto fail; >+ } >+ >+ smb_set_close_on_exec(fds[0]); >+ smb_set_close_on_exec(fds[1]); >+ >+ unique_id = serverid_get_random_unique_id(); >+ >+ ret = fork(); >+ if (ret == -1) { >+ int err = errno; >+ close(fds[0]); >+ close(fds[1]); >+ DEBUG(0, ("fork failed: %s", strerror(err))); >+ goto fail; >+ } >+ >+ if (ret == 0) { >+ /* child */ >+ >+ NTSTATUS status; >+ >+ close(fds[0]); >+ >+ am_parent = NULL; >+ >+ set_my_unique_id(unique_id); >+ >+ status = reinit_after_fork(state->msg, state->ev, true); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(2, ("reinit_after_fork failed: %s\n", >+ nt_errstr(status))); >+ exit_server("reinit_after_fork failed"); >+ return false; >+ } >+ >+ prctl_set_comment("smbd-scavenger"); >+ >+ state->am_scavenger = true; >+ *state->scavenger_id = messaging_server_id(state->msg); >+ >+ scavenger_setup_sig_term_handler(state->ev); >+ >+ serverid_register(*state->scavenger_id, FLAG_MSG_GENERAL); >+ >+ ok = scavenger_say_hello(fds[1], *state->scavenger_id); >+ if (!ok) { >+ DEBUG(2, ("scavenger_say_hello failed\n")); >+ exit_server("scavenger_say_hello failed"); >+ return false; >+ } >+ >+ fde = tevent_add_fd(state->ev, state->scavenger_id, >+ fds[1], TEVENT_FD_READ, >+ smbd_scavenger_parent_dead, state); >+ if (fde == NULL) { >+ DEBUG(2, ("tevent_add_fd(smbd_scavenger_parent_dead) " >+ "failed\n")); >+ exit_server("tevent_add_fd(smbd_scavenger_parent_dead) " >+ "failed"); >+ return false; >+ } >+ tevent_fd_set_auto_close(fde); >+ >+ ret = smbd_scavenger_main(state); >+ >+ DEBUG(10, ("scavenger ended: %d\n", ret)); >+ exit_server_cleanly("scavenger ended"); >+ return false; >+ } >+ >+ /* parent */ >+ close(fds[1]); >+ >+ ok = scavenger_wait_hello(fds[0], state->scavenger_id); >+ if (!ok) { >+ close(fds[0]); >+ goto fail; >+ } >+ >+ fde = tevent_add_fd(state->ev, state->scavenger_id, >+ fds[0], TEVENT_FD_READ, >+ smbd_scavenger_done, state); >+ if (fde == NULL) { >+ close(fds[0]); >+ goto fail; >+ } >+ tevent_fd_set_auto_close(fde); >+ >+ return true; >+fail: >+ TALLOC_FREE(state->scavenger_id); >+ return false; >+} >+ >+static void scavenger_add_timer(struct smbd_scavenger_state *state, >+ struct scavenger_message *msg); >+ >+static void smbd_scavenger_msg(struct messaging_context *msg_ctx, >+ void *private_data, >+ uint32_t msg_type, >+ struct server_id src, >+ DATA_BLOB *data) >+{ >+ struct smbd_scavenger_state *state = >+ talloc_get_type_abort(private_data, >+ struct smbd_scavenger_state); >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct server_id self = messaging_server_id(msg_ctx); >+ struct scavenger_message *msg = NULL; >+ >+ DEBUG(10, ("smbd_scavenger_msg: %s got message from %s\n", >+ server_id_str(talloc_tos(), &self), >+ server_id_str(talloc_tos(), &src))); >+ >+ if (server_id_equal(&state->parent_id, &self)) { >+ NTSTATUS status; >+ >+ if (!smbd_scavenger_running(state) && >+ !smbd_scavenger_start(state)) >+ { >+ DEBUG(2, ("Failed to start scavenger\n")); >+ goto done; >+ } >+ DEBUG(10, ("forwarding message to scavenger\n")); >+ >+ status = messaging_send(msg_ctx, >+ *state->scavenger_id, msg_type, data); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(2, ("forwarding message to scavenger failed: " >+ "%s\n", nt_errstr(status))); >+ goto done; >+ } >+ goto done; >+ } >+ >+ if (!state->am_scavenger) { >+ DEBUG(10, ("im not the scavenger: ignore message\n")); >+ goto done; >+ } >+ >+ if (!server_id_equal(&state->parent_id, &src)) { >+ DEBUG(10, ("scavenger: ignore spurious message\n")); >+ goto done; >+ } >+ >+ DEBUG(10, ("scavenger: got a message\n")); >+ msg = (struct scavenger_message*)data->data; >+ scavenger_add_timer(state, msg); >+done: >+ talloc_free(frame); >+} >+ >+bool smbd_scavenger_init(TALLOC_CTX *mem_ctx, >+ struct messaging_context *msg, >+ struct tevent_context *ev) >+{ >+ struct smbd_scavenger_state *state; >+ NTSTATUS status; >+ >+ if (smbd_scavenger_state) { >+ DEBUG(10, ("smbd_scavenger_init called again\n")); >+ return true; >+ } >+ >+ state = talloc_zero(mem_ctx, struct smbd_scavenger_state); >+ if (state == NULL) { >+ DEBUG(2, ("Out of memory\n")); >+ return false; >+ } >+ >+ state->msg = msg; >+ state->ev = ev; >+ state->parent_id = messaging_server_id(msg); >+ >+ status = messaging_register(msg, state, MSG_SMB_SCAVENGER, >+ smbd_scavenger_msg); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(2, ("failed to register message handler: %s\n", >+ nt_errstr(status))); >+ goto fail; >+ } >+ >+ smbd_scavenger_state = state; >+ return true; >+fail: >+ talloc_free(state); >+ return false; >+} >+ >+void scavenger_schedule_disconnected(struct files_struct *fsp) >+{ >+ NTSTATUS status; >+ struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx); >+ struct timeval disconnect_time, until; >+ uint64_t timeout_usec; >+ struct scavenger_message msg; >+ DATA_BLOB msg_blob; >+ >+ nttime_to_timeval(&disconnect_time, fsp->op->global->disconnect_time); >+ timeout_usec = 1000 * fsp->op->global->durable_timeout_msec; >+ until = timeval_add(&disconnect_time, >+ timeout_usec / 1000000, >+ timeout_usec % 1000000); >+ >+ ZERO_STRUCT(msg); >+ msg.file_id = fsp->file_id; >+ msg.open_persistent_id = fsp->op->global->open_persistent_id; >+ msg.until = timeval_to_nttime(&until); >+ >+ DEBUG(10, ("smbd: %s mark file %s as disconnected at %s with timeout " >+ "at %s in %fs\n", >+ server_id_str(talloc_tos(), &self), >+ file_id_string_tos(&fsp->file_id), >+ timeval_string(talloc_tos(), &disconnect_time, true), >+ timeval_string(talloc_tos(), &until, true), >+ fsp->op->global->durable_timeout_msec/1000.0)); >+ >+ SMB_ASSERT(server_id_is_disconnected(&fsp->op->global->server_id)); >+ SMB_ASSERT(!server_id_equal(&self, &smbd_scavenger_state->parent_id)); >+ SMB_ASSERT(!smbd_scavenger_state->am_scavenger); >+ >+ msg_blob = data_blob_const(&msg, sizeof(msg)); >+ DEBUG(10, ("send message to scavenger\n")); >+ >+ status = messaging_send(smbd_scavenger_state->msg, >+ smbd_scavenger_state->parent_id, >+ MSG_SMB_SCAVENGER, >+ &msg_blob); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(2, ("Failed to send message to parent smbd %s " >+ "from %s: %s\n", >+ server_id_str(talloc_tos(), >+ &smbd_scavenger_state->parent_id), >+ server_id_str(talloc_tos(), &self), >+ nt_errstr(status))); >+ } >+} >+ >+struct scavenger_timer_context { >+ struct smbd_scavenger_state *state; >+ struct scavenger_message msg; >+}; >+ >+static void scavenger_timer(struct tevent_context *ev, >+ struct tevent_timer *te, >+ struct timeval t, void *data) >+{ >+ struct scavenger_timer_context *ctx = >+ talloc_get_type_abort(data, struct scavenger_timer_context); >+ NTSTATUS status; >+ bool ok; >+ >+ DEBUG(10, ("scavenger: do cleanup for file %s at %s\n", >+ file_id_string_tos(&ctx->msg.file_id), >+ timeval_string(talloc_tos(), &t, true))); >+ >+ ok = share_mode_cleanup_disconnected(ctx->msg.file_id, >+ ctx->msg.open_persistent_id); >+ if (!ok) { >+ DEBUG(2, ("Failed to cleanup share modes and byte range locks " >+ "for file %s open %lu\n", >+ file_id_string_tos(&ctx->msg.file_id), >+ ctx->msg.open_persistent_id)); >+ } >+ >+ status = smbXsrv_open_cleanup(ctx->msg.open_persistent_id); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(2, ("Failed to cleanup open global for file %s open %lu:" >+ " %s\n", file_id_string_tos(&ctx->msg.file_id), >+ ctx->msg.open_persistent_id, nt_errstr(status))); >+ } >+} >+ >+static void scavenger_add_timer(struct smbd_scavenger_state *state, >+ struct scavenger_message *msg) >+{ >+ struct tevent_timer *te; >+ struct scavenger_timer_context *ctx; >+ struct timeval until; >+ >+ nttime_to_timeval(&until, msg->until); >+ >+ DEBUG(10, ("scavenger: schedule file %s for cleanup at %s\n", >+ file_id_string_tos(&msg->file_id), >+ timeval_string(talloc_tos(), &until, true))); >+ >+ ctx = talloc_zero(state, struct scavenger_timer_context); >+ if (ctx == NULL) { >+ DEBUG(2, ("Failed to talloc_zero(scavenger_timer_context)\n")); >+ return; >+ } >+ >+ ctx->state = state; >+ ctx->msg = *msg; >+ >+ te = tevent_add_timer(state->ev, >+ state, >+ until, >+ scavenger_timer, >+ ctx); >+ if (te == NULL) { >+ DEBUG(2, ("Failed to add scavenger_timer event\n")); >+ talloc_free(ctx); >+ return; >+ } >+ >+ /* delete context after handler was running */ >+ talloc_steal(te, ctx); >+} >diff --git a/source3/smbd/scavenger.h b/source3/smbd/scavenger.h >new file mode 100644 >index 0000000..966c80d >--- /dev/null >+++ b/source3/smbd/scavenger.h >@@ -0,0 +1,31 @@ >+/* >+ Unix SMB/CIFS implementation. >+ smbd scavenger daemon >+ >+ Copyright (C) Gregor Beck 2013 >+ >+ 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 _SCAVENGER_H_ >+#define _SCAVENGER_H_ >+ >+ >+bool smbd_scavenger_init(TALLOC_CTX *mem_ctx, >+ struct messaging_context *msg, >+ struct tevent_context *ev); >+ >+void scavenger_schedule_disconnected(struct files_struct *fsp); >+ >+#endif >diff --git a/source3/smbd/server.c b/source3/smbd/server.c >index 7113eae..e9bf9c9 100644 >--- a/source3/smbd/server.c >+++ b/source3/smbd/server.c >@@ -45,6 +45,7 @@ > #include "lib/conn_tdb.h" > #include "../lib/util/pidfile.h" > #include "lib/smbd_shim.h" >+#include "scavenger.h" > > struct smbd_open_socket; > struct smbd_child_pid; >@@ -1419,6 +1420,10 @@ extern void build_options(bool screen); > exit(1); > } > >+ if (!smbd_scavenger_init(NULL, msg_ctx, ev_ctx)) { >+ exit(1); >+ } >+ > if (!serverid_parent_init(ev_ctx)) { > exit(1); > } >diff --git a/source3/wscript_build b/source3/wscript_build >index 02040bf..e4498fd 100755 >--- a/source3/wscript_build >+++ b/source3/wscript_build >@@ -382,6 +382,7 @@ SMBD_SRC_SRV = '''smbd/server_reload.c smbd/files.c smbd/connection.c > smbd/smbXsrv_open.c > smbd/server_exit.c > smbd/durable.c >+ smbd/scavenger.c > ${MANGLE_SRC}''' > > SMBD_SRC_BASE = '''${SMBD_SRC_SRV} >-- >1.7.9.5 > > >From b2235e6b90a0856712da016b32090e80a61ce9ed Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 13 Feb 2013 08:26:43 -0500 >Subject: [PATCH 07/10] s3:smbd: use smbXsrv_open_close() instead of > smbXsrv_open_update() > >This makes sure we store the correct disconnect_time for disconnected >durable handles. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit f0e6a9be00e441e50f0087c543e1b7c9012d126f) >--- > source3/smbd/close.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > >diff --git a/source3/smbd/close.c b/source3/smbd/close.c >index 9b988e0..9e7ccc7 100644 >--- a/source3/smbd/close.c >+++ b/source3/smbd/close.c >@@ -769,10 +769,20 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, > fsp->op, > &new_cookie); > if (NT_STATUS_IS_OK(tmp)) { >+ struct timeval tv; >+ NTTIME now; >+ >+ if (req != NULL) { >+ tv = req->request_time; >+ } else { >+ tv = timeval_current(); >+ } >+ now = timeval_to_nttime(&tv); >+ > data_blob_free(&fsp->op->global->backend_cookie); > fsp->op->global->backend_cookie = new_cookie; > >- tmp = smbXsrv_open_update(fsp->op); >+ tmp = smbXsrv_open_close(fsp->op, now); > } > if (!NT_STATUS_IS_OK(tmp)) { > is_durable = false; >-- >1.7.9.5 > > >From afa52e7ef88741d14969b5733e4a88d1a19cd73d Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Tue, 12 Feb 2013 17:44:51 +0100 >Subject: [PATCH 08/10] s3:smbd: add debugging to close code (regarding > disconnect of a durable) > >Signed-off-by: Michael Adam <obnox@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Mon Feb 18 17:42:45 CET 2013 on sn-devel-104 >(cherry picked from commit cfebce3c56474ac914474b57ed94f93418b0564b) >--- > source3/smbd/close.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > >diff --git a/source3/smbd/close.c b/source3/smbd/close.c >index 9e7ccc7..df3ae23 100644 >--- a/source3/smbd/close.c >+++ b/source3/smbd/close.c >@@ -783,6 +783,17 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, > fsp->op->global->backend_cookie = new_cookie; > > tmp = smbXsrv_open_close(fsp->op, now); >+ if (!NT_STATUS_IS_OK(tmp)) { >+ DEBUG(1, ("Failed to update smbXsrv_open " >+ "record when disconnecting durable " >+ "handle for file %s: %s - " >+ "proceeding with normal close\n", >+ fsp_str_dbg(fsp), nt_errstr(tmp))); >+ } >+ } else { >+ DEBUG(1, ("Failed to disconnect durable handle for " >+ "file %s: %s - proceeding with normal " >+ "close\n", fsp_str_dbg(fsp), nt_errstr(tmp))); > } > if (!NT_STATUS_IS_OK(tmp)) { > is_durable = false; >@@ -795,6 +806,9 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, > * a durable handle and closed the underlying file. > * In all other cases, we proceed with a genuine close. > */ >+ DEBUG(10, ("%s disconnected durable handle for file %s\n", >+ conn->session_info->unix_info->unix_name, >+ fsp_str_dbg(fsp))); > file_free(req, fsp); > return NT_STATUS_OK; > } >-- >1.7.9.5 > > >From 88fa2ffbc77c258f635cfce22fce66be8bffee3b Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Mon, 18 Feb 2013 23:21:24 +0100 >Subject: [PATCH 09/10] s3:smbd:smb2: fix segfault (access after free) in > durable disconnect code > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Michael Adam <obnox@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Michael Adam <obnox@samba.org> >Autobuild-Date(master): Tue Feb 19 11:12:01 CET 2013 on sn-devel-104 >(cherry picked from commit bdb80aeb11d5458e281483a5cdc57f5481979cc9) >--- > source3/smbd/close.c | 1 + > source3/smbd/smbXsrv_open.c | 1 + > 2 files changed, 2 insertions(+) > >diff --git a/source3/smbd/close.c b/source3/smbd/close.c >index df3ae23..d0c843e 100644 >--- a/source3/smbd/close.c >+++ b/source3/smbd/close.c >@@ -782,6 +782,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, > data_blob_free(&fsp->op->global->backend_cookie); > fsp->op->global->backend_cookie = new_cookie; > >+ fsp->op->compat = NULL; > tmp = smbXsrv_open_close(fsp->op, now); > if (!NT_STATUS_IS_OK(tmp)) { > DEBUG(1, ("Failed to update smbXsrv_open " >diff --git a/source3/smbd/smbXsrv_open.c b/source3/smbd/smbXsrv_open.c >index a0352c7..27dd50c 100644 >--- a/source3/smbd/smbXsrv_open.c >+++ b/source3/smbd/smbXsrv_open.c >@@ -1078,6 +1078,7 @@ NTSTATUS smbXsrv_open_close(struct smbXsrv_open *op, NTTIME now) > op->db_rec = NULL; > > if (op->compat) { >+ op->compat->op = NULL; > file_free(NULL, op->compat); > op->compat = NULL; > } >-- >1.7.9.5 > > >From 3173f2d4c3fe516ea3e7df04073e1289f00a12c0 Mon Sep 17 00:00:00 2001 >From: Gregor Beck <gbeck@sernet.de> >Date: Wed, 20 Mar 2013 10:01:43 +0100 >Subject: [PATCH 10/10] s3:smbd: call scavenger_schedule_disconnected() from > close normal file for durable handles > >Signed-off-by: Gregor Beck <gbeck@sernet.de> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit c2ef5182e32fafeb3e279d9fc3a2a409e4aa0543) >--- > source3/smbd/close.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/source3/smbd/close.c b/source3/smbd/close.c >index d0c843e..5dddf45 100644 >--- a/source3/smbd/close.c >+++ b/source3/smbd/close.c >@@ -24,6 +24,7 @@ > #include "printing.h" > #include "smbd/smbd.h" > #include "smbd/globals.h" >+#include "smbd/scavenger.h" > #include "fake_file.h" > #include "transfer_file.h" > #include "auth.h" >@@ -791,6 +792,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, > "proceeding with normal close\n", > fsp_str_dbg(fsp), nt_errstr(tmp))); > } >+ scavenger_schedule_disconnected(fsp); > } else { > DEBUG(1, ("Failed to disconnect durable handle for " > "file %s: %s - proceeding with normal " >-- >1.7.9.5 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 9930
:
8944
|
8995
|
8999