[SCM] Samba Shared Repository - branch master updated

Rusty Russell rusty at samba.org
Fri Jun 22 01:23:02 MDT 2012


The branch, master has been updated
       via  3c4263e tdb: don't use err.h in tests.
       via  1783fe3 tdb: make TDB_NOSYNC merely disable sync.
       via  945473a dbwrap: dbwrap_hash_size().
       via  e92cb55 dbwrap: dbwrap_name().
       via  41f799d dbwrap: dbwrap_transaction_start_nonblock().
       via  f6eb187 dbwrap: dbwrap_fetch_locked_timeout().
       via  431667b dbwrap: add dbwrap_check() function.
       via  9d97bf3 dbwrap: dbwrap_local_open()
       via  1acf548 dbwrap: remove get_flags().
       via  fc9b298 util_tdb: move timeout chainlock variants from source3/lib/util/util_tdb.c
       via  02bacf1 util: util_ntdb ntdb_fetch_int32/ntdb_store_int32 and ntdb_add_int32_atomic
       via  348159d util: util_ntdb.c gets NTDB_ERROR => NTSTATUS map.
       via  88ad365 util: util_ntdb.c gains bystring functions.
       via  8113d53 util: ntdb_new() supports NTDB_CLEAR_IF_FIRST.
       via  735290f util: util_ntdb.c
       via  7c1d9fb ntdb: take advantage of direct access across expand.
       via  4c51ee1 ntdb: test arbitrary operations during ntdb_parse_record().
       via  01ec4a7 ntdb: make database read-only during ntdb_parse() callback.
       via  bd5c061 ntdb: allow direct access for NTDB_INTERNAL dbs during expansion.
       via  0a34f34 ntdb: enhancement to allow direct access to the ntdb map during expansion.
       via  66d151d ntdb: don't munmap the database on every close.
       via  406bd2d ntdb: hand correct error code when alloc_read allocation fails.
       via  f7f6992c autobuild: always set TDB_NO_FSYNC.
       via  0265837 ntdb: respect TDB_NO_FSYNC flag for 'make test'
      from  0c54e7c s4:torture/smb2: add smb2.durable-open.lock-oplock

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


- Log -----------------------------------------------------------------
commit 3c4263e7580143c69225729f5b67f09c00add2fd
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:44 2012 +0930

    tdb: don't use err.h in tests.
    
    It's not portable.  While we could use ccan/err, it seems overkill since
    we actually only use it in one test (I obviously cut & paste the #include).
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>
    
    Autobuild-User(master): Rusty Russell <rusty at rustcorp.com.au>
    Autobuild-Date(master): Fri Jun 22 09:22:28 CEST 2012 on sn-devel-104

commit 1783fe34433f9bb4b939de3231a7c296390ec426
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:44 2012 +0930

    tdb: make TDB_NOSYNC merely disable sync.
    
    (As suggested by Stefan Metzmacher, based on the change to ntdb.)
    
    Since commit ec96ea690edbe3398d690b4a953d487ca1773f1c, we handle the case
    where a process dies during a transaction commit.  Unfortunately, TDB_NOSYNC
    means this no longer works, as it disables the recovery area as well as the
    actual msync/fsync.  We should do everything except the syncs.
    
    This also means we can do a complete test with $TDB_NO_FSYNC set; just
    to get more complete coverage, we disable it explicitly for one test
    (where we override the actual sync calls anyway).
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 945473aac0abffd8509bbeef3ed5a32737b7df51
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:44 2012 +0930

    dbwrap: dbwrap_hash_size().
    
    Implemented for ntdb and tdb; falls back to 0 for others.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit e92cb556fdb5faee71f614475aaade846dcd0aed
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:44 2012 +0930

    dbwrap: dbwrap_name().
    
    Useful for debug messages: particularly once we start switching between .tdb
    and .ntdb files.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 41f799d877961d095401a628307e0c690dfbc124
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:44 2012 +0930

    dbwrap: dbwrap_transaction_start_nonblock().
    
    Implemented for ntdb and tdb; falls back to the blocking variant
    for others.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit f6eb187fdab6b8088bb065e418fe604c4eba7751
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:44 2012 +0930

    dbwrap: dbwrap_fetch_locked_timeout().
    
    Implemented for ntdb and tdb; falls back to the non-timeout variant
    for others.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 431667b47c0eac3069ba1e643996619ab61975e5
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:43 2012 +0930

    dbwrap: add dbwrap_check() function.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 9d97bf3f47a591a71e96cad8a87ef13a2b277c9c
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:43 2012 +0930

    dbwrap: dbwrap_local_open()
    
    This simply opens a tdb: it will eventually switch depending on the
    extension.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 1acf548eb75c9641e4e2c07167b42bc4380f9158
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:43 2012 +0930

    dbwrap: remove get_flags().
    
    The flags returned were TDB-specific: this was only used for detecting
    the endianness of obsolete databases (the conversion code was put in in
    2003, with reference to Samba 2.3).
    
    It's easier to remove it than to translate the NTDB flags to TDB flags,
    and it's a really weird thing to ask for anyway.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit fc9b2987611d7535b92288b26b09db19a0e2d78e
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 15:07:36 2012 +0930

    util_tdb: move timeout chainlock variants from source3/lib/util/util_tdb.c
    
    We're about to use them for dbwrap.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 02bacf1f95046163dfb5afb40f33b37ccdf1f374
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:42 2012 +0930

    util: util_ntdb ntdb_fetch_int32/ntdb_store_int32 and ntdb_add_int32_atomic
    
    Similar to the util_tdb versions, but return the error code.
    
    ntdb_add_int32_atomic seems a clearer name than tdb_change_int32_atomic.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 348159d1e4c11c330a75600269b1d45be70d8bb2
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:41 2012 +0930

    util: util_ntdb.c gets NTDB_ERROR => NTSTATUS map.
    
    Very similar to the tdb version.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 88ad365caf7811772b754bc00e5ca3d0b92812ea
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:41 2012 +0930

    util: util_ntdb.c gains bystring functions.
    
    Very similar to the util_tdb versions, but these return the error.
    I've only implemented those functions actually used.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 8113d53bb421217040a8184ba00f61308e8959d6
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:41 2012 +0930

    util: ntdb_new() supports NTDB_CLEAR_IF_FIRST.
    
    There are various issues with NTDB_CLEAR_IF_FIRST which makes it
    better if we don't have to use it, but much of the code does, so
    we fake up support here.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 735290f474a34986be4c66eb0bdf0b0ba14da970
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:41 2012 +0930

    util: util_ntdb.c
    
    The first function is ntdb_new: this is preferred over ntdb_open, as
    it makes the ntdb_context returned (and all NTDB_DATA returned from
    ntdb_fetch) valid talloc pointers.
    
    The API is very similar to tdb_wrap_open().
    
    Note that we handle $TDB_NO_FSYNC here, since ntdb doesn't do that
    hack (and it's great for speeding up testing!).
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 7c1d9fb3c12d20779afe8293b6a867bd2061077f
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:41 2012 +0930

    ntdb: take advantage of direct access across expand.
    
    This means we no longer have to unmap if we want to compare a record.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 4c51ee1116c983ceef3804d79954aafad1b935ad
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:41 2012 +0930

    ntdb: test arbitrary operations during ntdb_parse_record().
    
    In particular, this tests that we can store enough records to make the
    database expand while we map the given record.  We use a global lock for
    this, but it could happen in theory with another process.
    
    It also tests the that we can recurse inside ntdb_parse_record().
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 01ec4a72de56ade54bbbc92e0a408771390c5c12
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:41 2012 +0930

    ntdb: make database read-only during ntdb_parse() callback.
    
    Since we have a readlock, any write will grab a write lock: if it happens
    to be on the same bucket, we'll fail.
    
    For that reason, enforce read-only so every write operation fails
    (even for NTDB_NOLOCK or NTDB_INTERNAL dbs), and document it!
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit bd5c061932d9aaf2e66cd56a39743c9ff34c3a88
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:40 2012 +0930

    ntdb: allow direct access for NTDB_INTERNAL dbs during expansion.
    
    NTDB_INTERNAL databases need to malloc and copy to keep old versions
    around if we expand, in a similar way to the manner in which keep old
    mmaps around.
    
    Of course, it only works for read-only accesses, since the two copies
    are not synced.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 0a34f342c3facace0767ff08f05532c9f161e305
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:40 2012 +0930

    ntdb: enhancement to allow direct access to the ntdb map during expansion.
    
    This means keeping the old mmap around when we expand the database.
    We could revert to read/write, except for platforms with incoherent
    mmap (ie. OpenBSD), where we need to use mmap for all accesses.
    
    Thus we keep a linked list of old maps, and unmap them when the last access
    finally goes away.
    
    This is required if we want ntdb_parse_record() callbacks to be able
    to expand the database.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 66d151d6893657b31c419d422bffeefc506e2319
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:40 2012 +0930

    ntdb: don't munmap the database on every close.
    
    Since we can have multiple openers, we should leave the mmap in place
    for the other openers to use.  Enhance the test to check the bug (it
    still works, because without mmap we fall back to read/write, but
    performance would be terrible!).
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 406bd2d121c3eeef7c3bb6bc74c7a6ccbe296c38
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:40 2012 +0930

    ntdb: hand correct error code when alloc_read allocation fails.
    
    -ECUTNPASTE.  This is not a usage error!
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit f7f6992c1e6ee8ac4a55c2fddf169ac695362036
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:44:36 2012 +0930

    autobuild: always set TDB_NO_FSYNC.
    
    Then we unset it inside the tdb test target itself.  This means that
    new code can't accidently forget it, and we can set it in the
    'buildnice' script on sn-devel, for example.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 0265837ee8ab98b00c18411bee3770075e27f900
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Jun 22 09:17:13 2012 +0930

    ntdb: respect TDB_NO_FSYNC flag for 'make test'
    
    This reduces test time from 31 seconds to 6, on my laptop.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

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

Summary of changes:
 lib/dbwrap/dbwrap.c                            |   71 +++++-
 lib/dbwrap/dbwrap.h                            |   26 ++-
 lib/dbwrap/dbwrap_cache.c                      |   10 +-
 lib/dbwrap/dbwrap_file.c                       |    2 +
 lib/dbwrap/dbwrap_local_open.c                 |   70 +++++
 lib/dbwrap/dbwrap_private.h                    |    9 +-
 lib/dbwrap/dbwrap_rbt.c                        |    2 +
 lib/dbwrap/dbwrap_tdb.c                        |   50 +++-
 lib/dbwrap/wscript_build                       |    1 +
 lib/ntdb/doc/TDB_porting.txt                   |   91 +++++--
 lib/ntdb/free.c                                |    3 -
 lib/ntdb/hash.c                                |   48 +---
 lib/ntdb/io.c                                  |  119 +++++++--
 lib/ntdb/lock.c                                |   11 +-
 lib/ntdb/ntdb.c                                |   23 ++-
 lib/ntdb/ntdb.h                                |    9 +-
 lib/ntdb/open.c                                |   29 +-
 lib/ntdb/private.h                             |   19 +-
 lib/ntdb/test/api-12-store.c                   |    4 +-
 lib/ntdb/test/api-13-delete.c                  |    6 +-
 lib/ntdb/test/api-14-exists.c                  |    2 +-
 lib/ntdb/test/api-16-wipe_all.c                |    2 +-
 lib/ntdb/test/api-20-alloc-attr.c              |    2 +-
 lib/ntdb/test/api-21-parse_record.c            |    5 +-
 lib/ntdb/test/api-55-transaction.c             |    5 +-
 lib/ntdb/test/api-80-tdb_fd.c                  |    2 +-
 lib/ntdb/test/api-81-seqnum.c                  |    5 +-
 lib/ntdb/test/api-82-lockattr.c                |   16 +-
 lib/ntdb/test/api-83-openhook.c                |    8 +-
 lib/ntdb/test/api-91-get-stats.c               |    4 +-
 lib/ntdb/test/api-92-get-set-readonly.c        |   10 +-
 lib/ntdb/test/api-93-repack.c                  |    5 +-
 lib/ntdb/test/api-94-expand-during-parse.c     |   89 ++++++
 lib/ntdb/test/api-95-read-only-during-parse.c  |   94 +++++++
 lib/ntdb/test/api-add-remove-flags.c           |    5 +-
 lib/ntdb/test/api-check-callback.c             |    5 +-
 lib/ntdb/test/api-firstkey-nextkey.c           |    7 +-
 lib/ntdb/test/api-fork-test.c                  |    5 +-
 lib/ntdb/test/api-locktimeout.c                |    5 +-
 lib/ntdb/test/api-missing-entries.c            |    2 +-
 lib/ntdb/test/api-open-multiple-times.c        |   20 +-
 lib/ntdb/test/api-record-expand.c              |    5 +-
 lib/ntdb/test/api-simple-delete.c              |    5 +-
 lib/ntdb/test/api-summary.c                    |    4 +-
 lib/ntdb/test/external-agent.c                 |    4 +-
 lib/ntdb/test/no-fsync.h                       |    6 +
 lib/ntdb/test/run-01-new_database.c            |    4 +-
 lib/ntdb/test/run-02-expand.c                  |    4 +-
 lib/ntdb/test/run-03-coalesce.c                |   20 +-
 lib/ntdb/test/run-04-basichash.c               |    4 +-
 lib/ntdb/test/run-05-readonly-open.c           |   12 +-
 lib/ntdb/test/run-10-simple-store.c            |    5 +-
 lib/ntdb/test/run-11-simple-fetch.c            |    5 +-
 lib/ntdb/test/run-12-check.c                   |    4 +-
 lib/ntdb/test/run-15-append.c                  |   12 +-
 lib/ntdb/test/run-25-hashoverload.c            |    5 +-
 lib/ntdb/test/run-30-exhaust-before-expand.c   |    5 +-
 lib/ntdb/test/run-35-convert.c                 |   14 +-
 lib/ntdb/test/run-56-open-during-transaction.c |    4 +-
 lib/ntdb/test/run-57-die-during-transaction.c  |    4 +-
 lib/ntdb/test/run-64-bit-tdb.c                 |    4 +-
 lib/ntdb/test/run-90-get-set-attributes.c      |   12 +-
 lib/ntdb/test/run-capabilities.c               |   30 +-
 lib/ntdb/test/run-expand-in-transaction.c      |    5 +-
 lib/ntdb/test/run-features.c                   |    8 +-
 lib/ntdb/test/run-lockall.c                    |    4 +-
 lib/ntdb/test/run-remap-in-read_traverse.c     |    2 +-
 lib/ntdb/test/run-seed.c                       |    2 +-
 lib/ntdb/test/run-tdb_foreach.c                |   20 +-
 lib/ntdb/test/run-traverse.c                   |    4 +-
 lib/ntdb/test/tap-interface.h                  |    1 +
 lib/ntdb/wscript                               |    2 +
 lib/tdb/common/transaction.c                   |   17 +-
 lib/tdb/test/external-agent.c                  |    3 +-
 lib/tdb/test/run-3G-file.c                     |    1 -
 lib/tdb/test/run-bad-tdb-header.c              |    1 -
 lib/tdb/test/run-check.c                       |    1 -
 lib/tdb/test/run-corrupt.c                     |    1 -
 lib/tdb/test/run-die-during-transaction.c      |    1 -
 lib/tdb/test/run-endian.c                      |    1 -
 lib/tdb/test/run-incompatible.c                |    1 -
 lib/tdb/test/run-nested-transactions.c         |    1 -
 lib/tdb/test/run-nested-traverse.c             |    1 -
 lib/tdb/test/run-no-lock-during-traverse.c     |    1 -
 lib/tdb/test/run-oldhash.c                     |    1 -
 lib/tdb/test/run-open-during-transaction.c     |    1 -
 lib/tdb/test/run-readonly-check.c              |    1 -
 lib/tdb/test/run-rwlock-check.c                |    1 -
 lib/tdb/test/run-summary.c                     |    1 -
 lib/tdb/test/run-transaction-expand.c          |   15 +-
 lib/tdb/test/run-traverse-in-transaction.c     |    1 -
 lib/tdb/test/run-wronghash-fail.c              |    1 -
 lib/tdb/test/run-zero-append.c                 |    1 -
 lib/tdb/test/run.c                             |    1 -
 lib/util/util_ntdb.c                           |  346 ++++++++++++++++++++++++
 lib/util/util_ntdb.h                           |  135 +++++++++
 lib/util/util_tdb.c                            |   79 ++++++
 lib/util/util_tdb.h                            |   18 ++
 lib/util/wscript_build                         |    9 +-
 script/autobuild.py                            |   10 +-
 source3/Makefile.in                            |   26 ++-
 source3/include/util_tdb.h                     |    7 -
 source3/lib/dbwrap/dbwrap_ctdb.c               |    8 -
 source3/lib/dbwrap/dbwrap_open.c               |    6 +-
 source3/lib/util_tdb.c                         |   81 ------
 source3/winbindd/idmap_tdb.c                   |   19 +--
 106 files changed, 1486 insertions(+), 433 deletions(-)
 create mode 100644 lib/dbwrap/dbwrap_local_open.c
 create mode 100644 lib/ntdb/test/api-94-expand-during-parse.c
 create mode 100644 lib/ntdb/test/api-95-read-only-during-parse.c
 create mode 100644 lib/ntdb/test/no-fsync.h
 create mode 100644 lib/util/util_ntdb.c
 create mode 100644 lib/util/util_ntdb.h


Changeset truncated at 500 lines:

diff --git a/lib/dbwrap/dbwrap.c b/lib/dbwrap/dbwrap.c
index dbf10f7..4c0160a 100644
--- a/lib/dbwrap/dbwrap.c
+++ b/lib/dbwrap/dbwrap.c
@@ -50,6 +50,19 @@ static int dbwrap_fallback_wipe(struct db_context *db)
 	return NT_STATUS_IS_OK(status) ? 0 : -1;
 }
 
+static int do_nothing(struct db_record *rec, void *unused)
+{
+	return 0;
+}
+
+/*
+ * Fallback check operation: just traverse.
+ */
+static int dbwrap_fallback_check(struct db_context *db)
+{
+	NTSTATUS status = dbwrap_traverse_read(db, do_nothing, NULL, NULL);
+	return NT_STATUS_IS_OK(status) ? 0 : -1;
+}
 
 /*
  * Wrapper functions for the backend methods
@@ -218,6 +231,33 @@ struct db_record *dbwrap_try_fetch_locked(struct db_context *db,
 		? db->try_fetch_locked : db->fetch_locked);
 }
 
+struct db_record *dbwrap_fetch_locked_timeout(struct db_context *db,
+					      TALLOC_CTX *mem_ctx,
+					      TDB_DATA key,
+					      unsigned int timeout)
+{
+	struct db_record *rec;
+	struct dbwrap_lock_order_state *lock_order;
+	TALLOC_CTX *frame = talloc_stackframe();
+
+	lock_order = dbwrap_check_lock_order(db, frame);
+	if (lock_order == NULL) {
+		TALLOC_FREE(frame);
+		return NULL;
+	}
+	rec = db->fetch_locked_timeout
+		? db->fetch_locked_timeout(db, mem_ctx, key, timeout)
+		: db->fetch_locked(db, mem_ctx, key);
+	if (rec == NULL) {
+		TALLOC_FREE(frame);
+		return NULL;
+	}
+	(void)talloc_steal(rec, lock_order);
+	rec->db = db;
+	TALLOC_FREE(frame);
+	return rec;
+}
+
 struct db_context *dbwrap_record_get_db(struct db_record *rec)
 {
 	return rec->db;
@@ -367,14 +407,22 @@ int dbwrap_wipe(struct db_context *db)
 	return db->wipe(db);
 }
 
-int dbwrap_get_seqnum(struct db_context *db)
+int dbwrap_hash_size(struct db_context *db)
 {
-	return db->get_seqnum(db);
+	return db->hash_size;
+}
+
+int dbwrap_check(struct db_context *db)
+{
+	if (db->check == NULL) {
+		return dbwrap_fallback_check(db);
+	}
+	return db->check(db);
 }
 
-int dbwrap_get_flags(struct db_context *db)
+int dbwrap_get_seqnum(struct db_context *db)
 {
-	return db->get_flags(db);
+	return db->get_seqnum(db);
 }
 
 int dbwrap_transaction_start(struct db_context *db)
@@ -382,6 +430,16 @@ int dbwrap_transaction_start(struct db_context *db)
 	return db->transaction_start(db);
 }
 
+NTSTATUS dbwrap_transaction_start_nonblock(struct db_context *db)
+{
+	if (db->transaction_start_nonblock) {
+		return db->transaction_start_nonblock(db);
+	} else {
+		return dbwrap_transaction_start(db) == 0 ? NT_STATUS_OK
+			: NT_STATUS_UNSUCCESSFUL;
+	}
+}
+
 int dbwrap_transaction_commit(struct db_context *db)
 {
 	return db->transaction_commit(db);
@@ -396,3 +454,8 @@ void dbwrap_db_id(struct db_context *db, const uint8_t **id, size_t *idlen)
 {
 	db->id(db, id, idlen);
 }
+
+const char *dbwrap_name(struct db_context *db)
+{
+	return db->name;
+}
diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h
index db2cfa1..30c24fe 100644
--- a/lib/dbwrap/dbwrap.h
+++ b/lib/dbwrap/dbwrap.h
@@ -43,6 +43,11 @@ struct db_record *dbwrap_fetch_locked(struct db_context *db,
 struct db_record *dbwrap_try_fetch_locked(struct db_context *db,
 					  TALLOC_CTX *mem_ctx,
 					  TDB_DATA key);
+struct db_record *dbwrap_fetch_locked_timeout(struct db_context *db,
+					      TALLOC_CTX *mem_ctx,
+					      TDB_DATA key,
+					      unsigned int timeout);
+
 struct db_context *dbwrap_record_get_db(struct db_record *rec);
 void dbwrap_set_stored_callback(
 	struct db_context *db,
@@ -69,13 +74,16 @@ NTSTATUS dbwrap_parse_record(struct db_context *db, TDB_DATA key,
 					    void *private_data),
 			     void *private_data);
 int dbwrap_wipe(struct db_context *db);
+int dbwrap_check(struct db_context *db);
 int dbwrap_get_seqnum(struct db_context *db);
-int dbwrap_get_flags(struct db_context *db);
+/* Returns 0 if unknown. */
+int dbwrap_hash_size(struct db_context *db);
 int dbwrap_transaction_start(struct db_context *db);
+NTSTATUS dbwrap_transaction_start_nonblock(struct db_context *db);
 int dbwrap_transaction_commit(struct db_context *db);
 int dbwrap_transaction_cancel(struct db_context *db);
 void dbwrap_db_id(struct db_context *db, const uint8_t **id, size_t *idlen);
-
+const char *dbwrap_name(struct db_context *db);
 
 /* The following definitions come from lib/dbwrap_util.c  */
 
@@ -134,4 +142,18 @@ NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
 NTSTATUS dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx,
 				     const char *key, TDB_DATA *value);
 
+/**
+ * This opens an ntdb or tdb file: you can hand it a .ntdb or .tdb extension
+ * and it will decide (based on parameter settings, or else what exists) which
+ * to use.
+ *
+ * For backwards compatibility, it takes tdb-style open flags, not ntdb!
+ */
+struct db_context *dbwrap_local_open(TALLOC_CTX *mem_ctx,
+				     struct loadparm_context *lp_ctx,
+				     const char *name,
+				     int hash_size, int tdb_flags,
+				     int open_flags, mode_t mode,
+				     enum dbwrap_lock_order lock_order);
+
 #endif /* __DBWRAP_H__ */
diff --git a/lib/dbwrap/dbwrap_cache.c b/lib/dbwrap/dbwrap_cache.c
index 865fcff..f2a9c5f 100644
--- a/lib/dbwrap/dbwrap_cache.c
+++ b/lib/dbwrap/dbwrap_cache.c
@@ -131,13 +131,6 @@ static int dbwrap_cache_get_seqnum(struct db_context *db)
 	return dbwrap_get_seqnum(ctx->backing);
 }
 
-static int dbwrap_cache_get_flags(struct db_context *db)
-{
-	struct db_cache_ctx *ctx = talloc_get_type_abort(
-		db->private_data, struct db_cache_ctx);
-	return dbwrap_get_flags(ctx->backing);
-}
-
 static int dbwrap_cache_transaction_start(struct db_context *db)
 {
 	struct db_cache_ctx *ctx = talloc_get_type_abort(
@@ -210,13 +203,14 @@ struct db_context *db_open_cache(TALLOC_CTX *mem_ctx,
 	db->traverse = dbwrap_cache_traverse;
 	db->traverse_read = dbwrap_cache_traverse_read;
 	db->get_seqnum = dbwrap_cache_get_seqnum;
-	db->get_flags = dbwrap_cache_get_flags;
 	db->transaction_start = dbwrap_cache_transaction_start;
 	db->transaction_commit = dbwrap_cache_transaction_commit;
 	db->transaction_cancel = dbwrap_cache_transaction_cancel;
 	db->parse_record = dbwrap_cache_parse_record;
 	db->exists = dbwrap_cache_exists;
 	db->id = dbwrap_cache_id;
+	db->name = dbwrap_name(ctx->backing);
+	db->hash_size = dbwrap_hash_size(ctx->backing);
 	db->stored_callback = NULL;
 	db->wipe = NULL;
 	db->lock_order = 0;
diff --git a/lib/dbwrap/dbwrap_file.c b/lib/dbwrap/dbwrap_file.c
index e0fd4eb..54ed320 100644
--- a/lib/dbwrap/dbwrap_file.c
+++ b/lib/dbwrap/dbwrap_file.c
@@ -372,6 +372,8 @@ struct db_context *db_open_file(TALLOC_CTX *mem_ctx,
 	result->traverse = db_file_traverse;
 	result->traverse_read = db_file_traverse;
 	result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
+	result->name = name;
+	result->hash_size = 0;
 
 	ctx->locked_record = NULL;
 	if (!(ctx->dirname = talloc_strdup(ctx, name))) {
diff --git a/lib/dbwrap/dbwrap_local_open.c b/lib/dbwrap/dbwrap_local_open.c
new file mode 100644
index 0000000..bb0df48
--- /dev/null
+++ b/lib/dbwrap/dbwrap_local_open.c
@@ -0,0 +1,70 @@
+/*
+   Unix SMB/CIFS implementation.
+   Database interface wrapper: local open code.
+
+   Copyright (C) Rusty Russell 2012
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "dbwrap/dbwrap.h"
+#include "dbwrap/dbwrap_tdb.h"
+#include "tdb.h"
+#include "lib/util/util_ntdb.h"
+#include "lib/param/param.h"
+#include "system/filesys.h"
+#include "ccan/str/str.h"
+
+struct db_context *dbwrap_local_open(TALLOC_CTX *mem_ctx,
+				     struct loadparm_context *lp_ctx,
+				     const char *name,
+				     int hash_size, int tdb_flags,
+				     int open_flags, mode_t mode,
+				     enum dbwrap_lock_order lock_order)
+{
+	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	const char *ntdbname, *tdbname;
+	struct db_context *db = NULL;
+
+	/* Get both .ntdb and .tdb variants of the name. */
+	if (!name) {
+		tdbname = ntdbname = "unnamed database";
+	} else if (strends(name, ".tdb")) {
+		tdbname = name;
+		ntdbname = talloc_asprintf(tmp_ctx,
+					   "%.*s.ntdb",
+					   (int)strlen(name) - 4, name);
+	} else if (strends(name, ".ntdb")) {
+		ntdbname = name;
+		tdbname = talloc_asprintf(tmp_ctx,
+					  "%.*s.tdb",
+					  (int)strlen(name) - 5, name);
+	} else {
+		ntdbname = tdbname = name;
+	}
+
+	if (ntdbname == NULL || tdbname == NULL) {
+		DEBUG(0, ("talloc failed\n"));
+		goto out;
+	}
+
+	/* We currently always open a tdb, not an ntdb. */
+	db = db_open_tdb(mem_ctx, lp_ctx, tdbname, hash_size,
+			 tdb_flags, open_flags, mode,
+			 lock_order);
+out:
+	talloc_free(tmp_ctx);
+	return db;
+}
diff --git a/lib/dbwrap/dbwrap_private.h b/lib/dbwrap/dbwrap_private.h
index c197ffa..d49a568 100644
--- a/lib/dbwrap/dbwrap_private.h
+++ b/lib/dbwrap/dbwrap_private.h
@@ -38,6 +38,10 @@ struct db_context {
 	struct db_record *(*try_fetch_locked)(struct db_context *db,
 					      TALLOC_CTX *mem_ctx,
 					      TDB_DATA key);
+	struct db_record *(*fetch_locked_timeout)(struct db_context *db,
+						  TALLOC_CTX *mem_ctx,
+						  TDB_DATA key,
+						  unsigned int timeout);
 	int (*traverse)(struct db_context *db,
 			int (*f)(struct db_record *rec,
 				 void *private_data),
@@ -47,8 +51,8 @@ struct db_context {
 				      void *private_data),
 			     void *private_data);
 	int (*get_seqnum)(struct db_context *db);
-	int (*get_flags)(struct db_context *db);
 	int (*transaction_start)(struct db_context *db);
+	NTSTATUS (*transaction_start_nonblock)(struct db_context *db);
 	int (*transaction_commit)(struct db_context *db);
 	int (*transaction_cancel)(struct db_context *db);
 	NTSTATUS (*parse_record)(struct db_context *db, TDB_DATA key,
@@ -57,7 +61,10 @@ struct db_context {
 				 void *private_data);
 	int (*exists)(struct db_context *db,TDB_DATA key);
 	int (*wipe)(struct db_context *db);
+	int (*check)(struct db_context *db);
 	void (*id)(struct db_context *db, const uint8_t **id, size_t *idlen);
+	const char *name;
+	int hash_size;
 	void *private_data;
 	enum dbwrap_lock_order lock_order;
 	bool persistent;
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
index d512eac..afe9974 100644
--- a/lib/dbwrap/dbwrap_rbt.c
+++ b/lib/dbwrap/dbwrap_rbt.c
@@ -506,6 +506,8 @@ struct db_context *db_open_rbt(TALLOC_CTX *mem_ctx)
 	result->parse_record = db_rbt_parse_record;
 	result->lock_order = 0;
 	result->id = db_rbt_id;
+	result->name = "dbwrap rbt";
+	result->hash_size = 0;
 	result->stored_callback = NULL;
 
 	return result;
diff --git a/lib/dbwrap/dbwrap_tdb.c b/lib/dbwrap/dbwrap_tdb.c
index 398d41a..80d41b4 100644
--- a/lib/dbwrap/dbwrap_tdb.c
+++ b/lib/dbwrap/dbwrap_tdb.c
@@ -24,6 +24,7 @@
 #include "lib/tdb_wrap/tdb_wrap.h"
 #include "lib/util/util_tdb.h"
 #include "system/filesys.h"
+#include "ccan/str/str.h"
 
 struct db_tdb_ctx {
 	struct tdb_wrap *wtdb;
@@ -157,6 +158,21 @@ static struct db_record *db_tdb_fetch_locked(
 	return db_tdb_fetch_locked_internal(db, mem_ctx, key);
 }
 
+static struct db_record *db_tdb_fetch_locked_timeout(
+	struct db_context *db, TALLOC_CTX *mem_ctx, TDB_DATA key,
+	unsigned int timeout)
+{
+	struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data,
+						       struct db_tdb_ctx);
+
+	db_tdb_log_key("Locking with timeout ", key);
+	if (tdb_chainlock_with_timeout(ctx->wtdb->tdb, key, timeout) != 0) {
+		DEBUG(3, ("tdb_chainlock_with_timeout failed\n"));
+		return NULL;
+	}
+	return db_tdb_fetch_locked_internal(db, mem_ctx, key);
+}
+
 static struct db_record *db_tdb_try_fetch_locked(
 	struct db_context *db, TALLOC_CTX *mem_ctx, TDB_DATA key)
 {
@@ -186,6 +202,13 @@ static int db_tdb_wipe(struct db_context *db)
 	return tdb_wipe_all(ctx->wtdb->tdb);
 }
 
+static int db_tdb_check(struct db_context *db)
+{
+	struct db_tdb_ctx *ctx = talloc_get_type_abort(
+		db->private_data, struct db_tdb_ctx);
+	return tdb_check(ctx->wtdb->tdb, NULL, NULL);
+}
+
 struct db_tdb_parse_state {
 	void (*parser)(TDB_DATA key, TDB_DATA data,
 		       void *private_data);
@@ -344,19 +367,24 @@ static int db_tdb_get_seqnum(struct db_context *db)
 	return tdb_get_seqnum(db_ctx->wtdb->tdb);
 }
 
-static int db_tdb_get_flags(struct db_context *db)
-
+static int db_tdb_transaction_start(struct db_context *db)
 {
 	struct db_tdb_ctx *db_ctx =
 		talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
-	return tdb_get_flags(db_ctx->wtdb->tdb);
+	return tdb_transaction_start(db_ctx->wtdb->tdb) ? -1 : 0;
 }
 
-static int db_tdb_transaction_start(struct db_context *db)
+static NTSTATUS db_tdb_transaction_start_nonblock(struct db_context *db)
 {
 	struct db_tdb_ctx *db_ctx =
 		talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
-	return tdb_transaction_start(db_ctx->wtdb->tdb) ? -1 : 0;
+	int ret;
+
+	ret = tdb_transaction_start_nonblock(db_ctx->wtdb->tdb);
+	if (ret != 0) {
+		return map_nt_error_from_tdb(tdb_error(db_ctx->wtdb->tdb));
+	}
+	return NT_STATUS_OK;
 }
 
 static int db_tdb_transaction_commit(struct db_context *db)
@@ -393,6 +421,12 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
 	struct db_tdb_ctx *db_tdb;
 	struct stat st;
 
+	/* Extra paranoia. */
+	if (name && strends(name, ".ntdb")) {
+		DEBUG(0, ("can't try to open %s with tdb!\n", name));
+		return NULL;
+	}
+
 	result = talloc_zero(mem_ctx, struct db_context);
 	if (result == NULL) {
 		DEBUG(0, ("talloc failed\n"));
@@ -423,20 +457,24 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
 	db_tdb->id.ino = st.st_ino;
 
 	result->fetch_locked = db_tdb_fetch_locked;
+	result->fetch_locked_timeout = db_tdb_fetch_locked_timeout;
 	result->try_fetch_locked = db_tdb_try_fetch_locked;
 	result->traverse = db_tdb_traverse;
 	result->traverse_read = db_tdb_traverse_read;
 	result->parse_record = db_tdb_parse;
 	result->get_seqnum = db_tdb_get_seqnum;
-	result->get_flags = db_tdb_get_flags;
 	result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
 	result->transaction_start = db_tdb_transaction_start;
+	result->transaction_start_nonblock = db_tdb_transaction_start_nonblock;
 	result->transaction_commit = db_tdb_transaction_commit;
 	result->transaction_cancel = db_tdb_transaction_cancel;
 	result->exists = db_tdb_exists;
 	result->wipe = db_tdb_wipe;
 	result->id = db_tdb_id;
+	result->check = db_tdb_check;
 	result->stored_callback = NULL;
+	result->name = tdb_name(db_tdb->wtdb->tdb);
+	result->hash_size = hash_size;
 	return result;
 
  fail:
diff --git a/lib/dbwrap/wscript_build b/lib/dbwrap/wscript_build
index d172efb..3b247b3 100644
--- a/lib/dbwrap/wscript_build
+++ b/lib/dbwrap/wscript_build
@@ -5,6 +5,7 @@ bld.SAMBA_LIBRARY('dbwrap',
                   dbwrap_rbt.c
                   dbwrap_cache.c
                   dbwrap_tdb.c
+                  dbwrap_local_open.c
                   ''',
                   deps='samba-util util_tdb errors tdb tdb-wrap',
                   private_library=True)
diff --git a/lib/ntdb/doc/TDB_porting.txt b/lib/ntdb/doc/TDB_porting.txt
index 8b0ca2f..5daf94b 100644
--- a/lib/ntdb/doc/TDB_porting.txt
+++ b/lib/ntdb/doc/TDB_porting.txt
@@ -170,23 +170,6 @@ Interface differences between TDB and NTDB.
 		                   O_CREAT|O_RDWR, 0600, &hashsize);
 	}
 
-- ntdb does locking on read-only databases (ie. O_RDONLY passed to ntdb_open).
-  tdb did not: use the NTDB_NOLOCK flag if you want to suppress locking.
-
-  Example:
-	#include <tdb.h>
-	#include <ntdb.h>
-
-	struct tdb_context *tdb_example(void)
-	{
-		return tdb_open("example.tdb", 0, TDB_DEFAULT, O_RDONLY, 0);
-	}
-
-	struct ntdb_context *ntdb_example(void)
-	{
-		return ntdb_open("example.ntdb", NTDB_NOLOCK, O_RDONLY, NULL);
-	}
-
 - ntdb's log function is simpler than tdb's log function.  The string
   is already formatted, is not terminated by a '\n', and it takes an
   enum ntdb_log_level not a tdb_debug_level, and which has only three
@@ -304,6 +287,80 @@ Interface differences between TDB and NTDB.
 		}
 	}
 
+- ntdb's ntdb_parse_record() takes a type-checked callback data
+  pointer, not a void * (though a void * pointer still works).  The


-- 
Samba Shared Repository


More information about the samba-cvs mailing list