open.c 16 KB

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