diff options
Diffstat (limited to 'source3/tdb')
-rw-r--r-- | source3/tdb/README | 3 | ||||
-rw-r--r-- | source3/tdb/tdb.c | 225 | ||||
-rw-r--r-- | source3/tdb/tdb.h | 16 | ||||
-rw-r--r-- | source3/tdb/tdbtest.c | 6 | ||||
-rw-r--r-- | source3/tdb/tdbtool.c | 9 | ||||
-rw-r--r-- | source3/tdb/tdbtorture.c | 4 | ||||
-rw-r--r-- | source3/tdb/tdbutil.c | 4 |
7 files changed, 83 insertions, 184 deletions
diff --git a/source3/tdb/README b/source3/tdb/README index 3715c685c2..fac3eacb4d 100644 --- a/source3/tdb/README +++ b/source3/tdb/README @@ -60,8 +60,7 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, The hash size is advisory, use zero for a default value. - Return is NULL on error, in which case errno is also set. Don't - try to call tdb_error or tdb_errname, just do strerror(errno). + return is NULL on error possible tdb_flags are: TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index 3d4a6051d2..69e36ebd3e 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -35,7 +35,6 @@ #include <errno.h> #include <sys/mman.h> #include <sys/stat.h> -#include <stdarg.h> #include "tdb.h" #include "spinlock.h" #else @@ -150,12 +149,7 @@ struct list_struct { }; /* a byte range locking function - return 0 on success - this functions locks/unlocks 1 byte at the specified offset. - - On error, errno is also set so that errors are passed back properly - through tdb_open(). - - @param probe True to not emit errors if the lock fails. */ + this functions locks/unlocks 1 byte at the specified offset */ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, int rw_type, int lck_type, int probe) { @@ -163,10 +157,8 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, if (tdb->flags & TDB_NOLOCK) return 0; - if (tdb->read_only) { - errno = EACCES; + if (tdb->read_only) return -1; - } fl.l_type = rw_type; fl.l_whence = SEEK_SET; @@ -176,10 +168,9 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, if (fcntl(tdb->fd,lck_type,&fl)) { if (!probe) { - TDB_LOG((tdb, 5,"tdb_brlock failed at offset %d rw_type=%d lck_type=%d: %s\n", - offset, rw_type, lck_type, strerror(errno))); + TDB_LOG((tdb, 5,"tdb_brlock failed at offset %d rw_type=%d lck_type=%d\n", + offset, rw_type, lck_type)); } - /* errno set by fcntl */ return TDB_ERRCODE(TDB_ERR_LOCK, -1); } return 0; @@ -1372,202 +1363,134 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) return ret; } - -static int tdb_read_header(TDB_CONTEXT *tdb) -{ - int readlen = read(tdb->fd, &tdb->header, sizeof(tdb->header)); - - if (readlen == 0) { - /* file is just empty, still needs to be created */ - } else if (readlen == -1) { - TDB_LOG((tdb, 0, "tdb_read_header: failed to read tdb header of %s: %s\n", - tdb->name, strerror(errno))); - } else if (readlen != sizeof(tdb->header)) { - TDB_LOG((tdb, 0, "tdb_read_header: tdb header in %s is truncated at byte %d\n", - tdb->name, readlen)); - } else if (strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0) { - TDB_LOG((tdb, 0, "tdb_read_header: rotten food in %s\n", tdb->name)); - errno = EIO; - } else if (tdb->header.version != TDB_VERSION - && tdb->header.version != TDB_BYTEREV(TDB_VERSION)) { - TDB_LOG((tdb, 0, "tdb_read_header: bad version in header of %s: %#x\n", - tdb->name, tdb->header.version)); - } else { - return 1; - } - return 0; -} - - /* open the database, creating it if necessary The open_flags and mode are passed straight to the open call on the database file. A flags value of O_WRONLY is invalid. The hash size is advisory, use zero for a default value. - Return is NULL on error, in which case errno is also set. Don't - try to call tdb_error or tdb_errname, just do strerror(errno). */ + return is NULL on error */ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) { - return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL); -} - - -TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_func) -{ - TDB_CONTEXT tdb[1], *ret, *i; + TDB_CONTEXT tdb, *ret, *i; struct stat st; - int rev, locked; + int rev = 0, locked; - memset(tdb, 0, sizeof(tdb)); - tdb->fd = -1; - tdb->name = NULL; - tdb->map_ptr = NULL; - tdb->lockedkeys = NULL; - tdb->flags = tdb_flags; - tdb->open_flags = open_flags; - tdb_logging_function(tdb, log_func); + memset(&tdb, 0, sizeof(tdb)); + tdb.fd = -1; + tdb.name = NULL; + tdb.map_ptr = NULL; + tdb.lockedkeys = NULL; + tdb.flags = tdb_flags; + tdb.open_flags = open_flags; - if ((open_flags & O_ACCMODE) == O_WRONLY) { - TDB_LOG((tdb, 0, "tdb_open: tdb cannot be opened O_WRONLY\n")); - errno = EINVAL; + if ((open_flags & O_ACCMODE) == O_WRONLY) goto fail; - } - if (hash_size == 0) hash_size = DEFAULT_HASH_SIZE; if ((open_flags & O_ACCMODE) == O_RDONLY) { - tdb->read_only = 1; + tdb.read_only = 1; /* read only databases don't do locking or clear if first */ - tdb->flags |= TDB_NOLOCK; - tdb->flags &= ~TDB_CLEAR_IF_FIRST; + tdb.flags |= TDB_NOLOCK; + tdb.flags &= ~TDB_CLEAR_IF_FIRST; } /* internal databases don't mmap or lock, and start off cleared */ - if (tdb->flags & TDB_INTERNAL) { - tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - tdb_new_database(tdb, hash_size); + if (tdb.flags & TDB_INTERNAL) { + tdb.flags |= (TDB_NOLOCK | TDB_NOMMAP); + tdb.flags &= ~TDB_CLEAR_IF_FIRST; + tdb_new_database(&tdb, hash_size); goto internal; } - tdb->name = (char *)strdup(name); - if (!tdb->name) { - TDB_LOG((tdb, 0, "tdb_open: couldn't allocate memory for name\n")); - errno = ENOMEM; + if ((tdb.fd = open(name, open_flags, mode)) == -1) goto fail; - } - - if ((tdb->fd = open(name, open_flags, mode)) == -1) { - TDB_LOG((tdb, 0, "tdb_open: failed to open %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by open(2) */ - } /* ensure there is only one process initialising at once */ - if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) - goto fail; /* errno set by tdb_brlock */ + if (tdb_brlock(&tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) + goto fail; - /* We need to zero database if we are the only one with it - * open. Be quiet if the lock fails. */ - if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 1) == 0)) + /* we need to zero database if we are the only one with it open */ + if ((locked = (tdb_brlock(&tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0)) && (tdb_flags & TDB_CLEAR_IF_FIRST)) { open_flags |= O_CREAT; - if (ftruncate(tdb->fd, 0) == -1) { - TDB_LOG((tdb, 0, "tdb_open: couldn't truncate %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by ftruncate */ - } + if (ftruncate(tdb.fd, 0) == -1) + goto fail; } - - if (tdb_read_header(tdb)) { - rev = tdb->header.version = TDB_BYTEREV(TDB_VERSION); - } else { + + if (read(tdb.fd, &tdb.header, sizeof(tdb.header)) != sizeof(tdb.header) + || strcmp(tdb.header.magic_food, TDB_MAGIC_FOOD) != 0 + || (tdb.header.version != TDB_VERSION + && !(rev = (tdb.header.version==TDB_BYTEREV(TDB_VERSION))))) { /* its not a valid database - possibly initialise it */ - if (!(open_flags & O_CREAT)) { - TDB_LOG((tdb, 0, "tdb_open: database header not OK and O_CREAT not specified\n")); - errno = EIO; /* ie bad format or something */ - goto fail; - } else if (tdb_new_database(tdb, hash_size) == -1) { + if (!(open_flags & O_CREAT) || tdb_new_database(&tdb, hash_size) == -1) goto fail; - } - - rev = (tdb->flags & TDB_CONVERT); + rev = (tdb.flags & TDB_CONVERT); } - if (!rev) - tdb->flags &= ~TDB_CONVERT; + tdb.flags &= ~TDB_CONVERT; else { - tdb->flags |= TDB_CONVERT; - convert(&tdb->header, sizeof(tdb->header)); + tdb.flags |= TDB_CONVERT; + convert(&tdb.header, sizeof(tdb.header)); } - if (fstat(tdb->fd, &st) == -1) { - TDB_LOG((tdb, 0, "tdb_open: fstat of %s failed: %s\n", - name, strerror(errno))); + if (fstat(tdb.fd, &st) == -1) goto fail; - } /* Is it already in the open list? If so, fail. */ for (i = tdbs; i; i = i->next) { if (i->device == st.st_dev && i->inode == st.st_ino) { errno = EBUSY; - close(tdb->fd); + close(tdb.fd); return NULL; } } - tdb->map_size = st.st_size; - tdb->device = st.st_dev; - tdb->inode = st.st_ino; - tdb->locked = calloc(tdb->header.hash_size+1, sizeof(tdb->locked[0])); - if (!tdb->locked) { - errno = ENOMEM; + /* map the database and fill in the return structure */ + tdb.name = (char *)strdup(name); + if (!tdb.name) goto fail; - } - tdb_mmap(tdb); + tdb.map_size = st.st_size; + tdb.device = st.st_dev; + tdb.inode = st.st_ino; + tdb.locked = calloc(tdb.header.hash_size+1, sizeof(tdb.locked[0])); + if (!tdb.locked) + goto fail; + tdb_mmap(&tdb); if (locked) { - if (!tdb->read_only) - tdb_clear_spinlocks(tdb); - if (tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) + if (!tdb.read_only) + tdb_clear_spinlocks(&tdb); + if (tdb_brlock(&tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) goto fail; } /* leave this lock in place to indicate it's in use */ - if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) + if (tdb_brlock(&tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) goto fail; internal: - if (!(ret = malloc(sizeof(tdb)))) { - errno = ENOMEM; + if (!(ret = malloc(sizeof(tdb)))) goto fail; - } - *ret = *tdb; - if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1) + *ret = tdb; + if (tdb_brlock(&tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1) goto fail; ret->next = tdbs; tdbs = ret; return ret; fail: - { int save_errno = errno; - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - free(tdb->map_ptr); + if (tdb.map_ptr) { + if (tdb.flags & TDB_INTERNAL) + free(tdb.map_ptr); else - tdb_munmap(tdb); - } - if (tdb->name) - free(tdb->name); - if (tdb->fd != -1) - close(tdb->fd); - if (tdb->locked) - free(tdb->locked); - errno = save_errno; + tdb_munmap(&tdb); + } + if (tdb.name) + free(tdb.name); + if (tdb.fd != -1) + close(tdb.fd); + if (tdb.locked) + free(tdb.locked); return NULL; - } } /* close a database */ @@ -1694,16 +1617,6 @@ void tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key) } -void tdb_log_to_stderr(TDB_CONTEXT *tdb, int level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - fflush(stderr); -} - /* register a loging function */ void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)) { diff --git a/source3/tdb/tdb.h b/source3/tdb/tdb.h index 039c925702..4efe263ee8 100644 --- a/source3/tdb/tdb.h +++ b/source3/tdb/tdb.h @@ -99,17 +99,10 @@ typedef struct tdb_context { } TDB_CONTEXT; typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *); -typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...); - -int tdb_reopen(TDB_CONTEXT *tdb); -int tdb_reopen_all(void); -void tdb_log_to_stderr(TDB_CONTEXT *tdb, int level, const char *format, ...); -void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func fn); -TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_func); + TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode); +void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)); enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); const char *tdb_errorstr(TDB_CONTEXT *tdb); TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); @@ -128,11 +121,6 @@ void tdb_unlockall(TDB_CONTEXT *tdb); /* Low level locking functions: use with care */ int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); void tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); - -/* Debug functions. Not used in production. */ -void tdb_dump_all(TDB_CONTEXT *tdb); -void tdb_printfreelist(TDB_CONTEXT *tdb); - extern TDB_DATA tdb_null; #ifdef __cplusplus } diff --git a/source3/tdb/tdbtest.c b/source3/tdb/tdbtest.c index 7f3b1d48b7..cfc6135a0a 100644 --- a/source3/tdb/tdbtest.c +++ b/source3/tdb/tdbtest.c @@ -189,6 +189,7 @@ static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, void *state static void merge_test() { + int klen, dlen; int i; char keys[5][2]; TDB_DATA key, data; @@ -225,9 +226,8 @@ int main(int argc, char *argv[]) unlink("test.gdbm"); - db = tdb_open_ex("test.tdb", 0, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT | O_TRUNC, 0600, - tdb_log_to_stderr); + db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST, + O_RDWR | O_CREAT | O_TRUNC, 0600); gdbm = gdbm_open("test.gdbm", 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST, 0600, NULL); diff --git a/source3/tdb/tdbtool.c b/source3/tdb/tdbtool.c index a559fb0558..31ecd17a0c 100644 --- a/source3/tdb/tdbtool.c +++ b/source3/tdb/tdbtool.c @@ -29,7 +29,6 @@ #include <unistd.h> #include <string.h> #include <fcntl.h> -#include <time.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/time.h> @@ -174,9 +173,8 @@ static void create_tdb(void) return; } if (tdb) tdb_close(tdb); - tdb = tdb_open_ex(tok, 0, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT | O_TRUNC, 0600, - tdb_log_to_stderr); + tdb = tdb_open(tok, 0, TDB_CLEAR_IF_FIRST, + O_RDWR | O_CREAT | O_TRUNC, 0600); if (!tdb) { printf("Could not create %s: %s\n", tok, strerror(errno)); } @@ -190,7 +188,7 @@ static void open_tdb(void) return; } if (tdb) tdb_close(tdb); - tdb = tdb_open_ex(tok, 0, 0, O_RDWR, 0600, tdb_log_to_stderr); + tdb = tdb_open(tok, 0, 0, O_RDWR, 0600); if (!tdb) { printf("Could not open %s: %s\n", tok, strerror(errno)); } @@ -385,7 +383,6 @@ static void next_record(TDB_CONTEXT *tdb, TDB_DATA *pkey) print_rec(tdb, *pkey, dbuf, NULL); } - int main(int argc, char *argv[]) { int bIterate = 0; diff --git a/source3/tdb/tdbtorture.c b/source3/tdb/tdbtorture.c index 1cce60dc22..c76446b4fd 100644 --- a/source3/tdb/tdbtorture.c +++ b/source3/tdb/tdbtorture.c @@ -177,8 +177,8 @@ int main(int argc, char *argv[]) if ((pids[i+1]=fork()) == 0) break; } - db = tdb_open_ex("torture.tdb", 2, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT, 0600, tdb_log_to_stderr); + db = tdb_open("torture.tdb", 2, TDB_CLEAR_IF_FIRST, + O_RDWR | O_CREAT, 0600); if (!db) { fatal("db open failed"); } diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index 038d98eef9..68a47a199d 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/tdb/tdbutil.c @@ -355,8 +355,10 @@ TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags, if (!lp_use_mmap()) tdb_flags |= TDB_NOMMAP; tdb = tdb_open(name, hash_size, tdb_flags, - open_flags, mode, tdb_log); + open_flags, mode); if (!tdb) return NULL; + tdb_logging_function(tdb, tdb_log); + return tdb; } |