]> git.ozlabs.org Git - ccan/blob - ccan/tdb/open.c
437a5fc38d1706e9b5f3e846876f8aa4e8d9da75
[ccan] / ccan / tdb / open.c
1  /* 
2    Unix SMB/CIFS implementation.
3
4    trivial database library
5
6    Copyright (C) Andrew Tridgell              1999-2005
7    Copyright (C) Paul `Rusty' Russell              2000
8    Copyright (C) Jeremy Allison                    2000-2003
9    
10      ** NOTE! The following LGPL license applies to the tdb
11      ** library. This does NOT imply that all of Samba is released
12      ** under the LGPL
13    
14    This library is free software; you can redistribute it and/or
15    modify it under the terms of the GNU Lesser General Public
16    License as published by the Free Software Foundation; either
17    version 3 of the License, or (at your option) any later version.
18
19    This library is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    Lesser General Public License for more details.
23
24    You should have received a copy of the GNU Lesser General Public
25    License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 */
27
28 #include "tdb_private.h"
29
30 /* all contexts, to ensure no double-opens (fcntl locks don't nest!) */
31 static struct tdb_context *tdbs = NULL;
32
33
34 /* This is based on the hash algorithm from gdbm */
35 static unsigned int default_tdb_hash(TDB_DATA *key)
36 {
37         uint32_t value; /* Used to compute the hash value.  */
38         uint32_t   i;   /* Used to cycle through random values. */
39
40         /* Set the initial value from the key size. */
41         for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++)
42                 value = (value + (key->dptr[i] << (i*5 % 24)));
43
44         return (1103515243 * value + 12345);  
45 }
46
47
48 /* initialise a new database with a specified hash size */
49 static int tdb_new_database(struct tdb_context *tdb, int hash_size)
50 {
51         struct tdb_header *newdb;
52         size_t size;
53         int ret = -1;
54         ssize_t written;
55
56         /* We make it up in memory, then write it out if not internal */
57         size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t);
58         if (!(newdb = (struct tdb_header *)calloc(size, 1))) {
59                 tdb->ecode = TDB_ERR_OOM;
60                 return -1;
61         }
62
63         /* Fill in the header */
64         newdb->version = TDB_VERSION;
65         newdb->hash_size = hash_size;
66         newdb->hashcheck = hashcheck(tdb);
67         if (tdb->flags & TDB_INTERNAL) {
68                 tdb->map_size = size;
69                 tdb->map_ptr = (char *)newdb;
70                 memcpy(&tdb->header, newdb, sizeof(tdb->header));
71                 /* Convert the `ondisk' version if asked. */
72                 CONVERT(*newdb);
73                 return 0;
74         }
75         if (lseek(tdb->fd, 0, SEEK_SET) == -1)
76                 goto fail;
77
78         if (ftruncate(tdb->fd, 0) == -1)
79                 goto fail;
80
81         /* This creates an endian-converted header, as if read from disk */
82         CONVERT(*newdb);
83         memcpy(&tdb->header, newdb, sizeof(tdb->header));
84         /* Don't endian-convert the magic food! */
85         memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
86         /* we still have "ret == -1" here */
87         written = write(tdb->fd, newdb, size);
88         if (written == size) {
89                 ret = 0;
90         } else if (written != -1) {
91                 /* call write once again, this usually should return -1 and
92                  * set errno appropriately */
93                 size -= written;
94                 written = write(tdb->fd, newdb+written, size);
95                 if (written == size) {
96                 ret = 0;
97                 } else if (written >= 0) {
98                         /* a second incomplete write - we give up.
99                          * guessing the errno... */
100                         errno = ENOSPC;
101                 }
102         }
103
104   fail:
105         SAFE_FREE(newdb);
106         return ret;
107 }
108
109
110
111 static int tdb_already_open(dev_t device,
112                             ino_t ino)
113 {
114         struct tdb_context *i;
115         
116         for (i = tdbs; i; i = i->next) {
117                 if (i->device == device && i->inode == ino) {
118                         return 1;
119                 }
120         }
121
122         return 0;
123 }
124
125 /* open the database, creating it if necessary 
126
127    The open_flags and mode are passed straight to the open call on the
128    database file. A flags value of O_WRONLY is invalid. The hash size
129    is advisory, use zero for a default value.
130
131    Return is NULL on error, in which case errno is also set.  Don't 
132    try to call tdb_error or tdb_errname, just do strerror(errno).
133
134    @param name may be NULL for internal databases. */
135 struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags,
136                       int open_flags, mode_t mode)
137 {
138         return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL);
139 }
140
141 /* a default logging function */
142 static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
143 static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
144 {
145 }
146
147 uint32_t hashcheck(struct tdb_context *tdb)
148 {
149         uint32_t vals[] = { TDB_VERSION, TDB_MAGIC };
150         TDB_DATA hashkey = { (unsigned char *)vals, sizeof(vals) };
151
152         /* If we're using the default hash, let old code still open the db. */
153         if (tdb->hash_fn == default_tdb_hash)
154                 return 0;
155
156         /* Only let new hash-aware TDB code open it (must not be zero!) */
157         return (tdb->hash_fn(&hashkey) | 1);
158 }
159
160 struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
161                                 int open_flags, mode_t mode,
162                                 const struct tdb_logging_context *log_ctx,
163                                 tdb_hash_func hash_fn)
164 {
165         struct tdb_context *tdb;
166         struct stat st;
167         int rev = 0, locked = 0;
168         unsigned char *vp;
169         uint32_t vertest;
170         unsigned v;
171
172         if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) {
173                 /* Can't log this */
174                 errno = ENOMEM;
175                 goto fail;
176         }
177         tdb_io_init(tdb);
178         tdb->fd = -1;
179 #ifdef TDB_TRACE
180         tdb->tracefd = -1;
181 #endif
182         tdb->name = NULL;
183         tdb->map_ptr = NULL;
184         tdb->flags = tdb_flags;
185         tdb->open_flags = open_flags;
186         if (log_ctx) {
187                 tdb->log = *log_ctx;
188         } else {
189                 tdb->log.log_fn = null_log_fn;
190                 tdb->log.log_private = NULL;
191         }
192         tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash;
193
194         /* cache the page size */
195         tdb->page_size = getpagesize();
196         if (tdb->page_size <= 0) {
197                 tdb->page_size = 0x2000;
198         }
199
200         tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0;
201
202         if ((open_flags & O_ACCMODE) == O_WRONLY) {
203                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n",
204                          name));
205                 errno = EINVAL;
206                 goto fail;
207         }
208         
209         if (hash_size == 0)
210                 hash_size = DEFAULT_HASH_SIZE;
211         if ((open_flags & O_ACCMODE) == O_RDONLY) {
212                 tdb->read_only = 1;
213                 /* read only databases don't do locking or clear if first */
214                 tdb->flags |= TDB_NOLOCK;
215                 tdb->flags &= ~TDB_CLEAR_IF_FIRST;
216         }
217
218         if ((tdb->flags & TDB_ALLOW_NESTING) &&
219             (tdb->flags & TDB_DISALLOW_NESTING)) {
220                 tdb->ecode = TDB_ERR_NESTING;
221                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
222                         "allow_nesting and disallow_nesting are not allowed together!"));
223                 errno = EINVAL;
224                 goto fail;
225         }
226
227         /*
228          * TDB_DISALLOW_NESTING is the default behavior.
229          */
230         if (!(tdb->flags & TDB_ALLOW_NESTING)) {
231                 tdb->flags |= TDB_DISALLOW_NESTING;
232         }
233
234         /* internal databases don't mmap or lock, and start off cleared */
235         if (tdb->flags & TDB_INTERNAL) {
236                 tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP);
237                 tdb->flags &= ~TDB_CLEAR_IF_FIRST;
238                 if (tdb_new_database(tdb, hash_size) != 0) {
239                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!"));
240                         goto fail;
241                 }
242                 goto internal;
243         }
244
245         if ((tdb->fd = open(name, open_flags, mode)) == -1) {
246                 TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n",
247                          name, strerror(errno)));
248                 goto fail;      /* errno set by open(2) */
249         }
250
251         /* on exec, don't inherit the fd */
252         v = fcntl(tdb->fd, F_GETFD, 0);
253         fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC);
254
255         /* ensure there is only one process initialising at once */
256         if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) {
257                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get open lock on %s: %s\n",
258                          name, strerror(errno)));
259                 goto fail;      /* errno set by tdb_brlock */
260         }
261
262         /* we need to zero database if we are the only one with it open */
263         if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
264             (!tdb->read_only) &&
265             (locked = (tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE) == 0))) {
266                 open_flags |= O_CREAT;
267                 if (ftruncate(tdb->fd, 0) == -1) {
268                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
269                                  "failed to truncate %s: %s\n",
270                                  name, strerror(errno)));
271                         goto fail; /* errno set by ftruncate */
272                 }
273         }
274
275         errno = 0;
276         if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
277             || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0) {
278                 if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
279                         if (errno == 0) {
280                                 errno = EIO; /* ie bad format or something */
281                         }
282                         goto fail;
283                 }
284                 rev = (tdb->flags & TDB_CONVERT);
285         } else if (tdb->header.version != TDB_VERSION
286                    && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION)))) {
287                 /* wrong version */
288                 errno = EIO;
289                 goto fail;
290         }
291         vp = (unsigned char *)&tdb->header.version;
292         vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) |
293                   (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3];
294         tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0;
295         if (!rev)
296                 tdb->flags &= ~TDB_CONVERT;
297         else {
298                 tdb->flags |= TDB_CONVERT;
299                 tdb_convert(&tdb->header, sizeof(tdb->header));
300         }
301         if (fstat(tdb->fd, &st) == -1)
302                 goto fail;
303
304         if (tdb->header.hashcheck != hashcheck(tdb)) {
305                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: wrong hash?\n"));
306                 goto fail;
307         }
308
309         /* Is it already in the open list?  If so, fail. */
310         if (tdb_already_open(st.st_dev, st.st_ino)) {
311                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
312                          "%s (%d,%d) is already open in this process\n",
313                          name, (int)st.st_dev, (int)st.st_ino));
314                 errno = EBUSY;
315                 goto fail;
316         }
317
318         if (!(tdb->name = (char *)strdup(name))) {
319                 errno = ENOMEM;
320                 goto fail;
321         }
322
323         tdb->map_size = st.st_size;
324         tdb->device = st.st_dev;
325         tdb->inode = st.st_ino;
326         tdb_mmap(tdb);
327         if (locked) {
328                 if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) {
329                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
330                                  "failed to take ACTIVE_LOCK on %s: %s\n",
331                                  name, strerror(errno)));
332                         goto fail;
333                 }
334
335         }
336
337         /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if
338            we didn't get the initial exclusive lock as we need to let all other
339            users know we're using it. */
340
341         if (tdb_flags & TDB_CLEAR_IF_FIRST) {
342                 /* leave this lock in place to indicate it's in use */
343                 if (tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) {
344                         goto fail;
345                 }
346         }
347
348         /* if needed, run recovery */
349         if (tdb_transaction_recover(tdb) == -1) {
350                 goto fail;
351         }
352
353 #ifdef TDB_TRACE
354         {
355                 char tracefile[strlen(name) + 32];
356
357                 snprintf(tracefile, sizeof(tracefile),
358                          "%s.trace.%li", name, (long)getpid());
359                 tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600);
360                 if (tdb->tracefd >= 0) {
361                         tdb_enable_seqnum(tdb);
362                         tdb_trace_open(tdb, "tdb_open", hash_size, tdb_flags,
363                                        open_flags);
364                 } else
365                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to open trace file %s!\n", tracefile));
366         }
367 #endif
368
369  internal:
370         /* Internal (memory-only) databases skip all the code above to
371          * do with disk files, and resume here by releasing their
372          * open lock and hooking into the active list. */
373         if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1) {
374                 goto fail;
375         }
376         tdb->next = tdbs;
377         tdbs = tdb;
378         return tdb;
379
380  fail:
381         { int save_errno = errno;
382
383         if (!tdb)
384                 return NULL;
385
386 #ifdef TDB_TRACE
387         close(tdb->tracefd);
388 #endif
389         if (tdb->map_ptr) {
390                 if (tdb->flags & TDB_INTERNAL)
391                         SAFE_FREE(tdb->map_ptr);
392                 else
393                         tdb_munmap(tdb);
394         }
395         SAFE_FREE(tdb->name);
396         if (tdb->fd != -1)
397                 if (close(tdb->fd) != 0)
398                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n"));
399         SAFE_FREE(tdb->lockrecs);
400         SAFE_FREE(tdb);
401         errno = save_errno;
402         return NULL;
403         }
404 }
405
406 /*
407  * Set the maximum number of dead records per hash chain
408  */
409
410 void tdb_set_max_dead(struct tdb_context *tdb, int max_dead)
411 {
412         tdb->max_dead_records = max_dead;
413 }
414
415 /**
416  * Close a database.
417  *
418  * @returns -1 for error; 0 for success.
419  **/
420 int tdb_close(struct tdb_context *tdb)
421 {
422         struct tdb_context **i;
423         int ret = 0;
424
425         if (tdb->transaction) {
426                 tdb_transaction_cancel(tdb);
427         }
428         tdb_trace(tdb, "tdb_close");
429
430         if (tdb->map_ptr) {
431                 if (tdb->flags & TDB_INTERNAL)
432                         SAFE_FREE(tdb->map_ptr);
433                 else
434                         tdb_munmap(tdb);
435         }
436         SAFE_FREE(tdb->name);
437         if (tdb->fd != -1) {
438                 ret = close(tdb->fd);
439                 tdb->fd = -1;
440         }
441         SAFE_FREE(tdb->lockrecs);
442
443         /* Remove from contexts list */
444         for (i = &tdbs; *i; i = &(*i)->next) {
445                 if (*i == tdb) {
446                         *i = tdb->next;
447                         break;
448                 }
449         }
450
451 #ifdef TDB_TRACE
452         close(tdb->tracefd);
453 #endif
454         memset(tdb, 0, sizeof(*tdb));
455         SAFE_FREE(tdb);
456
457         return ret;
458 }
459
460 /* register a loging function */
461 void tdb_set_logging_function(struct tdb_context *tdb,
462                               const struct tdb_logging_context *log_ctx)
463 {
464         tdb->log = *log_ctx;
465 }
466
467 void *tdb_get_logging_private(struct tdb_context *tdb)
468 {
469         return tdb->log.log_private;
470 }
471
472 static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock)
473 {
474         struct stat st;
475
476         if (tdb->flags & TDB_INTERNAL) {
477                 return 0; /* Nothing to do. */
478         }
479
480         if (tdb_have_extra_locks(tdb)) {
481                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n"));
482                 goto fail;
483         }
484
485         if (tdb->transaction != 0) {
486                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n"));
487                 goto fail;
488         }
489
490         if (tdb_munmap(tdb) != 0) {
491                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
492                 goto fail;
493         }
494         if (close(tdb->fd) != 0)
495                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n"));
496         tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
497         if (tdb->fd == -1) {
498                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno)));
499                 goto fail;
500         }
501         if (fstat(tdb->fd, &st) != 0) {
502                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno)));
503                 goto fail;
504         }
505         if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
506                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n"));
507                 goto fail;
508         }
509         tdb_mmap(tdb);
510
511         /* We may still think we hold the active lock. */
512         tdb->num_lockrecs = 0;
513         SAFE_FREE(tdb->lockrecs);
514
515         if (active_lock && tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) {
516                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n"));
517                 goto fail;
518         }
519
520         return 0;
521
522 fail:
523         tdb_close(tdb);
524         return -1;
525 }
526
527 /* reopen a tdb - this can be used after a fork to ensure that we have an independent
528    seek pointer from our parent and to re-establish locks */
529 int tdb_reopen(struct tdb_context *tdb)
530 {
531         return tdb_reopen_internal(tdb, tdb->flags & TDB_CLEAR_IF_FIRST);
532 }
533
534 /* reopen all tdb's */
535 int tdb_reopen_all(int parent_longlived)
536 {
537         struct tdb_context *tdb;
538
539         for (tdb=tdbs; tdb; tdb = tdb->next) {
540                 bool active_lock = (tdb->flags & TDB_CLEAR_IF_FIRST);
541
542                 /*
543                  * If the parent is longlived (ie. a
544                  * parent daemon architecture), we know
545                  * it will keep it's active lock on a
546                  * tdb opened with CLEAR_IF_FIRST. Thus
547                  * for child processes we don't have to
548                  * add an active lock. This is essential
549                  * to improve performance on systems that
550                  * keep POSIX locks as a non-scalable data
551                  * structure in the kernel.
552                  */
553                 if (parent_longlived) {
554                         /* Ensure no clear-if-first. */
555                         active_lock = false;
556                 }
557
558                 if (tdb_reopen_internal(tdb, active_lock) != 0)
559                         return -1;
560         }
561
562         return 0;
563 }