f3ef856eae166874bb24d3dff6285a73e41eb88c
[samba.git] / lib / tdb / common / 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 /* We use two hashes to double-check they're using the right hash function. */
34 void tdb_header_hash(struct tdb_context *tdb,
35                      uint32_t *magic1_hash, uint32_t *magic2_hash)
36 {
37         TDB_DATA hash_key;
38         uint32_t tdb_magic = TDB_MAGIC;
39
40         hash_key.dptr = discard_const_p(unsigned char, TDB_MAGIC_FOOD);
41         hash_key.dsize = sizeof(TDB_MAGIC_FOOD);
42         *magic1_hash = tdb->hash_fn(&hash_key);
43
44         hash_key.dptr = (unsigned char *)CONVERT(tdb_magic);
45         hash_key.dsize = sizeof(tdb_magic);
46         *magic2_hash = tdb->hash_fn(&hash_key);
47
48         /* Make sure at least one hash is non-zero! */
49         if (*magic1_hash == 0 && *magic2_hash == 0)
50                 *magic1_hash = 1;
51 }
52
53 /* initialise a new database with a specified hash size */
54 static int tdb_new_database(struct tdb_context *tdb, struct tdb_header *header,
55                             int hash_size)
56 {
57         struct tdb_header *newdb;
58         size_t size;
59         int ret = -1;
60
61         /* We make it up in memory, then write it out if not internal */
62         size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t);
63         if (!(newdb = (struct tdb_header *)calloc(size, 1))) {
64                 tdb->ecode = TDB_ERR_OOM;
65                 return -1;
66         }
67
68         /* Fill in the header */
69         newdb->version = TDB_VERSION;
70         newdb->hash_size = hash_size;
71
72         tdb_header_hash(tdb, &newdb->magic1_hash, &newdb->magic2_hash);
73
74         /* Make sure older tdbs (which don't check the magic hash fields)
75          * will refuse to open this TDB. */
76         if (tdb->flags & TDB_INCOMPATIBLE_HASH)
77                 newdb->rwlocks = TDB_HASH_RWLOCK_MAGIC;
78
79         /*
80          * We create a tdb with TDB_FEATURE_FLAG_MUTEX support,
81          * the flag combination and runtime feature checks
82          * are done by the caller already.
83          */
84         if (tdb->flags & TDB_MUTEX_LOCKING) {
85                 newdb->feature_flags |= TDB_FEATURE_FLAG_MUTEX;
86         }
87
88         /*
89          * If we have any features we add the FEATURE_FLAG_MAGIC, overwriting the
90          * TDB_HASH_RWLOCK_MAGIC above.
91          */
92         if (newdb->feature_flags != 0) {
93                 newdb->rwlocks = TDB_FEATURE_FLAG_MAGIC;
94         }
95
96         /*
97          * It's required for some following code pathes
98          * to have the fields on 'tdb' up-to-date.
99          *
100          * E.g. tdb_mutex_size() requires it
101          */
102         tdb->feature_flags = newdb->feature_flags;
103         tdb->hash_size = newdb->hash_size;
104
105         if (tdb->flags & TDB_INTERNAL) {
106                 tdb->map_size = size;
107                 tdb->map_ptr = (char *)newdb;
108                 memcpy(header, newdb, sizeof(*header));
109                 /* Convert the `ondisk' version if asked. */
110                 CONVERT(*newdb);
111                 return 0;
112         }
113         if (lseek(tdb->fd, 0, SEEK_SET) == -1)
114                 goto fail;
115
116         if (ftruncate(tdb->fd, 0) == -1)
117                 goto fail;
118
119         if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) {
120                 newdb->mutex_size = tdb_mutex_size(tdb);
121                 tdb->hdr_ofs = newdb->mutex_size;
122         }
123
124         /* This creates an endian-converted header, as if read from disk */
125         CONVERT(*newdb);
126         memcpy(header, newdb, sizeof(*header));
127         /* Don't endian-convert the magic food! */
128         memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
129
130         if (!tdb_write_all(tdb->fd, newdb, size))
131                 goto fail;
132
133         if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) {
134
135                 /*
136                  * Now we init the mutex area
137                  * followed by a second header.
138                  */
139
140                 ret = ftruncate(
141                         tdb->fd,
142                         newdb->mutex_size + sizeof(struct tdb_header));
143                 if (ret == -1) {
144                         goto fail;
145                 }
146                 ret = tdb_mutex_init(tdb);
147                 if (ret == -1) {
148                         goto fail;
149                 }
150
151                 /*
152                  * Write a second header behind the mutexes. That's the area
153                  * that will be mmapp'ed.
154                  */
155                 ret = lseek(tdb->fd, newdb->mutex_size, SEEK_SET);
156                 if (ret == -1) {
157                         goto fail;
158                 }
159                 if (!tdb_write_all(tdb->fd, newdb, size)) {
160                         goto fail;
161                 }
162         }
163
164         ret = 0;
165   fail:
166         SAFE_FREE(newdb);
167         return ret;
168 }
169
170
171
172 static int tdb_already_open(dev_t device,
173                             ino_t ino)
174 {
175         struct tdb_context *i;
176
177         for (i = tdbs; i; i = i->next) {
178                 if (i->device == device && i->inode == ino) {
179                         return 1;
180                 }
181         }
182
183         return 0;
184 }
185
186 /* open the database, creating it if necessary
187
188    The open_flags and mode are passed straight to the open call on the
189    database file. A flags value of O_WRONLY is invalid. The hash size
190    is advisory, use zero for a default value.
191
192    Return is NULL on error, in which case errno is also set.  Don't
193    try to call tdb_error or tdb_errname, just do strerror(errno).
194
195    @param name may be NULL for internal databases. */
196 _PUBLIC_ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags,
197                       int open_flags, mode_t mode)
198 {
199         return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL);
200 }
201
202 /* a default logging function */
203 static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
204 static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
205 {
206 }
207
208 static bool check_header_hash(struct tdb_context *tdb,
209                               struct tdb_header *header,
210                               bool default_hash, uint32_t *m1, uint32_t *m2)
211 {
212         tdb_header_hash(tdb, m1, m2);
213         if (header->magic1_hash == *m1 &&
214             header->magic2_hash == *m2) {
215                 return true;
216         }
217
218         /* If they explicitly set a hash, always respect it. */
219         if (!default_hash)
220                 return false;
221
222         /* Otherwise, try the other inbuilt hash. */
223         if (tdb->hash_fn == tdb_old_hash)
224                 tdb->hash_fn = tdb_jenkins_hash;
225         else
226                 tdb->hash_fn = tdb_old_hash;
227         return check_header_hash(tdb, header, false, m1, m2);
228 }
229
230 static bool tdb_mutex_open_ok(struct tdb_context *tdb,
231                               const struct tdb_header *header)
232 {
233         int locked;
234
235         if (tdb->flags & TDB_NOLOCK) {
236                 /*
237                  * We don't look at locks, so it does not matter to have a
238                  * compatible mutex implementation. Allow the open.
239                  */
240                 return true;
241         }
242
243         locked = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK,
244                                TDB_LOCK_NOWAIT|TDB_LOCK_PROBE);
245
246         if ((locked == -1) && (tdb->ecode == TDB_ERR_LOCK)) {
247                 /*
248                  * CLEAR_IF_FIRST still active. The tdb was created on this
249                  * host, so we can assume the mutex implementation is
250                  * compatible. Important for tools like tdbdump on a still
251                  * open locking.tdb.
252                  */
253                 goto check_local_settings;
254         }
255
256         /*
257          * We got the CLEAR_IF_FIRST lock. That means the database was
258          * potentially copied from somewhere else. The mutex implementation
259          * might be incompatible.
260          */
261
262         if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) {
263                 /*
264                  * Should not happen
265                  */
266                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok: "
267                          "failed to release ACTIVE_LOCK on %s: %s\n",
268                          tdb->name, strerror(errno)));
269                 return false;
270         }
271
272 check_local_settings:
273
274         if (!(tdb->flags & TDB_MUTEX_LOCKING)) {
275                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: "
276                          "Can use mutexes only with "
277                          "MUTEX_LOCKING or NOLOCK\n",
278                          tdb->name));
279                 return false;
280         }
281
282         if (tdb_mutex_size(tdb) != header->mutex_size) {
283                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: "
284                          "Mutex size changed from %u to %u\n.",
285                          tdb->name,
286                          (unsigned int)header->mutex_size,
287                          (unsigned int)tdb_mutex_size(tdb)));
288                 return false;
289         }
290
291         return true;
292 }
293
294 _PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
295                                 int open_flags, mode_t mode,
296                                 const struct tdb_logging_context *log_ctx,
297                                 tdb_hash_func hash_fn)
298 {
299         int orig_errno = errno;
300         struct tdb_header header;
301         struct tdb_context *tdb;
302         struct stat st;
303         int rev = 0, locked = 0;
304         unsigned char *vp;
305         uint32_t vertest;
306         unsigned v;
307         const char *hash_alg;
308         uint32_t magic1, magic2;
309         int ret;
310
311         ZERO_STRUCT(header);
312
313         if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) {
314                 /* Can't log this */
315                 errno = ENOMEM;
316                 goto fail;
317         }
318         tdb_io_init(tdb);
319
320         if (tdb_flags & TDB_INTERNAL) {
321                 tdb_flags |= TDB_INCOMPATIBLE_HASH;
322         }
323         if (tdb_flags & TDB_MUTEX_LOCKING) {
324                 tdb_flags |= TDB_INCOMPATIBLE_HASH;
325         }
326
327         tdb->fd = -1;
328 #ifdef TDB_TRACE
329         tdb->tracefd = -1;
330 #endif
331         tdb->name = NULL;
332         tdb->map_ptr = NULL;
333         tdb->flags = tdb_flags;
334         tdb->open_flags = open_flags;
335         if (log_ctx) {
336                 tdb->log = *log_ctx;
337         } else {
338                 tdb->log.log_fn = null_log_fn;
339                 tdb->log.log_private = NULL;
340         }
341
342         if (name == NULL && (tdb_flags & TDB_INTERNAL)) {
343                 name = "__TDB_INTERNAL__";
344         }
345
346         if (name == NULL) {
347                 tdb->name = discard_const_p(char, "__NULL__");
348                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: called with name == NULL\n"));
349                 tdb->name = NULL;
350                 errno = EINVAL;
351                 goto fail;
352         }
353
354         /* now make a copy of the name, as the caller memory might go away */
355         if (!(tdb->name = (char *)strdup(name))) {
356                 /*
357                  * set the name as the given string, so that tdb_name() will
358                  * work in case of an error.
359                  */
360                 tdb->name = discard_const_p(char, name);
361                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't strdup(%s)\n",
362                          name));
363                 tdb->name = NULL;
364                 errno = ENOMEM;
365                 goto fail;
366         }
367
368         if (hash_fn) {
369                 tdb->hash_fn = hash_fn;
370                 hash_alg = "the user defined";
371         } else {
372                 /* This controls what we use when creating a tdb. */
373                 if (tdb->flags & TDB_INCOMPATIBLE_HASH) {
374                         tdb->hash_fn = tdb_jenkins_hash;
375                 } else {
376                         tdb->hash_fn = tdb_old_hash;
377                 }
378                 hash_alg = "either default";
379         }
380
381         /* cache the page size */
382         tdb->page_size = getpagesize();
383         if (tdb->page_size <= 0) {
384                 tdb->page_size = 0x2000;
385         }
386
387         tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0;
388
389         if ((open_flags & O_ACCMODE) == O_WRONLY) {
390                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n",
391                          name));
392                 errno = EINVAL;
393                 goto fail;
394         }
395
396         if (hash_size == 0)
397                 hash_size = DEFAULT_HASH_SIZE;
398         if ((open_flags & O_ACCMODE) == O_RDONLY) {
399                 tdb->read_only = 1;
400                 /* read only databases don't do locking or clear if first */
401                 tdb->flags |= TDB_NOLOCK;
402                 tdb->flags &= ~(TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING);
403         }
404
405         if ((tdb->flags & TDB_ALLOW_NESTING) &&
406             (tdb->flags & TDB_DISALLOW_NESTING)) {
407                 tdb->ecode = TDB_ERR_NESTING;
408                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
409                         "allow_nesting and disallow_nesting are not allowed together!"));
410                 errno = EINVAL;
411                 goto fail;
412         }
413
414         if (tdb->flags & TDB_MUTEX_LOCKING) {
415                 /*
416                  * Here we catch bugs in the callers,
417                  * the runtime check for existing tdb's comes later.
418                  */
419
420                 if (!(tdb->flags & TDB_CLEAR_IF_FIRST)) {
421                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
422                                 "invalid flags for %s - TDB_MUTEX_LOCKING "
423                                 "requires TDB_CLEAR_IF_FIRST\n", name));
424                         errno = EINVAL;
425                         goto fail;
426                 }
427
428                 if (tdb->flags & TDB_INTERNAL) {
429                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
430                                 "invalid flags for %s - TDB_MUTEX_LOCKING and "
431                                 "TDB_INTERNAL are not allowed together\n", name));
432                         errno = EINVAL;
433                         goto fail;
434                 }
435
436                 if (tdb->flags & TDB_NOMMAP) {
437                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
438                                 "invalid flags for %s - TDB_MUTEX_LOCKING and "
439                                 "TDB_NOMMAP are not allowed together\n", name));
440                         errno = EINVAL;
441                         goto fail;
442                 }
443
444                 if (tdb->read_only) {
445                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
446                                 "invalid flags for %s - TDB_MUTEX_LOCKING "
447                                 "not allowed read only\n", name));
448                         errno = EINVAL;
449                         goto fail;
450                 }
451
452                 /*
453                  * The callers should have called
454                  * tdb_runtime_check_for_robust_mutexes()
455                  * before using TDB_MUTEX_LOCKING!
456                  *
457                  * This makes sure the caller understands
458                  * that the locking may behave a bit differently
459                  * than with pure fcntl locking. E.g. multiple
460                  * read locks are not supported.
461                  */
462                 if (!tdb_runtime_check_for_robust_mutexes()) {
463                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
464                                 "invalid flags for %s - TDB_MUTEX_LOCKING "
465                                 "requires support for robust_mutexes\n",
466                                 name));
467                         errno = ENOSYS;
468                         goto fail;
469                 }
470         }
471
472         if (getenv("TDB_NO_FSYNC")) {
473                 tdb->flags |= TDB_NOSYNC;
474         }
475
476         /*
477          * TDB_ALLOW_NESTING is the default behavior.
478          * Note: this may change in future versions!
479          */
480         if (!(tdb->flags & TDB_DISALLOW_NESTING)) {
481                 tdb->flags |= TDB_ALLOW_NESTING;
482         }
483
484         /* internal databases don't mmap or lock, and start off cleared */
485         if (tdb->flags & TDB_INTERNAL) {
486                 tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP);
487                 tdb->flags &= ~TDB_CLEAR_IF_FIRST;
488                 if (tdb_new_database(tdb, &header, hash_size) != 0) {
489                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!"));
490                         goto fail;
491                 }
492                 tdb->hash_size = hash_size;
493                 goto internal;
494         }
495
496         if ((tdb->fd = open(name, open_flags, mode)) == -1) {
497                 TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n",
498                          name, strerror(errno)));
499                 goto fail;      /* errno set by open(2) */
500         }
501
502         /* on exec, don't inherit the fd */
503         v = fcntl(tdb->fd, F_GETFD, 0);
504         fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC);
505
506         /* ensure there is only one process initialising at once */
507         if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) {
508                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get open lock on %s: %s\n",
509                          name, strerror(errno)));
510                 goto fail;      /* errno set by tdb_brlock */
511         }
512
513         /* we need to zero database if we are the only one with it open */
514         if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
515             (!tdb->read_only) &&
516             (locked = (tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE) == 0))) {
517                 ret = tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0,
518                                  TDB_LOCK_WAIT);
519                 if (ret == -1) {
520                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
521                                  "tdb_brlock failed for %s: %s\n",
522                                  name, strerror(errno)));
523                         goto fail;
524                 }
525                 ret = tdb_new_database(tdb, &header, hash_size);
526                 if (ret == -1) {
527                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
528                                  "tdb_new_database failed for %s: %s\n",
529                                  name, strerror(errno)));
530                         tdb_unlockall(tdb);
531                         goto fail;
532                 }
533                 ret = tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0);
534                 if (ret == -1) {
535                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
536                                  "tdb_unlockall failed for %s: %s\n",
537                                  name, strerror(errno)));
538                         goto fail;
539                 }
540                 ret = lseek(tdb->fd, 0, SEEK_SET);
541                 if (ret == -1) {
542                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
543                                  "lseek failed for %s: %s\n",
544                                  name, strerror(errno)));
545                         goto fail;
546                 }
547         }
548
549         errno = 0;
550         if (read(tdb->fd, &header, sizeof(header)) != sizeof(header)
551             || strcmp(header.magic_food, TDB_MAGIC_FOOD) != 0) {
552                 if (!(open_flags & O_CREAT) ||
553                     tdb_new_database(tdb, &header, hash_size) == -1) {
554                         if (errno == 0) {
555                                 errno = EIO; /* ie bad format or something */
556                         }
557                         goto fail;
558                 }
559                 rev = (tdb->flags & TDB_CONVERT);
560         } else if (header.version != TDB_VERSION
561                    && !(rev = (header.version==TDB_BYTEREV(TDB_VERSION)))) {
562                 /* wrong version */
563                 errno = EIO;
564                 goto fail;
565         }
566         vp = (unsigned char *)&header.version;
567         vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) |
568                   (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3];
569         tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0;
570         if (!rev)
571                 tdb->flags &= ~TDB_CONVERT;
572         else {
573                 tdb->flags |= TDB_CONVERT;
574                 tdb_convert(&header, sizeof(header));
575         }
576
577         /*
578          * We only use st.st_dev and st.st_ino from the raw fstat()
579          * call, everything else needs to use tdb_fstat() in order
580          * to skip tdb->hdr_ofs!
581          */
582         if (fstat(tdb->fd, &st) == -1) {
583                 goto fail;
584         }
585         tdb->device = st.st_dev;
586         tdb->inode = st.st_ino;
587         ZERO_STRUCT(st);
588
589         if (header.rwlocks != 0 &&
590             header.rwlocks != TDB_FEATURE_FLAG_MAGIC &&
591             header.rwlocks != TDB_HASH_RWLOCK_MAGIC) {
592                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n"));
593                 errno = ENOSYS;
594                 goto fail;
595         }
596
597         if (header.hash_size == 0) {
598                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: invalid database: 0 hash_size\n"));
599                 errno = ENOSYS;
600                 goto fail;
601         }
602
603         tdb->hash_size = header.hash_size;
604
605         if (header.rwlocks == TDB_FEATURE_FLAG_MAGIC) {
606                 tdb->feature_flags = header.feature_flags;
607         }
608
609         if (tdb->feature_flags & ~TDB_SUPPORTED_FEATURE_FLAGS) {
610                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: unsupported "
611                          "features in tdb %s: 0x%08x (supported: 0x%08x)\n",
612                          name, (unsigned)tdb->feature_flags,
613                          (unsigned)TDB_SUPPORTED_FEATURE_FLAGS));
614                 errno = ENOSYS;
615                 goto fail;
616         }
617
618         if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) {
619                 if (!tdb_mutex_open_ok(tdb, &header)) {
620                         errno = EINVAL;
621                         goto fail;
622                 }
623
624                 /*
625                  * We need to remember the hdr_ofs
626                  * also for the TDB_NOLOCK case
627                  * if the current library doesn't support
628                  * mutex locking.
629                  */
630                 tdb->hdr_ofs = header.mutex_size;
631         }
632
633         if ((header.magic1_hash == 0) && (header.magic2_hash == 0)) {
634                 /* older TDB without magic hash references */
635                 tdb->hash_fn = tdb_old_hash;
636         } else if (!check_header_hash(tdb, &header, !hash_fn,
637                                       &magic1, &magic2)) {
638                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
639                          "%s was not created with %s hash function we are using\n"
640                          "magic1_hash[0x%08X %s 0x%08X] "
641                          "magic2_hash[0x%08X %s 0x%08X]\n",
642                          name, hash_alg,
643                          header.magic1_hash,
644                          (header.magic1_hash == magic1) ? "==" : "!=",
645                          magic1,
646                          header.magic2_hash,
647                          (header.magic2_hash == magic2) ? "==" : "!=",
648                          magic2));
649                 errno = EINVAL;
650                 goto fail;
651         }
652
653         /* Is it already in the open list?  If so, fail. */
654         if (tdb_already_open(tdb->device, tdb->inode)) {
655                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
656                          "%s (%d,%d) is already open in this process\n",
657                          name, (int)tdb->device, (int)tdb->inode));
658                 errno = EBUSY;
659                 goto fail;
660         }
661
662         /*
663          * We had tdb_mmap(tdb) here before,
664          * but we need to use tdb_fstat(),
665          * which is triggered from tdb_oob() before calling tdb_mmap().
666          * As this skips tdb->hdr_ofs.
667          */
668         tdb->map_size = 0;
669         ret = tdb->methods->tdb_oob(tdb, 0, 1, 0);
670         if (ret == -1) {
671                 errno = EIO;
672                 goto fail;
673         }
674
675         if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) {
676                 if (!(tdb->flags & TDB_NOLOCK)) {
677                         ret = tdb_mutex_mmap(tdb);
678                         if (ret != 0) {
679                                 goto fail;
680                         }
681                 }
682         }
683
684         if (locked) {
685                 if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) {
686                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
687                                  "failed to release ACTIVE_LOCK on %s: %s\n",
688                                  name, strerror(errno)));
689                         goto fail;
690                 }
691
692         }
693
694         /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if
695            we didn't get the initial exclusive lock as we need to let all other
696            users know we're using it. */
697
698         if (tdb_flags & TDB_CLEAR_IF_FIRST) {
699                 /* leave this lock in place to indicate it's in use */
700                 if (tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) {
701                         goto fail;
702                 }
703         }
704
705         /* if needed, run recovery */
706         if (tdb_transaction_recover(tdb) == -1) {
707                 goto fail;
708         }
709
710 #ifdef TDB_TRACE
711         {
712                 char tracefile[strlen(name) + 32];
713
714                 snprintf(tracefile, sizeof(tracefile),
715                          "%s.trace.%li", name, (long)getpid());
716                 tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600);
717                 if (tdb->tracefd >= 0) {
718                         tdb_enable_seqnum(tdb);
719                         tdb_trace_open(tdb, "tdb_open", hash_size, tdb_flags,
720                                        open_flags);
721                 } else
722                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to open trace file %s!\n", tracefile));
723         }
724 #endif
725
726  internal:
727         /* Internal (memory-only) databases skip all the code above to
728          * do with disk files, and resume here by releasing their
729          * open lock and hooking into the active list. */
730         if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1) {
731                 goto fail;
732         }
733         tdb->next = tdbs;
734         tdbs = tdb;
735         errno = orig_errno;
736         return tdb;
737
738  fail:
739         { int save_errno = errno;
740
741         if (!tdb)
742                 return NULL;
743
744 #ifdef TDB_TRACE
745         close(tdb->tracefd);
746 #endif
747         if (tdb->map_ptr) {
748                 if (tdb->flags & TDB_INTERNAL)
749                         SAFE_FREE(tdb->map_ptr);
750                 else
751                         tdb_munmap(tdb);
752         }
753         if (tdb->fd != -1)
754                 if (close(tdb->fd) != 0)
755                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n"));
756         SAFE_FREE(tdb->lockrecs);
757         SAFE_FREE(tdb->name);
758         SAFE_FREE(tdb);
759         errno = save_errno;
760         return NULL;
761         }
762 }
763
764 /*
765  * Set the maximum number of dead records per hash chain
766  */
767
768 _PUBLIC_ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead)
769 {
770         tdb->max_dead_records = max_dead;
771 }
772
773 /**
774  * Close a database.
775  *
776  * @returns -1 for error; 0 for success.
777  **/
778 _PUBLIC_ int tdb_close(struct tdb_context *tdb)
779 {
780         struct tdb_context **i;
781         int ret = 0;
782
783         if (tdb->transaction) {
784                 tdb_transaction_cancel(tdb);
785         }
786         tdb_trace(tdb, "tdb_close");
787
788         if (tdb->map_ptr) {
789                 if (tdb->flags & TDB_INTERNAL)
790                         SAFE_FREE(tdb->map_ptr);
791                 else
792                         tdb_munmap(tdb);
793         }
794
795         tdb_mutex_munmap(tdb);
796
797         SAFE_FREE(tdb->name);
798         if (tdb->fd != -1) {
799                 ret = close(tdb->fd);
800                 tdb->fd = -1;
801         }
802         SAFE_FREE(tdb->lockrecs);
803
804         /* Remove from contexts list */
805         for (i = &tdbs; *i; i = &(*i)->next) {
806                 if (*i == tdb) {
807                         *i = tdb->next;
808                         break;
809                 }
810         }
811
812 #ifdef TDB_TRACE
813         close(tdb->tracefd);
814 #endif
815         memset(tdb, 0, sizeof(*tdb));
816         SAFE_FREE(tdb);
817
818         return ret;
819 }
820
821 /* register a loging function */
822 _PUBLIC_ void tdb_set_logging_function(struct tdb_context *tdb,
823                                        const struct tdb_logging_context *log_ctx)
824 {
825         tdb->log = *log_ctx;
826 }
827
828 _PUBLIC_ void *tdb_get_logging_private(struct tdb_context *tdb)
829 {
830         return tdb->log.log_private;
831 }
832
833 static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock)
834 {
835 #if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \
836         !defined(LIBREPLACE_PWRITE_NOT_REPLACED)
837         struct stat st;
838 #endif
839
840         if (tdb->flags & TDB_INTERNAL) {
841                 return 0; /* Nothing to do. */
842         }
843
844         if (tdb_have_extra_locks(tdb)) {
845                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n"));
846                 goto fail;
847         }
848
849         if (tdb->transaction != 0) {
850                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n"));
851                 goto fail;
852         }
853
854 /* If we have real pread & pwrite, we can skip reopen. */
855 #if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \
856         !defined(LIBREPLACE_PWRITE_NOT_REPLACED)
857         if (tdb_munmap(tdb) != 0) {
858                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
859                 goto fail;
860         }
861         if (close(tdb->fd) != 0)
862                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n"));
863         tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
864         if (tdb->fd == -1) {
865                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno)));
866                 goto fail;
867         }
868         /*
869          * We only use st.st_dev and st.st_ino from the raw fstat()
870          * call, everything else needs to use tdb_fstat() in order
871          * to skip tdb->hdr_ofs!
872          */
873         if (fstat(tdb->fd, &st) != 0) {
874                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno)));
875                 goto fail;
876         }
877         if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
878                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n"));
879                 goto fail;
880         }
881         ZERO_STRUCT(st);
882
883         /*
884          * We had tdb_mmap(tdb) here before,
885          * but we need to use tdb_fstat(),
886          * which is triggered from tdb_oob() before calling tdb_mmap().
887          * As this skips tdb->hdr_ofs.
888          */
889         tdb->map_size = 0;
890         if (tdb->methods->tdb_oob(tdb, 0, 1, 0) != 0) {
891                 goto fail;
892         }
893 #endif /* fake pread or pwrite */
894
895         /* We may still think we hold the active lock. */
896         tdb->num_lockrecs = 0;
897         SAFE_FREE(tdb->lockrecs);
898         tdb->lockrecs_array_length = 0;
899
900         if (active_lock && tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) {
901                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n"));
902                 goto fail;
903         }
904
905         return 0;
906
907 fail:
908         tdb_close(tdb);
909         return -1;
910 }
911
912 /* reopen a tdb - this can be used after a fork to ensure that we have an independent
913    seek pointer from our parent and to re-establish locks */
914 _PUBLIC_ int tdb_reopen(struct tdb_context *tdb)
915 {
916         return tdb_reopen_internal(tdb, tdb->flags & TDB_CLEAR_IF_FIRST);
917 }
918
919 /* reopen all tdb's */
920 _PUBLIC_ int tdb_reopen_all(int parent_longlived)
921 {
922         struct tdb_context *tdb;
923
924         for (tdb=tdbs; tdb; tdb = tdb->next) {
925                 bool active_lock = (tdb->flags & TDB_CLEAR_IF_FIRST);
926
927                 /*
928                  * If the parent is longlived (ie. a
929                  * parent daemon architecture), we know
930                  * it will keep it's active lock on a
931                  * tdb opened with CLEAR_IF_FIRST. Thus
932                  * for child processes we don't have to
933                  * add an active lock. This is essential
934                  * to improve performance on systems that
935                  * keep POSIX locks as a non-scalable data
936                  * structure in the kernel.
937                  */
938                 if (parent_longlived) {
939                         /* Ensure no clear-if-first. */
940                         active_lock = false;
941                 }
942
943                 if (tdb_reopen_internal(tdb, active_lock) != 0)
944                         return -1;
945         }
946
947         return 0;
948 }