[SCM] Samba Shared Repository - branch v4-19-stable updated
Jule Anger
janger at samba.org
Thu Oct 17 12:04:43 UTC 2024
The branch, v4-19-stable has been updated
via 7eabe40bfe5 VERSION: Disable GIT_SNAPSHOT for the 4.19.9 release.
via 4059e00109b WHATSNEW: Add release notes for Samba 4.19.9.
via 8d4a277d258 BUG 15590 ldb: Release LDB 2.8.2
via 5a15cbb15da ldb:kv_index: help static analysers to not worry (CID 1615192)
via 9b33893987d ldb:kv_index: realloc away old dn list
via 9a617692d29 ldb_kv_index: dn_list load sub transaction can re-use keys
via 13cfe36b618 s4:lib/messaging: fix interaction between imessaging_reinit and irpc_destructor
via 335ce71c636 smbd: remove just created sharemode entry in the error codepaths
via 92d7e6c6339 smbd: consolidate DH reconnect failure code
via 153f9027c96 s3:tests: let test_durable_handle_reconnect.sh run smb2.durable-v2-regressions.durable_v2_reconnect_bug15624
via 5f3f8835282 s4:torture/smb2: add smb2.durable-v2-regressions.durable_v2_reconnect_bug15624
via b0fb5a1d39a vfs_error_inject: add 'error_inject:durable_reconnect = st_ex_nlink'
via 3e6d740bf3e smbd: add option "smbd:debug events" for tevent handling duration threshold warnings
via 38242b55d93 smbd: move trace_state variable behind tv variable
via 2c8dfff7d9e smbd: add option "smbd lease break:debug hung procs"
via 71568683ca7 smbd: log share_mode_watch_recv() errors as errors
via b5388c25b88 s3/lib: add option "serverid watch:debug script"
via b365e1068e4 s3/lib: add option "serverid watch:debug = yes" to print kernel stack of hanging process
via 796d026919f s3/lib: add next helper variable in server_id_watch_*
via 1602d847354 smb2_ioctl: fix truncated FSCTL_QUERY_ALLOCATED_RANGES responses
via 3455944ce0a s4:torture/smb2: test FSCTL_QUERY_ALLOCATED_RANGES truncation
via a92076d88bf s3:smbd: fix NULL dereference in case of readlink failure
via 2d944eb04ad s3:smb2_server: return NT_STATUS_NETWORK_SESSION_EXPIRED for compound requests
via 3db88bd0527 s4:torture/smb2: let smb2.session.expire2* also check compound requests
via 9d57d32bba0 VERSION: Bump version up to Samba 4.19.9...
from 204b0f2d2f7 VERSION: Disable GIT_SNAPSHOT for the 4.19.8 release.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-19-stable
- Log -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
VERSION | 2 +-
WHATSNEW.txt | 59 +++++++-
lib/ldb/ABI/{ldb-2.8.0.sigs => ldb-2.8.2.sigs} | 0
...pyldb-util-2.1.0.sigs => pyldb-util-2.8.2.sigs} | 0
lib/ldb/ldb_key_value/ldb_kv_index.c | 100 ++++++++------
lib/ldb/wscript | 2 +-
selftest/skip | 1 +
source3/lib/server_id_watch.c | 128 +++++++++++++++++-
source3/modules/vfs_error_inject.c | 76 +++++++++++
.../script/tests/test_durable_handle_reconnect.sh | 18 +++
source3/smbd/durable.c | 150 ++++++++-------------
source3/smbd/open.c | 119 ++++++++++++++--
source3/smbd/smb2_ioctl.c | 4 +-
source3/smbd/smb2_ioctl_filesys.c | 54 +++++---
source3/smbd/smb2_process.c | 72 +++++++++-
source3/smbd/smb2_server.c | 16 ++-
source4/lib/messaging/messaging.c | 9 ++
source4/libcli/smb2/ioctl.c | 3 +-
source4/torture/smb2/durable_v2_open.c | 118 ++++++++++++++++
source4/torture/smb2/ioctl.c | 149 +++++++++++++++++++-
source4/torture/smb2/session.c | 56 ++++++++
source4/torture/smb2/smb2.c | 2 +
22 files changed, 954 insertions(+), 184 deletions(-)
copy lib/ldb/ABI/{ldb-2.8.0.sigs => ldb-2.8.2.sigs} (100%)
copy lib/ldb/ABI/{pyldb-util-2.1.0.sigs => pyldb-util-2.8.2.sigs} (100%)
Changeset truncated at 500 lines:
diff --git a/VERSION b/VERSION
index 89a60174790..5a12a805f5b 100644
--- a/VERSION
+++ b/VERSION
@@ -27,7 +27,7 @@ SAMBA_COPYRIGHT_STRING="Copyright Andrew Tridgell and the Samba Team 1992-2023"
########################################################
SAMBA_VERSION_MAJOR=4
SAMBA_VERSION_MINOR=19
-SAMBA_VERSION_RELEASE=8
+SAMBA_VERSION_RELEASE=9
########################################################
# If a official release has a serious bug #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 43b8cafa119..7747fe33732 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,59 @@
+ ==============================
+ Release Notes for Samba 4.19.9
+ October 17, 2024
+ ==============================
+
+
+This is the latest stable release of the Samba 4.19 release series.
+
+
+Changes since 4.19.8
+--------------------
+
+o Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
+ * BUG 15590: libldb: performance issue with indexes (ldb 2.8.2 is already
+ released).
+
+o Ralph Boehme <slow at samba.org>
+ * BUG 15624: DH reconnect error handling can lead to stale sharemode entries.
+
+o David Disseldorp <ddiss at samba.org>
+ * BUG 15699: Incorrect FSCTL_QUERY_ALLOCATED_RANGES response when truncated.
+
+o Stefan Metzmacher <metze at samba.org>
+ * BUG 15280: irpc_destructor may crash during shutdown.
+ * BUG 15624: DH reconnect error handling can lead to stale sharemode entries.
+ * BUG 15696: Compound SMB2 requests don't return
+ NT_STATUS_NETWORK_SESSION_EXPIRED for all requests, confuses
+ MacOSX clients.
+
+o Shachar Sharon <ssharon at redhat.com>
+ * BUG 15700: Crash when readlinkat fails.
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical:matrix.org matrix room, or
+#samba-technical IRC channel on irc.libera.chat.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored. All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
==============================
Release Notes for Samba 4.19.8
August 15, 2024
@@ -97,8 +153,7 @@ database (https://bugzilla.samba.org/).
======================================================================
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
==============================
Release Notes for Samba 4.19.7
June 10, 2024
diff --git a/lib/ldb/ABI/ldb-2.8.0.sigs b/lib/ldb/ABI/ldb-2.8.2.sigs
similarity index 100%
copy from lib/ldb/ABI/ldb-2.8.0.sigs
copy to lib/ldb/ABI/ldb-2.8.2.sigs
diff --git a/lib/ldb/ABI/pyldb-util-2.1.0.sigs b/lib/ldb/ABI/pyldb-util-2.8.2.sigs
similarity index 100%
copy from lib/ldb/ABI/pyldb-util-2.1.0.sigs
copy to lib/ldb/ABI/pyldb-util-2.8.2.sigs
diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c
index bcbd903f6fb..902fb9b69f2 100644
--- a/lib/ldb/ldb_key_value/ldb_kv_index.c
+++ b/lib/ldb/ldb_key_value/ldb_kv_index.c
@@ -446,34 +446,39 @@ static int ldb_kv_dn_list_load(struct ldb_module *module,
* There is an active index sub transaction, and the record was
* found in the primary index transaction cache. A copy of the
* record needs be taken to prevent the original entry being
- * altered, until the index sub transaction is committed.
+ * altered, until the index sub transaction is committed, but we
+ * don't copy the actual values, just the array of struct ldb_val
+ * that points to the values (which are offsets into a GUID array).
+ *
+ * As a reminder, our primary cache is an in-memory tdb that
+ * maps attributes to struct dn_list objects, which point to
+ * the actual index, which is an array of struct ldb_val, the
+ * contents of which are {.data = <binary GUID>, .length =
+ * 16}. The array is sorted by GUID data, and these GUIDs are
+ * used to look up index entries in the main database. There
+ * are more layers of indirection than necessary, but what
+ * makes the index useful is we can use a binary search to
+ * find if the array contains a GUID.
+ *
+ * What we do in a sub-transaction is make a copy of the struct
+ * dn_list and the array of struct ldb_val, but *not* of the
+ * .data that they point to. This copy is put into a new
+ * in-memory tdb which masks the primary cache for the duration
+ * of the sub-transaction.
+ *
+ * In an add operation in a sub-transaction, the new ldb_val
+ * is a child of the sub-transaction dn_list, which will
+ * become the main dn_list if the transaction succeeds.
+ *
+ * These acrobatics do not affect read-only operations.
*/
-
- {
- struct ldb_val *dns = NULL;
- size_t x = 0;
-
- dns = talloc_array(
- list,
- struct ldb_val,
- list2->count);
- if (dns == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- for (x = 0; x < list2->count; x++) {
- dns[x].length = list2->dn[x].length;
- dns[x].data = talloc_memdup(
- dns,
- list2->dn[x].data,
- list2->dn[x].length);
- if (dns[x].data == NULL) {
- TALLOC_FREE(dns);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
- list->dn = dns;
- list->count = list2->count;
+ list->dn = talloc_memdup(list,
+ list2->dn,
+ talloc_get_size(list2->dn));
+ if (list->dn == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
+ list->count = list2->count;
return LDB_SUCCESS;
/*
@@ -3852,9 +3857,7 @@ int ldb_kv_reindex(struct ldb_module *module)
* Copy the contents of the nested transaction index cache record to the
* transaction index cache.
*
- * During this 'commit' of the subtransaction to the main transaction
- * (cache), care must be taken to free any existing index at the top
- * level because otherwise we would leak memory.
+ * This is a 'commit' of the subtransaction to the main transaction cache.
*/
static int ldb_kv_sub_transaction_traverse(
struct tdb_context *tdb,
@@ -3883,8 +3886,7 @@ static int ldb_kv_sub_transaction_traverse(
/*
* Do we already have an entry in the primary transaction cache
- * If so free it's dn_list and replace it with the dn_list from
- * the secondary cache
+ * If so replace dn_list with the one from the subtransaction.
*
* The TDB and so the fetched rec contains NO DATA, just a
* pointer to data held in memory.
@@ -3897,21 +3899,41 @@ static int ldb_kv_sub_transaction_traverse(
abort();
}
/*
- * We had this key at the top level. However we made a copy
- * at the sub-transaction level so that we could possibly
- * roll back. We have to free the top level index memory
- * otherwise we would leak
+ * We had this key at the top level, and made a copy
+ * of the dn list for this sub-transaction level that
+ * borrowed the top level GUID data. We can't free the
+ * original dn list just yet.
+ *
+ * In this diagram, ... is the C pointer structure
+ * and --- is the talloc structure (::: is both).
+ *
+ * index_in_top_level ::: dn orig ..............
+ * | | :
+ * | `--GUID array :
+ * | |----- val1 data
+ * ldb_kv `----- val2 data
+ * | :
+ * index_in_subtransaction :: dn copy ..........:
+ * | :
+ * `------------ new val3 data
+ *
+ * So we don't free the index_in_top_level dn list yet,
+ * because we are (probably) borrowing most of its
+ * children. But we can save memory by discarding the
+ * values and keeping it as an almost empty talloc
+ * node.
*/
- if (index_in_top_level->count > 0) {
- TALLOC_FREE(index_in_top_level->dn);
- }
+ talloc_realloc(index_in_top_level,
+ index_in_top_level->dn, struct ldb_val, 1);
index_in_top_level->dn
= talloc_steal(index_in_top_level,
index_in_subtransaction->dn);
index_in_top_level->count = index_in_subtransaction->count;
return 0;
}
-
+ /*
+ * We found no top level index in the cache, so we put one in.
+ */
index_in_top_level = talloc(ldb_kv->idxptr, struct dn_list);
if (index_in_top_level == NULL) {
ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR;
diff --git a/lib/ldb/wscript b/lib/ldb/wscript
index 604294eeba9..0e53d4f2952 100644
--- a/lib/ldb/wscript
+++ b/lib/ldb/wscript
@@ -2,7 +2,7 @@
APPNAME = 'ldb'
# For Samba 4.19.x !
-VERSION = '2.8.1'
+VERSION = '2.8.2'
import sys, os
diff --git a/selftest/skip b/selftest/skip
index e808367c00d..056c54ea287 100644
--- a/selftest/skip
+++ b/selftest/skip
@@ -149,3 +149,4 @@ bench # don't run benchmarks in our selftest
^samba.tests.reparsepoints.*
^samba.tests.smb2symlink.*
^samba3.blackbox.open-eintr.*
+smb2.durable-v2-regressions # Only used in blackbox tests
diff --git a/source3/lib/server_id_watch.c b/source3/lib/server_id_watch.c
index f0189e0e896..8ddf9c6b1c8 100644
--- a/source3/lib/server_id_watch.c
+++ b/source3/lib/server_id_watch.c
@@ -17,16 +17,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "replace.h"
-#include <tevent.h>
-#include <talloc.h>
+#include "includes.h"
#include "serverid.h"
#include "server_id_watch.h"
+#include "lib/util/server_id.h"
#include "lib/util/tevent_unix.h"
struct server_id_watch_state {
struct tevent_context *ev;
struct server_id pid;
+ struct timeval start;
+ struct timeval warn;
+ bool debug;
};
static void server_id_watch_waited(struct tevent_req *subreq);
@@ -37,6 +39,7 @@ struct tevent_req *server_id_watch_send(TALLOC_CTX *mem_ctx,
{
struct tevent_req *req, *subreq;
struct server_id_watch_state *state;
+ struct timeval next;
req = tevent_req_create(mem_ctx, &state, struct server_id_watch_state);
if (req == NULL) {
@@ -44,14 +47,21 @@ struct tevent_req *server_id_watch_send(TALLOC_CTX *mem_ctx,
}
state->ev = ev;
state->pid = pid;
+ state->start = tevent_timeval_current();
+ state->warn = tevent_timeval_add(&state->start, 10, 0);
+
+ state->debug = lp_parm_bool(GLOBAL_SECTION_SNUM,
+ "serverid watch",
+ "debug",
+ CHECK_DEBUGLVL(DBGLVL_DEBUG));
if (!serverid_exists(&state->pid)) {
tevent_req_done(req);
return tevent_req_post(req, ev);
}
- subreq = tevent_wakeup_send(
- state, ev, tevent_timeval_current_ofs(0, 500000));
+ next = tevent_timeval_add(&state->start, 0, 500000);
+ subreq = tevent_wakeup_send(state, ev, next);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
@@ -66,6 +76,8 @@ static void server_id_watch_waited(struct tevent_req *subreq)
subreq, struct tevent_req);
struct server_id_watch_state *state = tevent_req_data(
req, struct server_id_watch_state);
+ struct timeval now;
+ struct timeval next;
bool ok;
ok = tevent_wakeup_recv(subreq);
@@ -80,8 +92,110 @@ static void server_id_watch_waited(struct tevent_req *subreq)
return;
}
- subreq = tevent_wakeup_send(
- state, state->ev, tevent_timeval_current_ofs(0, 500000));
+ now = tevent_timeval_current();
+
+ if (!state->debug) {
+ goto next;
+ }
+
+ if (timeval_compare(&state->warn, &now) == -1) {
+ double duration = timeval_elapsed2(&state->start, &now);
+ const char *cmd = NULL;
+ char proc_path[64] = { 0, };
+ char *kstack = NULL;
+ struct server_id_buf buf;
+ const char *pid = server_id_str_buf(state->pid, &buf);
+ int ret;
+
+ state->warn = tevent_timeval_add(&now, 10, 0);
+
+ cmd = lp_parm_const_string(GLOBAL_SECTION_SNUM,
+ "serverid watch",
+ "debug script",
+ NULL);
+ if (cmd != NULL) {
+ char *cmdstr = NULL;
+ char *output = NULL;
+ int fd;
+
+ /*
+ * Note in a cluster setup pid will be
+ * a NOTE:PID like '1:3978365'
+ *
+ * Without clustering it is just '3978365'
+ */
+ cmdstr = talloc_asprintf(state, "%s %s", cmd, pid);
+ if (cmdstr == NULL) {
+ DBG_ERR("Process %s hanging for %f seconds?\n"
+ "talloc_asprintf failed\n",
+ pid, duration);
+ goto next;
+ }
+
+ become_root();
+ ret = smbrun(cmdstr, &fd, NULL);
+ unbecome_root();
+ if (ret != 0) {
+ DBG_ERR("Process %s hanging for %f seconds?\n"
+ "smbrun('%s') failed\n",
+ pid, duration, cmdstr);
+ TALLOC_FREE(cmdstr);
+ goto next;
+ }
+
+ output = fd_load(fd, NULL, 0, state);
+ close(fd);
+ if (output == NULL) {
+ DBG_ERR("Process %s hanging for %f seconds?\n"
+ "fd_load() of smbrun('%s') failed\n",
+ pid, duration, cmdstr);
+ TALLOC_FREE(cmdstr);
+ goto next;
+ }
+ DBG_ERR("Process %s hanging for %f seconds?\n"
+ "%s returned:\n%s",
+ pid, duration, cmdstr, output);
+ TALLOC_FREE(cmdstr);
+ TALLOC_FREE(output);
+ goto next;
+ }
+
+ if (!procid_is_local(&state->pid) || !sys_have_proc_fds()) {
+ DBG_ERR("Process %s hanging for %f seconds?\n",
+ pid, duration);
+ goto next;
+ }
+
+ ret = snprintf(proc_path,
+ ARRAY_SIZE(proc_path),
+ "/proc/%" PRIu64 "/stack",
+ state->pid.pid);
+ if (ret < 0) {
+ DBG_ERR("Process %s hanging for %f seconds?\n"
+ "snprintf failed\n",
+ pid, duration);
+ goto next;
+ }
+
+ become_root();
+ kstack = file_load(proc_path, NULL, 0, state);
+ unbecome_root();
+ if (kstack == NULL) {
+ DBG_ERR("Process %s hanging for %f seconds?\n"
+ "file_load [%s] failed\n",
+ pid, duration, proc_path);
+ goto next;
+ }
+
+ DBG_ERR("Process %s hanging for %f seconds?\n"
+ "%s:\n%s",
+ pid, duration, proc_path, kstack);
+ TALLOC_FREE(kstack);
+ }
+
+next:
+ next = tevent_timeval_add(&now, 0, 500000);
+ subreq = tevent_wakeup_send(state, state->ev, next);
if (tevent_req_nomem(subreq, req)) {
return;
}
diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c
index 529504fd8d5..dcf0de0a2d9 100644
--- a/source3/modules/vfs_error_inject.c
+++ b/source3/modules/vfs_error_inject.c
@@ -19,6 +19,7 @@
#include "includes.h"
#include "smbd/smbd.h"
+#include "librpc/gen_ndr/ndr_open_files.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
@@ -204,11 +205,86 @@ static int vfs_error_inject_unlinkat(struct vfs_handle_struct *handle,
return -1;
}
+static NTSTATUS vfs_error_inject_durable_reconnect(struct vfs_handle_struct *handle,
+ struct smb_request *smb1req,
+ struct smbXsrv_open *op,
+ const DATA_BLOB old_cookie,
+ TALLOC_CTX *mem_ctx,
+ struct files_struct **fsp,
+ DATA_BLOB *new_cookie)
+{
+ const char *vfs_func = "durable_reconnect";
+ const char *err_str = NULL;
+ NTSTATUS status;
+ enum ndr_err_code ndr_err;
+ struct vfs_default_durable_cookie cookie;
+ DATA_BLOB modified_cookie = data_blob_null;
+
+ err_str = lp_parm_const_string(SNUM(handle->conn),
+ "error_inject",
+ vfs_func,
+ NULL);
+ if (err_str == NULL) {
+ return SMB_VFS_NEXT_DURABLE_RECONNECT(handle,
+ smb1req,
+ op,
+ old_cookie,
+ mem_ctx,
+ fsp,
+ new_cookie);
+ }
+
+ ndr_err = ndr_pull_struct_blob(&old_cookie, talloc_tos(), &cookie,
+ (ndr_pull_flags_fn_t)ndr_pull_vfs_default_durable_cookie);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = ndr_map_error2ntstatus(ndr_err);
+ return status;
+ }
+
+ if (strcmp(cookie.magic, VFS_DEFAULT_DURABLE_COOKIE_MAGIC) != 0) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (cookie.version != VFS_DEFAULT_DURABLE_COOKIE_VERSION) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (strequal(err_str, "st_ex_nlink")) {
+ cookie.stat_info.st_ex_nlink += 1;
--
Samba Shared Repository
More information about the samba-cvs
mailing list