1 /* 2 Unix SMB/CIFS implementation. 3 4 trivial database library - private includes 5 6 Copyright (C) Andrew Tridgell 2005 7 8 ** NOTE! The following LGPL license applies to the tdb 9 ** library. This does NOT imply that all of Samba is released 10 ** under the LGPL 11 12 This library is free software; you can redistribute it and/or 13 modify it under the terms of the GNU Lesser General Public 14 License as published by the Free Software Foundation; either 15 version 3 of the License, or (at your option) any later version. 16 17 This library is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 Lesser General Public License for more details. 21 22 You should have received a copy of the GNU Lesser General Public 23 License along with this library; if not, see <http://www.gnu.org/licenses/>. 24*/ 25 26#include "replace.h" 27#include "system/filesys.h" 28#include "system/time.h" 29#include "system/shmem.h" 30#include "system/select.h" 31#include "system/wait.h" 32#include "tdb.h" 33 34/* #define TDB_TRACE 1 */ 35#ifndef HAVE_GETPAGESIZE 36#define getpagesize() 0x2000 37#endif 38 39typedef uint32_t tdb_len_t; 40typedef uint32_t tdb_off_t; 41 42#ifndef offsetof 43#define offsetof(t,f) ((unsigned int)&((t *)0)->f) 44#endif 45 46#define TDB_MAGIC_FOOD "TDB file\n" 47#define TDB_VERSION (0x26011967 + 6) 48#define TDB_MAGIC (0x26011999U) 49#define TDB_FREE_MAGIC (~TDB_MAGIC) 50#define TDB_DEAD_MAGIC (0xFEE1DEAD) 51#define TDB_RECOVERY_MAGIC (0xf53bc0e7U) 52#define TDB_ALIGNMENT 4 53#define DEFAULT_HASH_SIZE 131 54#define FREELIST_TOP (sizeof(struct tdb_header)) 55#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) 56#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) 57#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) 58#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) 59#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) 60#define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t)) 61#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) 62#define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) 63#define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) 64#define TDB_PAD_BYTE 0x42 65#define TDB_PAD_U32 0x42424242 66 67/* NB assumes there is a local variable called "tdb" that is the 68 * current context, also takes doubly-parenthesized print-style 69 * argument. */ 70#define TDB_LOG(x) tdb->log.log_fn x 71 72#ifdef TDB_TRACE 73void tdb_trace(struct tdb_context *tdb, const char *op); 74void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op); 75void tdb_trace_open(struct tdb_context *tdb, const char *op, 76 unsigned hash_size, unsigned tdb_flags, unsigned open_flags); 77void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret); 78void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret); 79void tdb_trace_1rec(struct tdb_context *tdb, const char *op, 80 TDB_DATA rec); 81void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op, 82 TDB_DATA rec, int ret); 83void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op, 84 TDB_DATA rec, TDB_DATA ret); 85void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op, 86 TDB_DATA rec1, TDB_DATA rec2, unsigned flag, 87 int ret); 88void tdb_trace_2rec_retrec(struct tdb_context *tdb, const char *op, 89 TDB_DATA rec1, TDB_DATA rec2, TDB_DATA ret); 90#else 91#define tdb_trace(tdb, op) 92#define tdb_trace_seqnum(tdb, seqnum, op) 93#define tdb_trace_open(tdb, op, hash_size, tdb_flags, open_flags) 94#define tdb_trace_ret(tdb, op, ret) 95#define tdb_trace_retrec(tdb, op, ret) 96#define tdb_trace_1rec(tdb, op, rec) 97#define tdb_trace_1rec_ret(tdb, op, rec, ret) 98#define tdb_trace_1rec_retrec(tdb, op, rec, ret) 99#define tdb_trace_2rec_flag_ret(tdb, op, rec1, rec2, flag, ret) 100#define tdb_trace_2rec_retrec(tdb, op, rec1, rec2, ret) 101#endif /* !TDB_TRACE */ 102 103/* lock offsets */ 104#define GLOBAL_LOCK 0 105#define ACTIVE_LOCK 4 106#define TRANSACTION_LOCK 8 107 108/* free memory if the pointer is valid and zero the pointer */ 109#ifndef SAFE_FREE 110#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) 111#endif 112 113#define BUCKET(hash) ((hash) % tdb->header.hash_size) 114 115#define DOCONV() (tdb->flags & TDB_CONVERT) 116#define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x) 117 118 119/* the body of the database is made of one tdb_record for the free space 120 plus a separate data list for each hash value */ 121struct tdb_record { 122 tdb_off_t next; /* offset of the next record in the list */ 123 tdb_len_t rec_len; /* total byte length of record */ 124 tdb_len_t key_len; /* byte length of key */ 125 tdb_len_t data_len; /* byte length of data */ 126 uint32_t full_hash; /* the full 32 bit hash of the key */ 127 uint32_t magic; /* try to catch errors */ 128 /* the following union is implied: 129 union { 130 char record[rec_len]; 131 struct { 132 char key[key_len]; 133 char data[data_len]; 134 } 135 uint32_t totalsize; (tailer) 136 } 137 */ 138}; 139 140 141/* this is stored at the front of every database */ 142struct tdb_header { 143 char magic_food[32]; /* for /etc/magic */ 144 uint32_t version; /* version of the code */ 145 uint32_t hash_size; /* number of hash entries */ 146 tdb_off_t rwlocks; /* obsolete - kept to detect old formats */ 147 tdb_off_t recovery_start; /* offset of transaction recovery region */ 148 tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */ 149 tdb_off_t reserved[29]; 150}; 151 152struct tdb_lock_type { 153 int list; 154 uint32_t count; 155 uint32_t ltype; 156}; 157 158struct tdb_traverse_lock { 159 struct tdb_traverse_lock *next; 160 uint32_t off; 161 uint32_t hash; 162 int lock_rw; 163}; 164 165 166struct tdb_methods { 167 int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int ); 168 int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t); 169 void (*next_hash_chain)(struct tdb_context *, uint32_t *); 170 int (*tdb_oob)(struct tdb_context *, tdb_off_t , int ); 171 int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t ); 172 int (*tdb_brlock)(struct tdb_context *, tdb_off_t , int, int, int, size_t); 173}; 174 175struct tdb_context { 176 char *name; /* the name of the database */ 177 void *map_ptr; /* where it is currently mapped */ 178 int fd; /* open file descriptor for the database */ 179 tdb_len_t map_size; /* how much space has been mapped */ 180 int read_only; /* opened read-only */ 181 int traverse_read; /* read-only traversal */ 182 int traverse_write; /* read-write traversal */ 183 struct tdb_lock_type global_lock; 184 int num_lockrecs; 185 struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ 186 enum TDB_ERROR ecode; /* error code for last tdb error */ 187 struct tdb_header header; /* a cached copy of the header */ 188 uint32_t flags; /* the flags passed to tdb_open */ 189 struct tdb_traverse_lock travlocks; /* current traversal locks */ 190 struct tdb_context *next; /* all tdbs to avoid multiple opens */ 191 dev_t device; /* uniquely identifies this tdb */ 192 ino_t inode; /* uniquely identifies this tdb */ 193 struct tdb_logging_context log; 194 unsigned int (*hash_fn)(TDB_DATA *key); 195 int open_flags; /* flags used in the open - needed by reopen */ 196 unsigned int num_locks; /* number of chain locks held */ 197 const struct tdb_methods *methods; 198 struct tdb_transaction *transaction; 199 int page_size; 200 int max_dead_records; 201 int transaction_lock_count; 202#ifdef TDB_TRACE 203 int tracefd; 204#endif 205 volatile sig_atomic_t *interrupt_sig_ptr; 206}; 207 208 209/* 210 internal prototypes 211*/ 212int tdb_munmap(struct tdb_context *tdb); 213void tdb_mmap(struct tdb_context *tdb); 214int tdb_lock(struct tdb_context *tdb, int list, int ltype); 215int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); 216int tdb_unlock(struct tdb_context *tdb, int list, int ltype); 217int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len); 218int tdb_transaction_lock(struct tdb_context *tdb, int ltype); 219int tdb_transaction_unlock(struct tdb_context *tdb); 220int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len); 221int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off); 222int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off); 223int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); 224int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); 225void *tdb_convert(void *buf, uint32_t size); 226int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); 227tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct tdb_record *rec); 228int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); 229int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); 230int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); 231int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off); 232int _tdb_transaction_cancel(struct tdb_context *tdb); 233int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); 234int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); 235int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct tdb_record *rec); 236unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len); 237int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, 238 tdb_off_t offset, tdb_len_t len, 239 int (*parser)(TDB_DATA key, TDB_DATA data, 240 void *private_data), 241 void *private_data); 242tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, 243 struct tdb_record *rec); 244void tdb_io_init(struct tdb_context *tdb); 245int tdb_expand(struct tdb_context *tdb, tdb_off_t size); 246int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, 247 struct tdb_record *rec); 248 249 250