[PATCHSET] dbwrap, read only copies, lock order

Michael Adam obnox at samba.org
Thu Feb 6 03:27:38 MST 2014


Hi,

attached find a patchset to samba's dbwrap system.

The first part introduces a means to activate
read only copies for the ctdb dbwrap backend.
(These are like delegations/leases on db records.
 In a cluster, under certain cenarios, the use
 of these read only copies can reduce the record
 ping-pong and hence prevent performance drops).

This patchset then activates the read only
for the netlogon_creds_cli DB, recently introduced
by Metze.

The second part of the patches does some
cleanups and systematization to the lock-order
code.

This patchset is already reviewed, but we wanted
to give a chance to comment before pushing.

Cheers - Michael

-------------- next part --------------
From 26b62baa435fa734358289bf7e20dba96389e8fc Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 27 Jan 2014 13:38:51 +0100
Subject: [PATCH 01/21] dbwrap: add flags DBWRAP_FLAG_NONE

This is in preparation of adding a dbwrap_flags argument to db_open
and firends.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h
index 8bf3286..4064ba2 100644
--- a/lib/dbwrap/dbwrap.h
+++ b/lib/dbwrap/dbwrap.h
@@ -32,6 +32,8 @@ enum dbwrap_lock_order {
 };
 #define DBWRAP_LOCK_ORDER_MAX DBWRAP_LOCK_ORDER_3
 
+#define DBWRAP_FLAG_NONE                     0x0000000000000000ULL
+
 /* The following definitions come from lib/dbwrap.c  */
 
 TDB_DATA dbwrap_record_get_key(const struct db_record *rec);
-- 
1.8.3.2


From b5e1948cf25ee1852590501ca209af871d4097b5 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 27 Jan 2014 14:49:12 +0100
Subject: [PATCH 02/21] dbwrap: add a dbwrap_flags argument to db_open()

This is in preparation to support handing flags to backends,
in particular activating read only record support for ctdb
databases. For a start, this does nothing but adding the
parameter, and all databases use DBWRAP_FLAG_NONE.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/groupdb/mapping_tdb.c           | 2 +-
 source3/lib/dbwrap/dbwrap_open.c        | 3 ++-
 source3/lib/dbwrap/dbwrap_open.h        | 3 ++-
 source3/lib/dbwrap/dbwrap_watch.c       | 3 ++-
 source3/lib/g_lock.c                    | 3 ++-
 source3/lib/serverid.c                  | 3 ++-
 source3/lib/sharesec.c                  | 2 +-
 source3/locking/brlock.c                | 2 +-
 source3/locking/share_mode_lock.c       | 2 +-
 source3/modules/vfs_acl_tdb.c           | 2 +-
 source3/modules/vfs_xattr_tdb.c         | 2 +-
 source3/passdb/account_pol.c            | 4 ++--
 source3/passdb/pdb_tdb.c                | 6 +++---
 source3/passdb/secrets.c                | 2 +-
 source3/printing/printer_list.c         | 3 ++-
 source3/registry/reg_backend_db.c       | 6 +++---
 source3/rpc_client/cli_netlogon.c       | 3 ++-
 source3/smbd/notify_internal.c          | 2 +-
 source3/smbd/smbXsrv_open.c             | 3 ++-
 source3/smbd/smbXsrv_session.c          | 3 ++-
 source3/smbd/smbXsrv_tcon.c             | 3 ++-
 source3/smbd/smbXsrv_version.c          | 3 ++-
 source3/torture/test_dbwrap_watch.c     | 3 ++-
 source3/torture/test_idmap_tdb_common.c | 2 +-
 source3/torture/torture.c               | 3 ++-
 source3/utils/dbwrap_tool.c             | 2 +-
 source3/utils/dbwrap_torture.c          | 2 +-
 source3/utils/net_idmap.c               | 8 ++++----
 source3/utils/net_idmap_check.c         | 2 +-
 source3/utils/net_registry_check.c      | 4 ++--
 source3/utils/status.c                  | 2 +-
 source3/winbindd/idmap_autorid_tdb.c    | 2 +-
 source3/winbindd/idmap_tdb.c            | 2 +-
 source3/winbindd/idmap_tdb2.c           | 2 +-
 34 files changed, 56 insertions(+), 43 deletions(-)

diff --git a/source3/groupdb/mapping_tdb.c b/source3/groupdb/mapping_tdb.c
index 3cb1024..cc397d9 100644
--- a/source3/groupdb/mapping_tdb.c
+++ b/source3/groupdb/mapping_tdb.c
@@ -54,7 +54,7 @@ static bool init_group_mapping(void)
 
 	db = db_open(NULL, state_path("group_mapping.tdb"), 0,
 		     TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
-		     DBWRAP_LOCK_ORDER_1);
+		     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (db == NULL) {
 		DEBUG(0, ("Failed to open group mapping database: %s\n",
 			  strerror(errno)));
diff --git a/source3/lib/dbwrap/dbwrap_open.c b/source3/lib/dbwrap/dbwrap_open.c
index 515b4bf..6c9280c 100644
--- a/source3/lib/dbwrap/dbwrap_open.c
+++ b/source3/lib/dbwrap/dbwrap_open.c
@@ -60,7 +60,8 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
 			   const char *name,
 			   int hash_size, int tdb_flags,
 			   int open_flags, mode_t mode,
-			   enum dbwrap_lock_order lock_order)
+			   enum dbwrap_lock_order lock_order,
+			   uint64_t dbwrap_flags)
 {
 	struct db_context *result = NULL;
 #ifdef CLUSTER_SUPPORT
diff --git a/source3/lib/dbwrap/dbwrap_open.h b/source3/lib/dbwrap/dbwrap_open.h
index 51c7dfd..d14794e 100644
--- a/source3/lib/dbwrap/dbwrap_open.h
+++ b/source3/lib/dbwrap/dbwrap_open.h
@@ -39,6 +39,7 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
 			   const char *name,
 			   int hash_size, int tdb_flags,
 			   int open_flags, mode_t mode,
-			   enum dbwrap_lock_order lock_order);
+			   enum dbwrap_lock_order lock_order,
+			   uint64_t dbwrap_flags);
 
 #endif /* __DBWRAP_OPEN_H__ */
diff --git a/source3/lib/dbwrap/dbwrap_watch.c b/source3/lib/dbwrap/dbwrap_watch.c
index b586b66..ba4381e 100644
--- a/source3/lib/dbwrap/dbwrap_watch.c
+++ b/source3/lib/dbwrap/dbwrap_watch.c
@@ -33,7 +33,8 @@ static struct db_context *dbwrap_record_watchers_db(void)
 		watchers_db = db_open(
 			NULL, lock_path("dbwrap_watchers.tdb"),	0,
 			TDB_CLEAR_IF_FIRST | TDB_INCOMPATIBLE_HASH,
-			O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_3);
+			O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_3,
+			DBWRAP_FLAG_NONE);
 	}
 	return watchers_db;
 }
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c
index 8c7a6c2..6813f06 100644
--- a/source3/lib/g_lock.c
+++ b/source3/lib/g_lock.c
@@ -61,7 +61,8 @@ struct g_lock_ctx *g_lock_ctx_init(TALLOC_CTX *mem_ctx,
 	result->db = db_open(result, lock_path("g_lock.tdb"), 0,
 			     TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
 			     O_RDWR|O_CREAT, 0600,
-			     DBWRAP_LOCK_ORDER_2);
+			     DBWRAP_LOCK_ORDER_2,
+			     DBWRAP_FLAG_NONE);
 	if (result->db == NULL) {
 		DEBUG(1, ("g_lock_init: Could not open g_lock.tdb\n"));
 		TALLOC_FREE(result);
diff --git a/source3/lib/serverid.c b/source3/lib/serverid.c
index cb49520..4259887 100644
--- a/source3/lib/serverid.c
+++ b/source3/lib/serverid.c
@@ -77,7 +77,8 @@ static struct db_context *serverid_db(void)
 	}
 	db = db_open(NULL, lock_path("serverid.tdb"), 0,
 		     TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
-		     O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_2);
+		     O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_2,
+		     DBWRAP_FLAG_NONE);
 	return db;
 }
 
diff --git a/source3/lib/sharesec.c b/source3/lib/sharesec.c
index c7a8e51..095c851 100644
--- a/source3/lib/sharesec.c
+++ b/source3/lib/sharesec.c
@@ -149,7 +149,7 @@ bool share_info_db_init(void)
 
 	share_db = db_open(NULL, state_path("share_info.tdb"), 0,
 			   TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
-			   DBWRAP_LOCK_ORDER_1);
+			   DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (share_db == NULL) {
 		DEBUG(0,("Failed to open share info database %s (%s)\n",
 			state_path("share_info.tdb"), strerror(errno) ));
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index e1f0c15..a516b60 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -328,7 +328,7 @@ void brl_init(bool read_only)
 	brlock_db = db_open(NULL, lock_path("brlock.tdb"),
 			    SMB_OPEN_DATABASE_TDB_HASH_SIZE, tdb_flags,
 			    read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644,
-			    DBWRAP_LOCK_ORDER_2);
+			    DBWRAP_LOCK_ORDER_2, DBWRAP_FLAG_NONE);
 	if (!brlock_db) {
 		DEBUG(0,("Failed to open byte range locking database %s\n",
 			lock_path("brlock.tdb")));
diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c
index 20756bf..5d0874c 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -67,7 +67,7 @@ static bool locking_init_internal(bool read_only)
 			  SMB_OPEN_DATABASE_TDB_HASH_SIZE,
 			  TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
 			  read_only?O_RDONLY:O_RDWR|O_CREAT, 0644,
-			  DBWRAP_LOCK_ORDER_1);
+			  DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 
 	if (!lock_db) {
 		DEBUG(0,("ERROR: Failed to initialise locking database\n"));
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index 80839e3..8ee4bd5 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -60,7 +60,7 @@ static bool acl_tdb_init(void)
 
 	become_root();
 	acl_db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
-			 DBWRAP_LOCK_ORDER_1);
+			 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	unbecome_root();
 
 	if (acl_db == NULL) {
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
index 43456cf..63a12fd 100644
--- a/source3/modules/vfs_xattr_tdb.c
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -320,7 +320,7 @@ static bool xattr_tdb_init(int snum, TALLOC_CTX *mem_ctx, struct db_context **p_
 
 	become_root();
 	db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
-		     DBWRAP_LOCK_ORDER_2);
+		     DBWRAP_LOCK_ORDER_2, DBWRAP_FLAG_NONE);
 	unbecome_root();
 
 	if (db == NULL) {
diff --git a/source3/passdb/account_pol.c b/source3/passdb/account_pol.c
index 06925e8..5f2c7ab 100644
--- a/source3/passdb/account_pol.c
+++ b/source3/passdb/account_pol.c
@@ -220,13 +220,13 @@ bool init_account_policy(void)
 	}
 
 	db = db_open(NULL, state_path("account_policy.tdb"), 0, TDB_DEFAULT,
-		     O_RDWR, 0600, DBWRAP_LOCK_ORDER_1);
+		     O_RDWR, 0600, DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 
 	if (db == NULL) { /* the account policies files does not exist or open
 			   * failed, try to create a new one */
 		db = db_open(NULL, state_path("account_policy.tdb"), 0,
 			     TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
-			     DBWRAP_LOCK_ORDER_1);
+			     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 		if (db == NULL) {
 			DEBUG(0,("Failed to open account policy database\n"));
 			return False;
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index f256e6c..162083f 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -226,7 +226,7 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
 
 	tmp_db = db_open(NULL, tmp_fname, 0,
 			 TDB_DEFAULT, O_CREAT|O_RDWR, 0600,
-			 DBWRAP_LOCK_ORDER_1);
+			 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (tmp_db == NULL) {
 		DEBUG(0, ("tdbsam_convert_backup: Failed to create backup TDB passwd "
 			  "[%s]\n", tmp_fname));
@@ -293,7 +293,7 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
 
 	orig_db = db_open(NULL, dbname, 0,
 			  TDB_DEFAULT, O_CREAT|O_RDWR, 0600,
-			  DBWRAP_LOCK_ORDER_1);
+			  DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (orig_db == NULL) {
 		DEBUG(0, ("tdbsam_convert_backup: Failed to re-open "
 			  "converted passdb TDB [%s]\n", dbname));
@@ -444,7 +444,7 @@ static bool tdbsam_open( const char *name )
 	/* Try to open tdb passwd.  Create a new one if necessary */
 
 	db_sam = db_open(NULL, name, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600,
-			 DBWRAP_LOCK_ORDER_1);
+			 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (db_sam == NULL) {
 		DEBUG(0, ("tdbsam_open: Failed to open/create TDB passwd "
 			  "[%s]\n", name));
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index f97510d..9d91c2f 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -79,7 +79,7 @@ bool secrets_init_path(const char *private_dir, bool use_ntdb)
 
 	db_ctx = db_open(NULL, fname, 0,
 			 TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
-			 DBWRAP_LOCK_ORDER_1);
+			 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 
 	if (db_ctx == NULL) {
 		DEBUG(0,("Failed to open %s\n", fname));
diff --git a/source3/printing/printer_list.c b/source3/printing/printer_list.c
index 6e02ee5..a64775d 100644
--- a/source3/printing/printer_list.c
+++ b/source3/printing/printer_list.c
@@ -40,7 +40,8 @@ static struct db_context *get_printer_list_db(void)
 	}
 	db = db_open(NULL, PL_DB_NAME(), 0,
 		     TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
-		     O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_1);
+		     O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_1,
+		     DBWRAP_FLAG_NONE);
 	return db;
 }
 
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index 3e561eb..fdaf576 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -732,11 +732,11 @@ WERROR regdb_init(void)
 
 	regdb = db_open(NULL, state_path("registry.tdb"), 0,
 			REG_TDB_FLAGS, O_RDWR, 0600,
-			DBWRAP_LOCK_ORDER_1);
+			DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (!regdb) {
 		regdb = db_open(NULL, state_path("registry.tdb"), 0,
 				REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600,
-				DBWRAP_LOCK_ORDER_1);
+				DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 		if (!regdb) {
 			werr = ntstatus_to_werror(map_nt_error_from_unix(errno));
 			DEBUG(1,("regdb_init: Failed to open registry %s (%s)\n",
@@ -852,7 +852,7 @@ WERROR regdb_open( void )
 
 	regdb = db_open(NULL, state_path("registry.tdb"), 0,
 			REG_TDB_FLAGS, O_RDWR, 0600,
-			DBWRAP_LOCK_ORDER_1);
+			DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if ( !regdb ) {
 		result = ntstatus_to_werror( map_nt_error_from_unix( errno ) );
 		DEBUG(0,("regdb_open: Failed to open %s! (%s)\n",
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index b7b490f..9e3c1bd 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -69,7 +69,8 @@ NTSTATUS rpccli_pre_open_netlogon_creds(void)
 
 	global_db = db_open(talloc_autofree_context(), fname,
 			    0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
-			    O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2);
+			    O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
+			    DBWRAP_FLAG_NONE);
 	if (global_db == NULL) {
 		TALLOC_FREE(frame);
 		return NT_STATUS_NO_MEMORY;
diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c
index 994608c..0a7e5de 100644
--- a/source3/smbd/notify_internal.c
+++ b/source3/smbd/notify_internal.c
@@ -145,7 +145,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx,
 	notify->db_index = db_open(
 		notify, lock_path("notify_index.tdb"),
 		0, TDB_SEQNUM|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
-		O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_3);
+		O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_3, DBWRAP_FLAG_NONE);
 	if (notify->db_index == NULL) {
 		goto fail;
 	}
diff --git a/source3/smbd/smbXsrv_open.c b/source3/smbd/smbXsrv_open.c
index 3e2fed3..7e6b54f 100644
--- a/source3/smbd/smbXsrv_open.c
+++ b/source3/smbd/smbXsrv_open.c
@@ -64,7 +64,8 @@ NTSTATUS smbXsrv_open_global_init(void)
 			 TDB_CLEAR_IF_FIRST |
 			 TDB_INCOMPATIBLE_HASH,
 			 O_RDWR | O_CREAT, 0600,
-			 DBWRAP_LOCK_ORDER_1);
+			 DBWRAP_LOCK_ORDER_1,
+			 DBWRAP_FLAG_NONE);
 	if (db_ctx == NULL) {
 		NTSTATUS status;
 
diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c
index fa3033b..560fa3c 100644
--- a/source3/smbd/smbXsrv_session.c
+++ b/source3/smbd/smbXsrv_session.c
@@ -73,7 +73,8 @@ NTSTATUS smbXsrv_session_global_init(void)
 			 TDB_CLEAR_IF_FIRST |
 			 TDB_INCOMPATIBLE_HASH,
 			 O_RDWR | O_CREAT, 0600,
-			 DBWRAP_LOCK_ORDER_1);
+			 DBWRAP_LOCK_ORDER_1,
+			 DBWRAP_FLAG_NONE);
 	if (db_ctx == NULL) {
 		NTSTATUS status;
 
diff --git a/source3/smbd/smbXsrv_tcon.c b/source3/smbd/smbXsrv_tcon.c
index b6e2058..2cbd761 100644
--- a/source3/smbd/smbXsrv_tcon.c
+++ b/source3/smbd/smbXsrv_tcon.c
@@ -62,7 +62,8 @@ NTSTATUS smbXsrv_tcon_global_init(void)
 			 TDB_CLEAR_IF_FIRST |
 			 TDB_INCOMPATIBLE_HASH,
 			 O_RDWR | O_CREAT, 0600,
-			 DBWRAP_LOCK_ORDER_1);
+			 DBWRAP_LOCK_ORDER_1,
+			 DBWRAP_FLAG_NONE);
 	if (db_ctx == NULL) {
 		NTSTATUS status;
 
diff --git a/source3/smbd/smbXsrv_version.c b/source3/smbd/smbXsrv_version.c
index 8ba5e1f..b24dae9 100644
--- a/source3/smbd/smbXsrv_version.c
+++ b/source3/smbd/smbXsrv_version.c
@@ -80,7 +80,8 @@ NTSTATUS smbXsrv_version_global_init(const struct server_id *server_id)
 			 TDB_CLEAR_IF_FIRST |
 			 TDB_INCOMPATIBLE_HASH,
 			 O_RDWR | O_CREAT, 0600,
-			 DBWRAP_LOCK_ORDER_1);
+			 DBWRAP_LOCK_ORDER_1,
+			 DBWRAP_FLAG_NONE);
 	if (db_ctx == NULL) {
 		status = map_nt_error_from_unix_common(errno);
 		DEBUG(0,("smbXsrv_version_global_init: "
diff --git a/source3/torture/test_dbwrap_watch.c b/source3/torture/test_dbwrap_watch.c
index 9c2a679..4e699fe 100644
--- a/source3/torture/test_dbwrap_watch.c
+++ b/source3/torture/test_dbwrap_watch.c
@@ -48,7 +48,8 @@ bool run_dbwrap_watch1(int dummy)
 		goto fail;
 	}
 	db = db_open(msg, "test_watch.tdb", 0, TDB_DEFAULT,
-		     O_CREAT|O_RDWR, 0644, DBWRAP_LOCK_ORDER_1);
+		     O_CREAT|O_RDWR, 0644, DBWRAP_LOCK_ORDER_1,
+		     DBWRAP_FLAG_NONE);
 	if (db == NULL) {
 		fprintf(stderr, "db_open failed: %s\n", strerror(errno));
 		goto fail;
diff --git a/source3/torture/test_idmap_tdb_common.c b/source3/torture/test_idmap_tdb_common.c
index 6f5f3c5..f7262a2 100644
--- a/source3/torture/test_idmap_tdb_common.c
+++ b/source3/torture/test_idmap_tdb_common.c
@@ -86,7 +86,7 @@ static bool open_db(struct idmap_tdb_common_context *ctx)
 
 	ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT,
 			  O_RDWR | O_CREAT, 0600,
-			  DBWRAP_LOCK_ORDER_1);
+			  DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 
 	if(!ctx->db) {
 		DEBUG(0, ("Failed to open database: %s\n", strerror(errno)));
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 1d915fc..1f29a70 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -9066,7 +9066,8 @@ static bool run_local_dbtrans(int dummy)
 	TDB_DATA value;
 
 	db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
-		     O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1);
+		     O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
+		     DBWRAP_FLAG_NONE);
 	if (db == NULL) {
 		printf("Could not open transtest.db\n");
 		return false;
diff --git a/source3/utils/dbwrap_tool.c b/source3/utils/dbwrap_tool.c
index ffca6b6..b56e07a 100644
--- a/source3/utils/dbwrap_tool.c
+++ b/source3/utils/dbwrap_tool.c
@@ -588,7 +588,7 @@ int main(int argc, const char **argv)
 	case OP_LISTKEYS:
 	case OP_EXISTS:
 		db = db_open(mem_ctx, dbname, 0, tdb_flags, O_RDWR | O_CREAT,
-			     0644, DBWRAP_LOCK_ORDER_1);
+			     0644, DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 		if (db == NULL) {
 			d_fprintf(stderr, "ERROR: could not open dbname\n");
 			goto done;
diff --git a/source3/utils/dbwrap_torture.c b/source3/utils/dbwrap_torture.c
index 2741820..f748ac2 100644
--- a/source3/utils/dbwrap_torture.c
+++ b/source3/utils/dbwrap_torture.c
@@ -309,7 +309,7 @@ int main(int argc, const char *argv[])
 	}
 
 	db = db_open(mem_ctx, db_name, 0, tdb_flags,  O_RDWR | O_CREAT, 0644,
-		     DBWRAP_LOCK_ORDER_1);
+		     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 
 	if (db == NULL) {
 		d_fprintf(stderr, "failed to open db '%s': %s\n", db_name,
diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 1095f14..ec2b050 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -206,7 +206,7 @@ static bool net_idmap_opendb_autorid(TALLOC_CTX *mem_ctx,
 
 	if (readonly) {
 		*db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDONLY, 0,
-			     DBWRAP_LOCK_ORDER_1);
+			     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 		if (*db == NULL) {
 			d_fprintf(stderr,
 				  _("Could not open autorid db (%s): %s\n"),
@@ -261,7 +261,7 @@ static int net_idmap_dump(struct net_context *c, int argc, const char **argv)
 	d_fprintf(stderr, _("dumping id mapping from %s\n"), dbfile);
 
 	db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDONLY, 0,
-		     DBWRAP_LOCK_ORDER_1);
+		     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (db == NULL) {
 		d_fprintf(stderr, _("Could not open idmap db (%s): %s\n"),
 			  dbfile, strerror(errno));
@@ -387,7 +387,7 @@ static int net_idmap_restore(struct net_context *c, int argc, const char **argv)
 	}
 
 	db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644,
-		     DBWRAP_LOCK_ORDER_1);
+		     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (db == NULL) {
 		d_fprintf(stderr, _("Could not open idmap db (%s): %s\n"),
 			  dbfile, strerror(errno));
@@ -598,7 +598,7 @@ static int net_idmap_delete_mapping(struct net_context *c, int argc,
 	d_fprintf(stderr, _("deleting id mapping from %s\n"), dbfile);
 
 	db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDWR, 0,
-		     DBWRAP_LOCK_ORDER_1);
+		     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (db == NULL) {
 		d_fprintf(stderr, _("Could not open idmap db (%s): %s\n"),
 			  dbfile, strerror(errno));
diff --git a/source3/utils/net_idmap_check.c b/source3/utils/net_idmap_check.c
index e75c890..4b82871 100644
--- a/source3/utils/net_idmap_check.c
+++ b/source3/utils/net_idmap_check.c
@@ -790,7 +790,7 @@ static bool check_open_db(struct check_ctx* ctx, const char* name, int oflags)
 	}
 
 	ctx->db = db_open(ctx, name, 0, TDB_DEFAULT, oflags, 0,
-			  DBWRAP_LOCK_ORDER_1);
+			  DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (ctx->db == NULL) {
 		d_fprintf(stderr,
 			  _("Could not open idmap db (%s) for writing: %s\n"),
diff --git a/source3/utils/net_registry_check.c b/source3/utils/net_registry_check.c
index 8cdb8fa..d57c2aa 100644
--- a/source3/utils/net_registry_check.c
+++ b/source3/utils/net_registry_check.c
@@ -338,7 +338,7 @@ static bool check_ctx_open_output(struct check_ctx *ctx)
 	}
 
 	ctx->odb = db_open(ctx, ctx->opt.output, 0, TDB_DEFAULT, oflags, 0644,
-			   DBWRAP_LOCK_ORDER_1);
+			   DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (ctx->odb == NULL) {
 		d_fprintf(stderr,
 			  _("Could not open db (%s) for writing: %s\n"),
@@ -351,7 +351,7 @@ static bool check_ctx_open_output(struct check_ctx *ctx)
 
 static bool check_ctx_open_input(struct check_ctx *ctx) {
 	ctx->idb = db_open(ctx, ctx->fname, 0, TDB_DEFAULT, O_RDONLY, 0,
-			   DBWRAP_LOCK_ORDER_1);
+			   DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (ctx->idb == NULL) {
 		d_fprintf(stderr,
 			  _("Could not open db (%s) for reading: %s\n"),
diff --git a/source3/utils/status.c b/source3/utils/status.c
index be7c52f..1ff0e36 100644
--- a/source3/utils/status.c
+++ b/source3/utils/status.c
@@ -508,7 +508,7 @@ static void print_notify_recs(const char *path,
 		struct db_context *db;
 		db = db_open(NULL, lock_path("locking.tdb"), 0,
 			     TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDONLY, 0,
-			     DBWRAP_LOCK_ORDER_1);
+			     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 
 		if (!db) {
 			d_printf("%s not initialised\n",
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index e06cb21..dd99767 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -666,7 +666,7 @@ NTSTATUS idmap_autorid_db_init(const char *path,
 
 	/* Open idmap repository */
 	*db = db_open(mem_ctx, path, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644,
-		      DBWRAP_LOCK_ORDER_1);
+		      DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 
 	if (*db == NULL) {
 		DEBUG(0, ("Unable to open idmap_autorid database '%s'\n", path));
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c
index cc930ff..ebff347 100644
--- a/source3/winbindd/idmap_tdb.c
+++ b/source3/winbindd/idmap_tdb.c
@@ -321,7 +321,7 @@ static NTSTATUS idmap_tdb_open_db(struct idmap_domain *dom)
 
 	/* Open idmap repository */
 	db = db_open(mem_ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644,
-		     DBWRAP_LOCK_ORDER_1);
+		     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (!db) {
 		DEBUG(0, ("Unable to open idmap database\n"));
 		ret = NT_STATUS_UNSUCCESSFUL;
diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c
index 4a9c2fe..942490d 100644
--- a/source3/winbindd/idmap_tdb2.c
+++ b/source3/winbindd/idmap_tdb2.c
@@ -114,7 +114,7 @@ static NTSTATUS idmap_tdb2_open_db(struct idmap_domain *dom)
 
 	/* Open idmap repository */
 	ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644,
-			  DBWRAP_LOCK_ORDER_1);
+			  DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	TALLOC_FREE(db_path);
 
 	if (ctx->db == NULL) {
-- 
1.8.3.2


From 04440f841927d9c54c0109ecb64f493f325f8d1b Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 12:53:24 +0100
Subject: [PATCH 03/21] dbwrap: add a dbwrap_flags argument to db_open_ctdb()

This is in preparation of directly supporting ctdb read only
record copies when opening a ctdb database from samba.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/lib/dbwrap/dbwrap_ctdb.c   | 6 ++++--
 source3/lib/dbwrap/dbwrap_ctdb.h   | 3 ++-
 source3/lib/dbwrap/dbwrap_open.c   | 2 +-
 source3/torture/test_dbwrap_ctdb.c | 2 +-
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c
index 98a9138..2770129 100644
--- a/source3/lib/dbwrap/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap/dbwrap_ctdb.c
@@ -1569,7 +1569,8 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
 				const char *name,
 				int hash_size, int tdb_flags,
 				int open_flags, mode_t mode,
-				enum dbwrap_lock_order lock_order)
+				enum dbwrap_lock_order lock_order,
+				uint64_t dbwrap_flags)
 {
 	struct db_context *result;
 	struct db_ctdb_ctx *db_ctdb;
@@ -1703,7 +1704,8 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
 				const char *name,
 				int hash_size, int tdb_flags,
 				int open_flags, mode_t mode,
-				enum dbwrap_lock_order lock_order)
+				enum dbwrap_lock_order lock_order,
+				uint64_t dbwrap_flags)
 {
 	DEBUG(3, ("db_open_ctdb: no cluster support!\n"));
 	errno = ENOSYS;
diff --git a/source3/lib/dbwrap/dbwrap_ctdb.h b/source3/lib/dbwrap/dbwrap_ctdb.h
index bfbe3bd..3196b91 100644
--- a/source3/lib/dbwrap/dbwrap_ctdb.h
+++ b/source3/lib/dbwrap/dbwrap_ctdb.h
@@ -31,6 +31,7 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
 				const char *name,
 				int hash_size, int tdb_flags,
 				int open_flags, mode_t mode,
-				enum dbwrap_lock_order lock_order);
+				enum dbwrap_lock_order lock_order,
+				uint64_t dbwrap_flags);
 
 #endif /* __DBWRAP_CTDB_H__ */
diff --git a/source3/lib/dbwrap/dbwrap_open.c b/source3/lib/dbwrap/dbwrap_open.c
index 6c9280c..61324f7 100644
--- a/source3/lib/dbwrap/dbwrap_open.c
+++ b/source3/lib/dbwrap/dbwrap_open.c
@@ -104,7 +104,7 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
 		if (lp_parm_bool(-1, "ctdb", partname, True)) {
 			result = db_open_ctdb(mem_ctx, partname, hash_size,
 					      tdb_flags, open_flags, mode,
-					      lock_order);
+					      lock_order, dbwrap_flags);
 			if (result == NULL) {
 				DEBUG(0,("failed to attach to ctdb %s\n",
 					 partname));
diff --git a/source3/torture/test_dbwrap_ctdb.c b/source3/torture/test_dbwrap_ctdb.c
index f7672ba..d7380b1 100644
--- a/source3/torture/test_dbwrap_ctdb.c
+++ b/source3/torture/test_dbwrap_ctdb.c
@@ -32,7 +32,7 @@ bool run_local_dbwrap_ctdb(int dummy)
 	uint32_t val;
 
 	db = db_open_ctdb(talloc_tos(), "torture.tdb", 0, TDB_DEFAULT,
-			  O_RDWR, 0755, DBWRAP_LOCK_ORDER_1);
+			  O_RDWR, 0755, DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
 	if (db == NULL) {
 		perror("db_open_ctdb failed");
 		goto fail;
-- 
1.8.3.2


From 578bbaecca77c7c749af4f44b1842d0d7e7a3559 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 11:31:44 +0100
Subject: [PATCH 04/21] dbwrap: add DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h
index 4064ba2..02b4405 100644
--- a/lib/dbwrap/dbwrap.h
+++ b/lib/dbwrap/dbwrap.h
@@ -33,6 +33,7 @@ enum dbwrap_lock_order {
 #define DBWRAP_LOCK_ORDER_MAX DBWRAP_LOCK_ORDER_3
 
 #define DBWRAP_FLAG_NONE                     0x0000000000000000ULL
+#define DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS 0x0000000000000001ULL
 
 /* The following definitions come from lib/dbwrap.c  */
 
-- 
1.8.3.2


From 1e7bad0792275d8ecb21c908e3a865988d49d9c5 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 28 Jan 2014 21:24:22 +0100
Subject: [PATCH 05/21] dbwrap_ctdb: implement
 DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS

For non-persistent databases we try to use CTDB_CONTROL_SET_DB_READONLY
in order to make use of readonly records.

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/lib/dbwrap/dbwrap_ctdb.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c
index 2770129..87e644d 100644
--- a/source3/lib/dbwrap/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap/dbwrap_ctdb.c
@@ -1649,6 +1649,27 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
+#ifdef HAVE_CTDB_WANT_READONLY_DECL
+	if (!result->persistent &&
+	    (dbwrap_flags & DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS))
+	{
+		TDB_DATA indata;
+
+		indata = make_tdb_data((uint8_t *)&db_ctdb->db_id,
+				       sizeof(db_ctdb->db_id));
+
+		status = ctdbd_control_local(
+			conn, CTDB_CONTROL_SET_DB_READONLY, 0, 0, indata,
+			NULL, NULL, &cstatus);
+		if (!NT_STATUS_IS_OK(status) || (cstatus != 0)) {
+			DEBUG(1, ("CTDB_CONTROL_SET_DB_READONLY failed: "
+				  "%s, %d\n", nt_errstr(status), cstatus));
+			TALLOC_FREE(result);
+			return NULL;
+		}
+	}
+#endif
+
 	lp_ctx = loadparm_init_s3(db_path, loadparm_s3_helpers());
 
 	db_ctdb->wtdb = tdb_wrap_open(db_ctdb, db_path, hash_size, tdb_flags,
-- 
1.8.3.2


From ed23bc35c68d9a5de7858d0b77b24f0e828fdda6 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 28 Jan 2014 21:31:17 +0100
Subject: [PATCH 06/21] dbwrap_open: add 'dbwrap_optimize_readonly:* = yes'
 option

Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
---
 source3/lib/dbwrap/dbwrap_open.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/source3/lib/dbwrap/dbwrap_open.c b/source3/lib/dbwrap/dbwrap_open.c
index 61324f7..7f3cddf 100644
--- a/source3/lib/dbwrap/dbwrap_open.c
+++ b/source3/lib/dbwrap/dbwrap_open.c
@@ -81,6 +81,31 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
+	if (tdb_flags & TDB_CLEAR_IF_FIRST) {
+		const char *base;
+		bool try_readonly = false;
+
+		base = strrchr_m(name, '/');
+		if (base != NULL) {
+			base += 1;
+		} else {
+			base = name;
+		}
+
+		if (dbwrap_flags & DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS) {
+			try_readonly = true;
+		}
+
+		try_readonly = lp_parm_bool(-1, "dbwrap_optimize_readonly", "*", try_readonly);
+		try_readonly = lp_parm_bool(-1, "dbwrap_optimize_readonly", base, try_readonly);
+
+		if (try_readonly) {
+			dbwrap_flags |= DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS;
+		} else {
+			dbwrap_flags &= ~DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS;
+		}
+	}
+
 #ifdef CLUSTER_SUPPORT
 	sockname = lp_ctdbd_socket();
 
-- 
1.8.3.2


From 870a1d9fe56323f1887761ef1d7e97535dcb372a Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 27 Jan 2014 16:21:14 +0100
Subject: [PATCH 07/21] s3:rpc_client: optimize the netlogon_creds_cli.tdb for
 read-only access

Usually a record in this DB will be written once and then read
many times by winbindd processes on multiple nodes (when run in
a cluster). In order not to introduce a big performance penalty
with the increased correctness achieved by storing the netlogon
creds, in a cluster setup, we should activate ctdb's read only
record copies on this db.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_client/cli_netlogon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 9e3c1bd..746c7b6 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -70,7 +70,7 @@ NTSTATUS rpccli_pre_open_netlogon_creds(void)
 	global_db = db_open(talloc_autofree_context(), fname,
 			    0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
 			    O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
-			    DBWRAP_FLAG_NONE);
+			    DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS);
 	if (global_db == NULL) {
 		TALLOC_FREE(frame);
 		return NT_STATUS_NO_MEMORY;
-- 
1.8.3.2


From 7eef988ccc9bc9e26f19696f1cd4c0fe0863894b Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 27 Jan 2014 16:19:52 +0100
Subject: [PATCH 08/21] s3:registry: introduce REG_DBWRAP_FLAGS to use for all
 db_open calls

This is in accordance with the use of REG_TDB_FLAGS.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/registry/reg_backend_db.c | 6 +++---
 source3/registry/reg_db.h         | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index fdaf576..7c1e546 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -732,11 +732,11 @@ WERROR regdb_init(void)
 
 	regdb = db_open(NULL, state_path("registry.tdb"), 0,
 			REG_TDB_FLAGS, O_RDWR, 0600,
-			DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
+			DBWRAP_LOCK_ORDER_1, REG_DBWRAP_FLAGS);
 	if (!regdb) {
 		regdb = db_open(NULL, state_path("registry.tdb"), 0,
 				REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600,
-				DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
+				DBWRAP_LOCK_ORDER_1, REG_DBWRAP_FLAGS);
 		if (!regdb) {
 			werr = ntstatus_to_werror(map_nt_error_from_unix(errno));
 			DEBUG(1,("regdb_init: Failed to open registry %s (%s)\n",
@@ -852,7 +852,7 @@ WERROR regdb_open( void )
 
 	regdb = db_open(NULL, state_path("registry.tdb"), 0,
 			REG_TDB_FLAGS, O_RDWR, 0600,
-			DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
+			DBWRAP_LOCK_ORDER_1, REG_DBWRAP_FLAGS);
 	if ( !regdb ) {
 		result = ntstatus_to_werror( map_nt_error_from_unix( errno ) );
 		DEBUG(0,("regdb_open: Failed to open %s! (%s)\n",
diff --git a/source3/registry/reg_db.h b/source3/registry/reg_db.h
index d0d9fd3..f2f79d2 100644
--- a/source3/registry/reg_db.h
+++ b/source3/registry/reg_db.h
@@ -21,6 +21,7 @@
 #define _REG_DB_H
 
 #define REG_TDB_FLAGS   TDB_SEQNUM
+#define REG_DBWRAP_FLAGS DBWRAP_FLAG_NONE
 
 #define REGDB_VERSION_V1    1  /* first db version with write support */
 #define REGDB_VERSION_V2    2  /* version 2 with normalized keys */
-- 
1.8.3.2


From f5c7819e7506ecfc777a9204fba4db179d23aa47 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 12:33:42 +0100
Subject: [PATCH 09/21] dbwrap: add a dbwrap_flags argument to db_open_tdb()

...for consistency and in preparation of future flags
that the tdb backend might be aware of.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap_local_open.c           | 4 ++--
 lib/dbwrap/dbwrap_tdb.c                  | 3 ++-
 lib/dbwrap/dbwrap_tdb.h                  | 3 ++-
 source3/smbd/notify_internal.c           | 2 +-
 source4/ntvfs/posix/python/pyxattr_tdb.c | 6 ++++--
 5 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/lib/dbwrap/dbwrap_local_open.c b/lib/dbwrap/dbwrap_local_open.c
index 56048af..650bcb3 100644
--- a/lib/dbwrap/dbwrap_local_open.c
+++ b/lib/dbwrap/dbwrap_local_open.c
@@ -103,7 +103,7 @@ static bool tdb_to_ntdb(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx,
 		return false;
 	}
 	tdb = db_open_tdb(ctx, lp_ctx, tdbname, 0,
-			  TDB_DEFAULT, O_RDONLY, 0, 0);
+			  TDB_DEFAULT, O_RDONLY, 0, 0, DBWRAP_FLAG_NONE);
 	if (!tdb) {
 		DEBUG(0, ("tdb_to_ntdb: could not open %s: %s\n",
 			  tdbname, strerror(errno)));
@@ -213,7 +213,7 @@ struct db_context *dbwrap_local_open(TALLOC_CTX *mem_ctx,
 		}
 		db = db_open_tdb(mem_ctx, lp_ctx, tdbname, hash_size,
 				 tdb_flags, open_flags, mode,
-				 lock_order);
+				 lock_order, dbwrap_flags);
 	}
 out:
 	talloc_free(tmp_ctx);
diff --git a/lib/dbwrap/dbwrap_tdb.c b/lib/dbwrap/dbwrap_tdb.c
index 3f21192..1b061e3 100644
--- a/lib/dbwrap/dbwrap_tdb.c
+++ b/lib/dbwrap/dbwrap_tdb.c
@@ -401,7 +401,8 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
 			       const char *name,
 			       int hash_size, int tdb_flags,
 			       int open_flags, mode_t mode,
-			       enum dbwrap_lock_order lock_order)
+			       enum dbwrap_lock_order lock_order,
+			       uint64_t dbrwap_flags)
 {
 	struct db_context *result = NULL;
 	struct db_tdb_ctx *db_tdb;
diff --git a/lib/dbwrap/dbwrap_tdb.h b/lib/dbwrap/dbwrap_tdb.h
index 6a6da45..93ee09c 100644
--- a/lib/dbwrap/dbwrap_tdb.h
+++ b/lib/dbwrap/dbwrap_tdb.h
@@ -29,7 +29,8 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
 			       const char *name,
 			       int hash_size, int tdb_flags,
 			       int open_flags, mode_t mode,
-			       enum dbwrap_lock_order lock_order);
+			       enum dbwrap_lock_order lock_order,
+			       uint64_t dbwrap_flags);
 
 
 #endif /* __DBWRAP_TDB_H__ */
diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c
index 0a7e5de..4d88565 100644
--- a/source3/smbd/notify_internal.c
+++ b/source3/smbd/notify_internal.c
@@ -137,7 +137,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx,
 	notify->db_notify = db_open_tdb(
 		notify, lp_ctx, lock_path("notify.tdb"),
 		0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
-		O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_2);
+		O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_2, DBWRAP_FLAG_NONE);
 		talloc_unlink(notify, lp_ctx);
 	if (notify->db_notify == NULL) {
 		goto fail;
diff --git a/source4/ntvfs/posix/python/pyxattr_tdb.c b/source4/ntvfs/posix/python/pyxattr_tdb.c
index b510931..b866d7e 100644
--- a/source4/ntvfs/posix/python/pyxattr_tdb.c
+++ b/source4/ntvfs/posix/python/pyxattr_tdb.c
@@ -57,7 +57,8 @@ static PyObject *py_wrap_setxattr(PyObject *self, PyObject *args)
 	blob.length = blobsize;
 	mem_ctx = talloc_new(NULL);
 	eadb = db_open_tdb(mem_ctx, py_default_loadparm_context(mem_ctx), tdbname, 50000,
-			   TDB_DEFAULT, O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2);
+			   TDB_DEFAULT, O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
+			   DBWRAP_FLAG_NONE);
 
 	if (eadb == NULL) {
 		PyErr_SetFromErrno(PyExc_IOError);
@@ -104,7 +105,8 @@ static PyObject *py_wrap_getxattr(PyObject *self, PyObject *args)
 	mem_ctx = talloc_new(NULL);
 
 	eadb = db_open_tdb(mem_ctx, py_default_loadparm_context(mem_ctx), tdbname, 50000,
-			   TDB_DEFAULT, O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2);
+			   TDB_DEFAULT, O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
+			   DBWRAP_FLAG_NONE);
 
 	if (eadb == NULL) {
 		PyErr_SetFromErrno(PyExc_IOError);
-- 
1.8.3.2


From c44cbd2c1515fb2187cc068f41ade9fdfc59793e Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 12:37:36 +0100
Subject: [PATCH 10/21] dbwrap: add a dbwrap_flags argument to db_open_ntdb()

for consistency and to perpare for possible future
flags that the ntdb backend might be aware of.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap_local_open.c | 5 +++--
 lib/dbwrap/dbwrap_ntdb.c       | 3 ++-
 lib/dbwrap/dbwrap_ntdb.h       | 3 ++-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/lib/dbwrap/dbwrap_local_open.c b/lib/dbwrap/dbwrap_local_open.c
index 650bcb3..e54ed97 100644
--- a/lib/dbwrap/dbwrap_local_open.c
+++ b/lib/dbwrap/dbwrap_local_open.c
@@ -111,7 +111,7 @@ static bool tdb_to_ntdb(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx,
 	}
 	ntdb = db_open_ntdb(ctx, lp_ctx, ntdbname, dbwrap_hash_size(tdb),
 			    TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL,
-			    st.st_mode & 0777, 0);
+			    st.st_mode & 0777, 0, DBWRAP_FLAG_NONE);
 	if (!ntdb) {
 		DEBUG(0, ("tdb_to_ntdb: could not create %s: %s\n",
 			  ntdbname, strerror(errno)));
@@ -204,7 +204,8 @@ struct db_context *dbwrap_local_open(TALLOC_CTX *mem_ctx,
 			}
 		}
 		db = db_open_ntdb(mem_ctx, lp_ctx, ntdbname, hash_size,
-				  ntdb_flags, open_flags, mode, lock_order);
+				  ntdb_flags, open_flags, mode, lock_order,
+				  dbwrap_flags);
 	} else {
 		if (!streq(ntdbname, tdbname) && file_exist(ntdbname)) {
 			DEBUG(0, ("Refusing to open '%s' when '%s' exists\n",
diff --git a/lib/dbwrap/dbwrap_ntdb.c b/lib/dbwrap/dbwrap_ntdb.c
index 48fe39e..5be5414 100644
--- a/lib/dbwrap/dbwrap_ntdb.c
+++ b/lib/dbwrap/dbwrap_ntdb.c
@@ -502,7 +502,8 @@ struct db_context *db_open_ntdb(TALLOC_CTX *mem_ctx,
 				const char *ntdbname,
 				int hash_size, int ntdb_flags,
 				int open_flags, mode_t mode,
-				enum dbwrap_lock_order lock_order)
+				enum dbwrap_lock_order lock_order,
+				uint64_t dbwrap_flags)
 {
 	struct db_context *result = NULL;
 	struct db_ntdb_ctx *db_ntdb;
diff --git a/lib/dbwrap/dbwrap_ntdb.h b/lib/dbwrap/dbwrap_ntdb.h
index b00a567..a1da1bc 100644
--- a/lib/dbwrap/dbwrap_ntdb.h
+++ b/lib/dbwrap/dbwrap_ntdb.h
@@ -30,6 +30,7 @@ struct db_context *db_open_ntdb(TALLOC_CTX *mem_ctx,
 				const char *name,
 				int hash_size, int ntdb_flags,
 				int open_flags, mode_t mode,
-				enum dbwrap_lock_order lock_order);
+				enum dbwrap_lock_order lock_order,
+				uint64_t dbwrap_flags);
 
 #endif /* __DBWRAP_NTDB_H__ */
-- 
1.8.3.2


From 115ce2ae0ecdd2f12c4599b610d4db5f3dbff146 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 27 Jan 2014 16:38:25 +0100
Subject: [PATCH 11/21] dbwrap: add dbwrap_flags argument to
 dbwrap_local_open()

To be consistent with db_open() and prepare for future
possible extensions.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 auth/credentials/credentials_secrets.c | 3 ++-
 lib/dbwrap/dbwrap.h                    | 3 ++-
 lib/dbwrap/dbwrap_local_open.c         | 3 ++-
 libcli/auth/netlogon_creds_cli.c       | 3 ++-
 libcli/auth/schannel_state_tdb.c       | 2 +-
 source3/lib/dbwrap/dbwrap_open.c       | 2 +-
 source4/cluster/local.c                | 2 +-
 7 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/auth/credentials/credentials_secrets.c b/auth/credentials/credentials_secrets.c
index 6c1cded..9fad104 100644
--- a/auth/credentials/credentials_secrets.c
+++ b/auth/credentials/credentials_secrets.c
@@ -255,7 +255,8 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
 		
 	db_ctx = dbwrap_local_open(cred, lp_ctx, secrets_tdb, 0,
 				   TDB_DEFAULT, O_RDWR, 0600,
-				   DBWRAP_LOCK_ORDER_1);
+				   DBWRAP_LOCK_ORDER_1,
+				   DBWRAP_FLAG_NONE);
 	/* Bleh, nasty recursion issues: We are setting a machine
 	 * account here, so we don't want the 'pending' flag around
 	 * any more */
diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h
index 02b4405..1949d5f 100644
--- a/lib/dbwrap/dbwrap.h
+++ b/lib/dbwrap/dbwrap.h
@@ -160,6 +160,7 @@ struct db_context *dbwrap_local_open(TALLOC_CTX *mem_ctx,
 				     const char *name,
 				     int hash_size, int tdb_flags,
 				     int open_flags, mode_t mode,
-				     enum dbwrap_lock_order lock_order);
+				     enum dbwrap_lock_order lock_order,
+				     uint64_t dbwrap_flags);
 
 #endif /* __DBWRAP_H__ */
diff --git a/lib/dbwrap/dbwrap_local_open.c b/lib/dbwrap/dbwrap_local_open.c
index e54ed97..a6f494e 100644
--- a/lib/dbwrap/dbwrap_local_open.c
+++ b/lib/dbwrap/dbwrap_local_open.c
@@ -160,7 +160,8 @@ struct db_context *dbwrap_local_open(TALLOC_CTX *mem_ctx,
 				     const char *name,
 				     int hash_size, int tdb_flags,
 				     int open_flags, mode_t mode,
-				     enum dbwrap_lock_order lock_order)
+				     enum dbwrap_lock_order lock_order,
+				     uint64_t dbwrap_flags)
 {
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 	const char *ntdbname, *tdbname;
diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
index 88893ad..d73335d 100644
--- a/libcli/auth/netlogon_creds_cli.c
+++ b/libcli/auth/netlogon_creds_cli.c
@@ -227,7 +227,8 @@ NTSTATUS netlogon_creds_cli_open_global_db(struct loadparm_context *lp_ctx)
 				      fname, 0,
 				      TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
 				      O_RDWR|O_CREAT,
-				      0600, DBWRAP_LOCK_ORDER_2);
+				      0600, DBWRAP_LOCK_ORDER_2,
+				      DBWRAP_FLAG_NONE);
 	if (global_db == NULL) {
 		DEBUG(0,("netlogon_creds_cli_open_global_db: Failed to open %s - %s\n",
 			 fname, strerror(errno)));
diff --git a/libcli/auth/schannel_state_tdb.c b/libcli/auth/schannel_state_tdb.c
index 6669b46..2219540 100644
--- a/libcli/auth/schannel_state_tdb.c
+++ b/libcli/auth/schannel_state_tdb.c
@@ -49,7 +49,7 @@ struct db_context *open_schannel_session_store(TALLOC_CTX *mem_ctx,
 
 	db_sc = dbwrap_local_open(mem_ctx, lp_ctx, fname, 0,
 				  TDB_CLEAR_IF_FIRST|TDB_NOSYNC, O_RDWR|O_CREAT,
-				  0600, 0);
+				  0600, 0, DBWRAP_FLAG_NONE);
 
 	if (!db_sc) {
 		DEBUG(0,("open_schannel_session_store: Failed to open %s - %s\n",
diff --git a/source3/lib/dbwrap/dbwrap_open.c b/source3/lib/dbwrap/dbwrap_open.c
index 7f3cddf..ee5ec74 100644
--- a/source3/lib/dbwrap/dbwrap_open.c
+++ b/source3/lib/dbwrap/dbwrap_open.c
@@ -147,7 +147,7 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
 		struct loadparm_context *lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
 		result = dbwrap_local_open(mem_ctx, lp_ctx, name, hash_size,
 					   tdb_flags, open_flags, mode,
-					   lock_order);
+					   lock_order, dbwrap_flags);
 		talloc_unlink(mem_ctx, lp_ctx);
 	}
 	return result;
diff --git a/source4/cluster/local.c b/source4/cluster/local.c
index aa0fd7d..0a65950 100644
--- a/source4/cluster/local.c
+++ b/source4/cluster/local.c
@@ -63,7 +63,7 @@ static struct db_context *local_db_tmp_open(struct cluster_ops *ops,
 
 	path = smbd_tmp_path(tmp_ctx, lp_ctx, dbname);
 	db = dbwrap_local_open(mem_ctx, lp_ctx, path, 0, flags, O_RDWR|O_CREAT,
-			       0600, 0);
+			       0600, 0, DBWRAP_FLAG_NONE);
 	talloc_free(tmp_ctx);
 	return db;
 }
-- 
1.8.3.2


From 566deccf539a3e89495549ad6c199903741b834e Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 27 Jan 2014 17:20:56 +0100
Subject: [PATCH 12/21] dbwrap: introduce DBWRAP_LOCK_ORDER_NONE for lock order
 "0".

Ther are still some databases which are opened (locally) with
lock oder 0, which means don't do lock oder checking,
thereby circumventing this deadlock-prevention mechanism.

Add a symbolic constant for this "0" to make this circumvention
more explicit.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap.c | 2 +-
 lib/dbwrap/dbwrap.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/dbwrap/dbwrap.c b/lib/dbwrap/dbwrap.c
index 8270b63..3606617 100644
--- a/lib/dbwrap/dbwrap.c
+++ b/lib/dbwrap/dbwrap.c
@@ -212,7 +212,7 @@ static struct db_record *dbwrap_fetch_locked_internal(
 	struct db_record *rec;
 	struct dbwrap_lock_order_state *lock_order = NULL;
 
-	if (db->lock_order != 0) {
+	if (db->lock_order != DBWRAP_LOCK_ORDER_NONE) {
 		lock_order = dbwrap_check_lock_order(db, mem_ctx);
 		if (lock_order == NULL) {
 			return NULL;
diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h
index 1949d5f..03cc3f4 100644
--- a/lib/dbwrap/dbwrap.h
+++ b/lib/dbwrap/dbwrap.h
@@ -26,6 +26,7 @@ struct db_record;
 struct db_context;
 
 enum dbwrap_lock_order {
+	DBWRAP_LOCK_ORDER_NONE = 0, /* Don't check lock orders for this db. */
 	DBWRAP_LOCK_ORDER_1 = 1,
 	DBWRAP_LOCK_ORDER_2 = 2,
 	DBWRAP_LOCK_ORDER_3 = 3
-- 
1.8.3.2


From e6b1927372befac2630904991c74305e5b0aaab9 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 27 Jan 2014 17:25:54 +0100
Subject: [PATCH 13/21] libcli: use DBWRAP_LOCK_ORDER_NONE when opening
 schannel_store.tdb

Make lack of lock order checking more visible.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 libcli/auth/schannel_state_tdb.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libcli/auth/schannel_state_tdb.c b/libcli/auth/schannel_state_tdb.c
index 2219540..2d3481d 100644
--- a/libcli/auth/schannel_state_tdb.c
+++ b/libcli/auth/schannel_state_tdb.c
@@ -49,7 +49,8 @@ struct db_context *open_schannel_session_store(TALLOC_CTX *mem_ctx,
 
 	db_sc = dbwrap_local_open(mem_ctx, lp_ctx, fname, 0,
 				  TDB_CLEAR_IF_FIRST|TDB_NOSYNC, O_RDWR|O_CREAT,
-				  0600, 0, DBWRAP_FLAG_NONE);
+				  0600, DBWRAP_LOCK_ORDER_NONE,
+				  DBWRAP_FLAG_NONE);
 
 	if (!db_sc) {
 		DEBUG(0,("open_schannel_session_store: Failed to open %s - %s\n",
-- 
1.8.3.2


From 6cc35609a2bc902c52d9e882a491bdc8d7a5b1d1 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 27 Jan 2014 17:26:50 +0100
Subject: [PATCH 14/21] s4:cluster: use DBWRAP_LOCK_ODER_NONE for
 local_db_tmp_open()

Make lack of lock oder checking more visible.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source4/cluster/local.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/cluster/local.c b/source4/cluster/local.c
index 0a65950..18ee3d9 100644
--- a/source4/cluster/local.c
+++ b/source4/cluster/local.c
@@ -63,7 +63,7 @@ static struct db_context *local_db_tmp_open(struct cluster_ops *ops,
 
 	path = smbd_tmp_path(tmp_ctx, lp_ctx, dbname);
 	db = dbwrap_local_open(mem_ctx, lp_ctx, path, 0, flags, O_RDWR|O_CREAT,
-			       0600, 0, DBWRAP_FLAG_NONE);
+			       0600, DBWRAP_LOCK_ORDER_NONE, DBWRAP_FLAG_NONE);
 	talloc_free(tmp_ctx);
 	return db;
 }
-- 
1.8.3.2


From 4954a64b8b72151b58dabed4fd7c5a97372c3e7f Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 12:42:31 +0100
Subject: [PATCH 15/21] dbwrap: explicitly use DBWRAP_LOCK_ORDER_NONE in
 tdb->ntdb conversion

Make lack of lock order checking more visible.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap_local_open.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/dbwrap/dbwrap_local_open.c b/lib/dbwrap/dbwrap_local_open.c
index a6f494e..6e40139 100644
--- a/lib/dbwrap/dbwrap_local_open.c
+++ b/lib/dbwrap/dbwrap_local_open.c
@@ -103,7 +103,8 @@ static bool tdb_to_ntdb(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx,
 		return false;
 	}
 	tdb = db_open_tdb(ctx, lp_ctx, tdbname, 0,
-			  TDB_DEFAULT, O_RDONLY, 0, 0, DBWRAP_FLAG_NONE);
+			  TDB_DEFAULT, O_RDONLY, 0, DBWRAP_LOCK_ORDER_NONE,
+			  DBWRAP_FLAG_NONE);
 	if (!tdb) {
 		DEBUG(0, ("tdb_to_ntdb: could not open %s: %s\n",
 			  tdbname, strerror(errno)));
@@ -111,7 +112,8 @@ static bool tdb_to_ntdb(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx,
 	}
 	ntdb = db_open_ntdb(ctx, lp_ctx, ntdbname, dbwrap_hash_size(tdb),
 			    TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL,
-			    st.st_mode & 0777, 0, DBWRAP_FLAG_NONE);
+			    st.st_mode & 0777, DBWRAP_LOCK_ORDER_NONE,
+			    DBWRAP_FLAG_NONE);
 	if (!ntdb) {
 		DEBUG(0, ("tdb_to_ntdb: could not create %s: %s\n",
 			  ntdbname, strerror(errno)));
-- 
1.8.3.2


From 502fa16bc968ee75d568338e6da36ad36156de7f Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 11:52:36 +0100
Subject: [PATCH 16/21] dbwrap: move definition of DBWRAP_LOCK_ORDER_MAX to the
 private header.

This is only needed internally.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap.h         | 1 -
 lib/dbwrap/dbwrap_private.h | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h
index 03cc3f4..81c4974 100644
--- a/lib/dbwrap/dbwrap.h
+++ b/lib/dbwrap/dbwrap.h
@@ -31,7 +31,6 @@ enum dbwrap_lock_order {
 	DBWRAP_LOCK_ORDER_2 = 2,
 	DBWRAP_LOCK_ORDER_3 = 3
 };
-#define DBWRAP_LOCK_ORDER_MAX DBWRAP_LOCK_ORDER_3
 
 #define DBWRAP_FLAG_NONE                     0x0000000000000000ULL
 #define DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS 0x0000000000000001ULL
diff --git a/lib/dbwrap/dbwrap_private.h b/lib/dbwrap/dbwrap_private.h
index da904f0..14553bc 100644
--- a/lib/dbwrap/dbwrap_private.h
+++ b/lib/dbwrap/dbwrap_private.h
@@ -69,5 +69,7 @@ struct db_context {
 	void *stored_callback_private_data;
 };
 
+#define DBWRAP_LOCK_ORDER_MAX DBWRAP_LOCK_ORDER_3
+
 #endif /* __DBWRAP_PRIVATE_H__ */
 
-- 
1.8.3.2


From 308a236b94b45b3b76c5a18c35e951611a2bb253 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 12:04:38 +0100
Subject: [PATCH 17/21] dbwrap: add DBWRAP_LOCK_ORDER_MIN

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap_private.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/dbwrap/dbwrap_private.h b/lib/dbwrap/dbwrap_private.h
index 14553bc..e131654 100644
--- a/lib/dbwrap/dbwrap_private.h
+++ b/lib/dbwrap/dbwrap_private.h
@@ -69,6 +69,7 @@ struct db_context {
 	void *stored_callback_private_data;
 };
 
+#define DBWRAP_LOCK_ORDER_MIN DBWRAP_LOCK_ORDER_1
 #define DBWRAP_LOCK_ORDER_MAX DBWRAP_LOCK_ORDER_3
 
 #endif /* __DBWRAP_PRIVATE_H__ */
-- 
1.8.3.2


From 846019e60a9ed5af38fe3b7a799ec7686765519d Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 11:54:06 +0100
Subject: [PATCH 18/21] dbwrap: add DBWRAP_LOCK_ORDER_VALID()

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap_private.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/dbwrap/dbwrap_private.h b/lib/dbwrap/dbwrap_private.h
index e131654..a6bad04 100644
--- a/lib/dbwrap/dbwrap_private.h
+++ b/lib/dbwrap/dbwrap_private.h
@@ -72,5 +72,9 @@ struct db_context {
 #define DBWRAP_LOCK_ORDER_MIN DBWRAP_LOCK_ORDER_1
 #define DBWRAP_LOCK_ORDER_MAX DBWRAP_LOCK_ORDER_3
 
+#define DBWRAP_LOCK_ORDER_VALID(order) \
+	(((order) >= DBWRAP_LOCK_ORDER_MIN) && \
+	 ((order) <= DBWRAP_LOCK_ORDER_MAX))
+
 #endif /* __DBWRAP_PRIVATE_H__ */
 
-- 
1.8.3.2


From b151a33c94ea42a52ba7b65d265b59adf053f066 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 11:44:21 +0100
Subject: [PATCH 19/21] dbwrap: add a comment explaining the supported lock
 orders

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h
index 81c4974..d289243 100644
--- a/lib/dbwrap/dbwrap.h
+++ b/lib/dbwrap/dbwrap.h
@@ -27,6 +27,10 @@ struct db_context;
 
 enum dbwrap_lock_order {
 	DBWRAP_LOCK_ORDER_NONE = 0, /* Don't check lock orders for this db. */
+	/*
+	 * We only allow orders 1, 2, 3:
+	 * These are the orders that CTDB currently supports.
+	 */
 	DBWRAP_LOCK_ORDER_1 = 1,
 	DBWRAP_LOCK_ORDER_2 = 2,
 	DBWRAP_LOCK_ORDER_3 = 3
-- 
1.8.3.2


From e43bb62b6fc810baf2751ea8637146cdcd35f83a Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 27 Jan 2014 17:34:31 +0100
Subject: [PATCH 20/21] dbwrap: completely check validity of lock order in
 dbwrap_check_lock_order()

This is currently not strictly necessay, because the
only caller catches the DBWRAP_LOCK_ORDER_NONE case,
and maximum is already checked,  but this seems too dangerous to me.

Use the new DBWRAP_LOCK_ORDER_VALID() macro.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 lib/dbwrap/dbwrap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/dbwrap/dbwrap.c b/lib/dbwrap/dbwrap.c
index 3606617..d75c714 100644
--- a/lib/dbwrap/dbwrap.c
+++ b/lib/dbwrap/dbwrap.c
@@ -167,7 +167,7 @@ static struct dbwrap_lock_order_state *dbwrap_check_lock_order(
 	static struct db_context *locked_dbs[DBWRAP_LOCK_ORDER_MAX];
 	struct dbwrap_lock_order_state *state = NULL;
 
-	if (db->lock_order > DBWRAP_LOCK_ORDER_MAX) {
+	if (!DBWRAP_LOCK_ORDER_VALID(db->lock_order)) {
 		DEBUG(0,("Invalid lock order %d of %s\n",
 			 (int)db->lock_order, db->name));
 		smb_panic("invalid lock_order\n");
-- 
1.8.3.2


From 6db7bacb6d63d0119f36a4fecada966057d3c3ef Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 28 Jan 2014 11:58:05 +0100
Subject: [PATCH 21/21] dbwrap: use DBWRAP_LOCK_ORDER_VALID() in db_open()

instead of the hand written test.

Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/lib/dbwrap/dbwrap_open.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/source3/lib/dbwrap/dbwrap_open.c b/source3/lib/dbwrap/dbwrap_open.c
index ee5ec74..3c8756b 100644
--- a/source3/lib/dbwrap/dbwrap_open.c
+++ b/source3/lib/dbwrap/dbwrap_open.c
@@ -68,15 +68,7 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
 	const char *sockname;
 #endif
 
-	switch (lock_order) {
-	case DBWRAP_LOCK_ORDER_1:
-	case DBWRAP_LOCK_ORDER_2:
-	case DBWRAP_LOCK_ORDER_3:
-		break;
-	default:
-		/*
-		 * Only allow the 3 levels ctdb gives us.
-		 */
+	if (!DBWRAP_LOCK_ORDER_VALID(lock_order)) {
 		errno = EINVAL;
 		return NULL;
 	}
-- 
1.8.3.2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 215 bytes
Desc: Digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20140206/2b72d3db/attachment.pgp>


More information about the samba-technical mailing list