ntdb.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933
  1. #ifndef CCAN_NTDB_H
  2. #define CCAN_NTDB_H
  3. /*
  4. NTDB: trivial database library version 2
  5. Copyright (C) Andrew Tridgell 1999-2004
  6. Copyright (C) Rusty Russell 2010-2012
  7. ** NOTE! The following LGPL license applies to the ntdb
  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. #ifdef __cplusplus
  22. extern "C" {
  23. #endif
  24. #ifdef HAVE_LIBREPLACE
  25. #include <replace.h>
  26. #include <system/filesys.h>
  27. #else
  28. #include "config.h"
  29. #if HAVE_FILE_OFFSET_BITS
  30. #define _FILE_OFFSET_BITS 64
  31. #endif
  32. #ifndef _PUBLIC_
  33. #ifdef HAVE_VISIBILITY_ATTR
  34. #define _PUBLIC_ __attribute__((visibility("default")))
  35. #else
  36. #define _PUBLIC_
  37. #endif
  38. #endif
  39. /* For mode_t */
  40. #include <sys/types.h>
  41. /* For O_* flags. */
  42. #include <sys/stat.h>
  43. /* For sig_atomic_t. */
  44. #include <signal.h>
  45. /* For uint64_t */
  46. #include <stdint.h>
  47. /* For bool */
  48. #include <stdbool.h>
  49. /* For memcmp */
  50. #include <string.h>
  51. #endif
  52. #include <ccan/compiler/compiler.h>
  53. #include <ccan/typesafe_cb/typesafe_cb.h>
  54. #include <ccan/cast/cast.h>
  55. union ntdb_attribute;
  56. struct ntdb_context;
  57. /**
  58. * struct TDB_DATA - (n)tdb data blob
  59. *
  60. * To ease compatibility, we use 'struct TDB_DATA' from tdb.h, so if
  61. * you want to include both tdb.h and ntdb.h, you need to #include
  62. * tdb.h first.
  63. */
  64. #ifndef __TDB_H__
  65. struct TDB_DATA {
  66. unsigned char *dptr;
  67. size_t dsize;
  68. };
  69. #endif
  70. typedef struct TDB_DATA NTDB_DATA;
  71. /**
  72. * ntdb_open - open a database file
  73. * @name: the file name (or database name if flags contains NTDB_INTERNAL)
  74. * @ntdb_flags: options for this database
  75. * @open_flags: flags argument for ntdb's open() call.
  76. * @mode: mode argument for ntdb's open() call.
  77. * @attributes: linked list of extra attributes for this ntdb.
  78. *
  79. * This call opens (and potentially creates) a database file.
  80. * Multiple processes can have the NTDB file open at once.
  81. *
  82. * On failure it will return NULL, and set errno: it may also call
  83. * any log attribute found in @attributes.
  84. *
  85. * See also:
  86. * union ntdb_attribute
  87. */
  88. struct ntdb_context *ntdb_open(const char *name, int ntdb_flags,
  89. int open_flags, mode_t mode,
  90. union ntdb_attribute *attributes);
  91. /* flags for ntdb_open() */
  92. #define NTDB_DEFAULT 0 /* just a readability place holder */
  93. #define NTDB_INTERNAL 2 /* don't store on disk */
  94. #define NTDB_NOLOCK 4 /* don't do any locking */
  95. #define NTDB_NOMMAP 8 /* don't use mmap */
  96. #define NTDB_CONVERT 16 /* convert endian */
  97. #define NTDB_NOSYNC 64 /* don't use synchronous transactions */
  98. #define NTDB_SEQNUM 128 /* maintain a sequence number */
  99. #define NTDB_ALLOW_NESTING 256 /* fake nested transactions */
  100. #define NTDB_RDONLY 512 /* implied by O_RDONLY */
  101. #define NTDB_CANT_CHECK 2048 /* has a feature which we don't understand */
  102. /**
  103. * ntdb_close - close and free a ntdb.
  104. * @ntdb: the ntdb context returned from ntdb_open()
  105. *
  106. * This always succeeds, in that @ntdb is unusable after this call. But if
  107. * some unexpected error occurred while closing, it will return non-zero
  108. * (the only clue as to cause will be via the log attribute).
  109. */
  110. int ntdb_close(struct ntdb_context *ntdb);
  111. /**
  112. * enum NTDB_ERROR - error returns for NTDB
  113. *
  114. * See Also:
  115. * ntdb_errorstr()
  116. */
  117. enum NTDB_ERROR {
  118. NTDB_SUCCESS = 0, /* No error. */
  119. NTDB_ERR_CORRUPT = -1, /* We read the db, and it was bogus. */
  120. NTDB_ERR_IO = -2, /* We couldn't read/write the db. */
  121. NTDB_ERR_LOCK = -3, /* Locking failed. */
  122. NTDB_ERR_OOM = -4, /* Out of Memory. */
  123. NTDB_ERR_EXISTS = -5, /* The key already exists. */
  124. NTDB_ERR_NOEXIST = -6, /* The key does not exist. */
  125. NTDB_ERR_EINVAL = -7, /* You're using it wrong. */
  126. NTDB_ERR_RDONLY = -8, /* The database is read-only. */
  127. NTDB_ERR_LAST = NTDB_ERR_RDONLY
  128. };
  129. /**
  130. * ntdb_store - store a key/value pair in a ntdb.
  131. * @ntdb: the ntdb context returned from ntdb_open()
  132. * @key: the key
  133. * @dbuf: the data to associate with the key.
  134. * @flag: NTDB_REPLACE, NTDB_INSERT or NTDB_MODIFY.
  135. *
  136. * This inserts (or overwrites) a key/value pair in the NTDB. If flag
  137. * is NTDB_REPLACE, it doesn't matter whether the key exists or not;
  138. * NTDB_INSERT means it must not exist (returns NTDB_ERR_EXISTS otherwise),
  139. * and NTDB_MODIFY means it must exist (returns NTDB_ERR_NOEXIST otherwise).
  140. *
  141. * On success, this returns NTDB_SUCCESS.
  142. *
  143. * See also:
  144. * ntdb_fetch, ntdb_transaction_start, ntdb_append, ntdb_delete.
  145. */
  146. enum NTDB_ERROR ntdb_store(struct ntdb_context *ntdb,
  147. NTDB_DATA key,
  148. NTDB_DATA dbuf,
  149. int flag);
  150. /* flags to ntdb_store() */
  151. #define NTDB_REPLACE 1 /* A readability place holder */
  152. #define NTDB_INSERT 2 /* Don't overwrite an existing entry */
  153. #define NTDB_MODIFY 3 /* Don't create an existing entry */
  154. /**
  155. * ntdb_fetch - fetch a value from a ntdb.
  156. * @ntdb: the ntdb context returned from ntdb_open()
  157. * @key: the key
  158. * @data: pointer to data.
  159. *
  160. * This looks up a key in the database and sets it in @data.
  161. *
  162. * If it returns NTDB_SUCCESS, the key was found: it is your
  163. * responsibility to call free() on @data->dptr.
  164. *
  165. * Otherwise, it returns an error (usually, NTDB_ERR_NOEXIST) and @data is
  166. * undefined.
  167. */
  168. enum NTDB_ERROR ntdb_fetch(struct ntdb_context *ntdb, NTDB_DATA key,
  169. NTDB_DATA *data);
  170. /**
  171. * ntdb_errorstr - map the ntdb error onto a constant readable string
  172. * @ecode: the enum NTDB_ERROR to map.
  173. *
  174. * This is useful for displaying errors to users.
  175. */
  176. const char *ntdb_errorstr(enum NTDB_ERROR ecode);
  177. /**
  178. * ntdb_append - append a value to a key/value pair in a ntdb.
  179. * @ntdb: the ntdb context returned from ntdb_open()
  180. * @key: the key
  181. * @dbuf: the data to append.
  182. *
  183. * This is equivalent to fetching a record, reallocating .dptr to add the
  184. * data, and writing it back, only it's much more efficient. If the key
  185. * doesn't exist, it's equivalent to ntdb_store (with an additional hint that
  186. * you expect to expand the record in future).
  187. *
  188. * See Also:
  189. * ntdb_fetch(), ntdb_store()
  190. */
  191. enum NTDB_ERROR ntdb_append(struct ntdb_context *ntdb,
  192. NTDB_DATA key, NTDB_DATA dbuf);
  193. /**
  194. * ntdb_delete - delete a key from a ntdb.
  195. * @ntdb: the ntdb context returned from ntdb_open()
  196. * @key: the key to delete.
  197. *
  198. * Returns NTDB_SUCCESS on success, or an error (usually NTDB_ERR_NOEXIST).
  199. *
  200. * See Also:
  201. * ntdb_fetch(), ntdb_store()
  202. */
  203. enum NTDB_ERROR ntdb_delete(struct ntdb_context *ntdb, NTDB_DATA key);
  204. /**
  205. * ntdb_exists - does a key exist in the database?
  206. * @ntdb: the ntdb context returned from ntdb_open()
  207. * @key: the key to search for.
  208. *
  209. * Returns true if it exists, or false if it doesn't or any other error.
  210. */
  211. bool ntdb_exists(struct ntdb_context *ntdb, NTDB_DATA key);
  212. /**
  213. * ntdb_deq - are NTDB_DATA equal?
  214. * @a: one NTDB_DATA
  215. * @b: another NTDB_DATA
  216. */
  217. static inline bool ntdb_deq(NTDB_DATA a, NTDB_DATA b)
  218. {
  219. return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0;
  220. }
  221. /**
  222. * ntdb_mkdata - make a NTDB_DATA from const data
  223. * @p: the constant pointer
  224. * @len: the length
  225. *
  226. * As the dptr member of NTDB_DATA is not constant, you need to
  227. * cast it. This function keeps thost casts in one place, as well as
  228. * suppressing the warning some compilers give when casting away a
  229. * qualifier (eg. gcc with -Wcast-qual)
  230. */
  231. static inline NTDB_DATA ntdb_mkdata(const void *p, size_t len)
  232. {
  233. NTDB_DATA d;
  234. d.dptr = cast_const(void *, p);
  235. d.dsize = len;
  236. return d;
  237. }
  238. /**
  239. * ntdb_transaction_start - start a transaction
  240. * @ntdb: the ntdb context returned from ntdb_open()
  241. *
  242. * This begins a series of atomic operations. Other processes will be able
  243. * to read the ntdb, but not alter it (they will block), nor will they see
  244. * any changes until ntdb_transaction_commit() is called.
  245. *
  246. * Note that if the NTDB_ALLOW_NESTING flag is set, a ntdb_transaction_start()
  247. * within a transaction will succeed, but it's not a real transaction:
  248. * (1) An inner transaction which is committed is not actually committed until
  249. * the outer transaction is; if the outer transaction is cancelled, the
  250. * inner ones are discarded.
  251. * (2) ntdb_transaction_cancel() marks the outer transaction as having an error,
  252. * so the final ntdb_transaction_commit() will fail.
  253. * (3) the outer transaction will see the results of the inner transaction.
  254. *
  255. * See Also:
  256. * ntdb_transaction_cancel, ntdb_transaction_commit.
  257. */
  258. enum NTDB_ERROR ntdb_transaction_start(struct ntdb_context *ntdb);
  259. /**
  260. * ntdb_transaction_cancel - abandon a transaction
  261. * @ntdb: the ntdb context returned from ntdb_open()
  262. *
  263. * This aborts a transaction, discarding any changes which were made.
  264. * ntdb_close() does this implicitly.
  265. */
  266. void ntdb_transaction_cancel(struct ntdb_context *ntdb);
  267. /**
  268. * ntdb_transaction_commit - commit a transaction
  269. * @ntdb: the ntdb context returned from ntdb_open()
  270. *
  271. * This completes a transaction, writing any changes which were made.
  272. *
  273. * fsync() is used to commit the transaction (unless NTDB_NOSYNC is set),
  274. * making it robust against machine crashes, but very slow compared to
  275. * other NTDB operations.
  276. *
  277. * A failure can only be caused by unexpected errors (eg. I/O or
  278. * memory); this is no point looping on transaction failure.
  279. *
  280. * See Also:
  281. * ntdb_transaction_prepare_commit()
  282. */
  283. enum NTDB_ERROR ntdb_transaction_commit(struct ntdb_context *ntdb);
  284. /**
  285. * ntdb_transaction_prepare_commit - prepare to commit a transaction
  286. * @ntdb: the ntdb context returned from ntdb_open()
  287. *
  288. * This ensures we have the resources to commit a transaction (using
  289. * ntdb_transaction_commit): if this succeeds then a transaction will only
  290. * fail if the write() or fsync() calls fail.
  291. *
  292. * If this fails you must still call ntdb_transaction_cancel() to cancel
  293. * the transaction.
  294. *
  295. * See Also:
  296. * ntdb_transaction_commit()
  297. */
  298. enum NTDB_ERROR ntdb_transaction_prepare_commit(struct ntdb_context *ntdb);
  299. /**
  300. * ntdb_traverse - traverse a NTDB
  301. * @ntdb: the ntdb context returned from ntdb_open()
  302. * @fn: the function to call for every key/value pair (or NULL)
  303. * @p: the pointer to hand to @f
  304. *
  305. * This walks the NTDB until all they keys have been traversed, or @fn
  306. * returns non-zero. If the traverse function or other processes are
  307. * changing data or adding or deleting keys, the traverse may be
  308. * unreliable: keys may be skipped or (rarely) visited twice.
  309. *
  310. * There is one specific exception: the special case of deleting the
  311. * current key does not undermine the reliability of the traversal.
  312. *
  313. * On success, returns the number of keys iterated. On error returns
  314. * a negative enum NTDB_ERROR value.
  315. */
  316. #define ntdb_traverse(ntdb, fn, p) \
  317. ntdb_traverse_(ntdb, typesafe_cb_preargs(int, void *, (fn), (p), \
  318. struct ntdb_context *, \
  319. NTDB_DATA, NTDB_DATA), (p))
  320. int64_t ntdb_traverse_(struct ntdb_context *ntdb,
  321. int (*fn)(struct ntdb_context *,
  322. NTDB_DATA, NTDB_DATA, void *), void *p);
  323. /**
  324. * ntdb_parse_record - operate directly on data in the database.
  325. * @ntdb: the ntdb context returned from ntdb_open()
  326. * @key: the key whose record we should hand to @parse
  327. * @parse: the function to call for the data
  328. * @data: the private pointer to hand to @parse (types must match).
  329. *
  330. * This avoids a copy for many cases, by handing you a pointer into
  331. * the memory-mapped database. It also locks the record to prevent
  332. * other accesses at the same time, so it won't change.
  333. *
  334. * Within the @parse callback you can perform read operations on the
  335. * database, but no write operations: no ntdb_store() or
  336. * ntdb_delete(), for example. The exception is if you call
  337. * ntdb_lockall() before ntdb_parse_record().
  338. *
  339. * Never alter the data handed to parse()!
  340. */
  341. #define ntdb_parse_record(ntdb, key, parse, data) \
  342. ntdb_parse_record_((ntdb), (key), \
  343. typesafe_cb_preargs(enum NTDB_ERROR, void *, \
  344. (parse), (data), \
  345. NTDB_DATA, NTDB_DATA), (data))
  346. enum NTDB_ERROR ntdb_parse_record_(struct ntdb_context *ntdb,
  347. NTDB_DATA key,
  348. enum NTDB_ERROR (*parse)(NTDB_DATA k,
  349. NTDB_DATA d,
  350. void *data),
  351. void *data);
  352. /**
  353. * ntdb_get_seqnum - get a database sequence number
  354. * @ntdb: the ntdb context returned from ntdb_open()
  355. *
  356. * This returns a sequence number: any change to the database from a
  357. * ntdb context opened with the NTDB_SEQNUM flag will cause that number
  358. * to increment. Note that the incrementing is unreliable (it is done
  359. * without locking), so this is only useful as an optimization.
  360. *
  361. * For example, you may have a regular database backup routine which
  362. * does not operate if the sequence number is unchanged. In the
  363. * unlikely event of a failed increment, it will be backed up next
  364. * time any way.
  365. *
  366. * Returns an enum NTDB_ERROR (ie. negative) on error.
  367. */
  368. int64_t ntdb_get_seqnum(struct ntdb_context *ntdb);
  369. /**
  370. * ntdb_firstkey - get the "first" key in a NTDB
  371. * @ntdb: the ntdb context returned from ntdb_open()
  372. * @key: pointer to key.
  373. *
  374. * This returns an arbitrary key in the database; with ntdb_nextkey() it allows
  375. * open-coded traversal of the database, though it is slightly less efficient
  376. * than ntdb_traverse.
  377. *
  378. * It is your responsibility to free @key->dptr on success.
  379. *
  380. * Returns NTDB_ERR_NOEXIST if the database is empty.
  381. */
  382. enum NTDB_ERROR ntdb_firstkey(struct ntdb_context *ntdb, NTDB_DATA *key);
  383. /**
  384. * ntdb_nextkey - get the "next" key in a NTDB
  385. * @ntdb: the ntdb context returned from ntdb_open()
  386. * @key: a key returned by ntdb_firstkey() or ntdb_nextkey().
  387. *
  388. * This returns another key in the database; it will free @key.dptr for
  389. * your convenience.
  390. *
  391. * Returns NTDB_ERR_NOEXIST if there are no more keys.
  392. */
  393. enum NTDB_ERROR ntdb_nextkey(struct ntdb_context *ntdb, NTDB_DATA *key);
  394. /**
  395. * ntdb_chainlock - lock a record in the NTDB
  396. * @ntdb: the ntdb context returned from ntdb_open()
  397. * @key: the key to lock.
  398. *
  399. * This prevents any access occurring to a group of keys including @key,
  400. * even if @key does not exist. This allows primitive atomic updates of
  401. * records without using transactions.
  402. *
  403. * You cannot begin a transaction while holding a ntdb_chainlock(), nor can
  404. * you do any operations on any other keys in the database. This also means
  405. * that you cannot hold more than one ntdb_chainlock() at a time.
  406. *
  407. * See Also:
  408. * ntdb_chainunlock()
  409. */
  410. enum NTDB_ERROR ntdb_chainlock(struct ntdb_context *ntdb, NTDB_DATA key);
  411. /**
  412. * ntdb_chainunlock - unlock a record in the NTDB
  413. * @ntdb: the ntdb context returned from ntdb_open()
  414. * @key: the key to unlock.
  415. *
  416. * The key must have previously been locked by ntdb_chainlock().
  417. */
  418. void ntdb_chainunlock(struct ntdb_context *ntdb, NTDB_DATA key);
  419. /**
  420. * ntdb_chainlock_read - lock a record in the NTDB, for reading
  421. * @ntdb: the ntdb context returned from ntdb_open()
  422. * @key: the key to lock.
  423. *
  424. * This prevents any changes from occurring to a group of keys including @key,
  425. * even if @key does not exist. This allows primitive atomic updates of
  426. * records without using transactions.
  427. *
  428. * You cannot begin a transaction while holding a ntdb_chainlock_read(), nor can
  429. * you do any operations on any other keys in the database. This also means
  430. * that you cannot hold more than one ntdb_chainlock()/read() at a time.
  431. *
  432. * See Also:
  433. * ntdb_chainlock()
  434. */
  435. enum NTDB_ERROR ntdb_chainlock_read(struct ntdb_context *ntdb, NTDB_DATA key);
  436. /**
  437. * ntdb_chainunlock_read - unlock a record in the NTDB for reading
  438. * @ntdb: the ntdb context returned from ntdb_open()
  439. * @key: the key to unlock.
  440. *
  441. * The key must have previously been locked by ntdb_chainlock_read().
  442. */
  443. void ntdb_chainunlock_read(struct ntdb_context *ntdb, NTDB_DATA key);
  444. /**
  445. * ntdb_lockall - lock the entire NTDB
  446. * @ntdb: the ntdb context returned from ntdb_open()
  447. *
  448. * You cannot hold a ntdb_chainlock while calling this. It nests, so you
  449. * must call ntdb_unlockall as many times as you call ntdb_lockall.
  450. */
  451. enum NTDB_ERROR ntdb_lockall(struct ntdb_context *ntdb);
  452. /**
  453. * ntdb_unlockall - unlock the entire NTDB
  454. * @ntdb: the ntdb context returned from ntdb_open()
  455. */
  456. void ntdb_unlockall(struct ntdb_context *ntdb);
  457. /**
  458. * ntdb_lockall_read - lock the entire NTDB for reading
  459. * @ntdb: the ntdb context returned from ntdb_open()
  460. *
  461. * This prevents others writing to the database, eg. ntdb_delete, ntdb_store,
  462. * ntdb_append, but not ntdb_fetch.
  463. *
  464. * You cannot hold a ntdb_chainlock while calling this. It nests, so you
  465. * must call ntdb_unlockall_read as many times as you call ntdb_lockall_read.
  466. */
  467. enum NTDB_ERROR ntdb_lockall_read(struct ntdb_context *ntdb);
  468. /**
  469. * ntdb_unlockall_read - unlock the entire NTDB for reading
  470. * @ntdb: the ntdb context returned from ntdb_open()
  471. */
  472. void ntdb_unlockall_read(struct ntdb_context *ntdb);
  473. /**
  474. * ntdb_wipe_all - wipe the database clean
  475. * @ntdb: the ntdb context returned from ntdb_open()
  476. *
  477. * Completely erase the database. This is faster than iterating through
  478. * each key and doing ntdb_delete.
  479. */
  480. enum NTDB_ERROR ntdb_wipe_all(struct ntdb_context *ntdb);
  481. /**
  482. * ntdb_repack - repack the database
  483. * @ntdb: the ntdb context returned from ntdb_open()
  484. *
  485. * This repacks the database; if it is suffering from a great deal of
  486. * fragmentation this might help. However, it can take twice the
  487. * memory of the existing NTDB.
  488. */
  489. enum NTDB_ERROR ntdb_repack(struct ntdb_context *ntdb);
  490. /**
  491. * ntdb_check - check a NTDB for consistency
  492. * @ntdb: the ntdb context returned from ntdb_open()
  493. * @check: function to check each key/data pair (or NULL)
  494. * @data: argument for @check, must match type.
  495. *
  496. * This performs a consistency check of the open database, optionally calling
  497. * a check() function on each record so you can do your own data consistency
  498. * checks as well. If check() returns an error, that is returned from
  499. * ntdb_check().
  500. *
  501. * Note that the NTDB uses a feature which we don't understand which
  502. * indicates we can't run ntdb_check(), this will log a warning to that
  503. * effect and return NTDB_SUCCESS. You can detect this condition by
  504. * looking for NTDB_CANT_CHECK in ntdb_get_flags().
  505. *
  506. * Returns NTDB_SUCCESS or an error.
  507. */
  508. #define ntdb_check(ntdb, check, data) \
  509. ntdb_check_((ntdb), typesafe_cb_preargs(enum NTDB_ERROR, void *, \
  510. (check), (data), \
  511. NTDB_DATA, \
  512. NTDB_DATA), \
  513. (data))
  514. enum NTDB_ERROR ntdb_check_(struct ntdb_context *ntdb,
  515. enum NTDB_ERROR (*check)(NTDB_DATA k,
  516. NTDB_DATA d,
  517. void *data),
  518. void *data);
  519. /**
  520. * enum ntdb_summary_flags - flags for ntdb_summary.
  521. */
  522. enum ntdb_summary_flags {
  523. NTDB_SUMMARY_HISTOGRAMS = 1 /* Draw graphs in the summary. */
  524. };
  525. /**
  526. * ntdb_summary - return a string describing the NTDB state
  527. * @ntdb: the ntdb context returned from ntdb_open()
  528. * @flags: flags to control the summary output.
  529. * @summary: pointer to string to allocate.
  530. *
  531. * This returns a developer-readable string describing the overall
  532. * state of the ntdb, such as the percentage used and sizes of records.
  533. * It is designed to provide information about the ntdb at a glance
  534. * without displaying any keys or data in the database.
  535. *
  536. * On success, sets @summary to point to a malloc()'ed nul-terminated
  537. * multi-line string. It is your responsibility to free() it.
  538. */
  539. enum NTDB_ERROR ntdb_summary(struct ntdb_context *ntdb,
  540. enum ntdb_summary_flags flags,
  541. char **summary);
  542. /**
  543. * ntdb_get_flags - return the flags for a ntdb
  544. * @ntdb: the ntdb context returned from ntdb_open()
  545. *
  546. * This returns the flags on the current ntdb. Some of these are caused by
  547. * the flags argument to ntdb_open(), others (such as NTDB_CONVERT) are
  548. * intuited.
  549. */
  550. unsigned int ntdb_get_flags(struct ntdb_context *ntdb);
  551. /**
  552. * ntdb_add_flag - set a flag for a ntdb
  553. * @ntdb: the ntdb context returned from ntdb_open()
  554. * @flag: one of NTDB_NOLOCK, NTDB_NOMMAP, NTDB_NOSYNC or NTDB_ALLOW_NESTING.
  555. *
  556. * You can use this to set a flag on the NTDB. You cannot set these flags
  557. * on a NTDB_INTERNAL ntdb.
  558. */
  559. void ntdb_add_flag(struct ntdb_context *ntdb, unsigned flag);
  560. /**
  561. * ntdb_remove_flag - unset a flag for a ntdb
  562. * @ntdb: the ntdb context returned from ntdb_open()
  563. * @flag: one of NTDB_NOLOCK, NTDB_NOMMAP, NTDB_NOSYNC or NTDB_ALLOW_NESTING.
  564. *
  565. * You can use this to clear a flag on the NTDB. You cannot clear flags
  566. * on a NTDB_INTERNAL ntdb.
  567. */
  568. void ntdb_remove_flag(struct ntdb_context *ntdb, unsigned flag);
  569. /**
  570. * enum ntdb_attribute_type - descriminator for union ntdb_attribute.
  571. */
  572. enum ntdb_attribute_type {
  573. NTDB_ATTRIBUTE_LOG = 0,
  574. NTDB_ATTRIBUTE_HASH = 1,
  575. NTDB_ATTRIBUTE_SEED = 2,
  576. NTDB_ATTRIBUTE_STATS = 3,
  577. NTDB_ATTRIBUTE_OPENHOOK = 4,
  578. NTDB_ATTRIBUTE_FLOCK = 5,
  579. NTDB_ATTRIBUTE_ALLOCATOR = 6,
  580. NTDB_ATTRIBUTE_HASHSIZE = 7
  581. };
  582. /**
  583. * ntdb_get_attribute - get an attribute for an existing ntdb
  584. * @ntdb: the ntdb context returned from ntdb_open()
  585. * @attr: the union ntdb_attribute to set.
  586. *
  587. * This gets an attribute from a NTDB which has previously been set (or
  588. * may return the default values). Set @attr.base.attr to the
  589. * attribute type you want get.
  590. */
  591. enum NTDB_ERROR ntdb_get_attribute(struct ntdb_context *ntdb,
  592. union ntdb_attribute *attr);
  593. /**
  594. * ntdb_set_attribute - set an attribute for an existing ntdb
  595. * @ntdb: the ntdb context returned from ntdb_open()
  596. * @attr: the union ntdb_attribute to set.
  597. *
  598. * This sets an attribute on a NTDB, overriding any previous attribute
  599. * of the same type. It returns NTDB_ERR_EINVAL if the attribute is
  600. * unknown or invalid.
  601. *
  602. * Note that NTDB_ATTRIBUTE_HASH, NTDB_ATTRIBUTE_SEED, and
  603. * NTDB_ATTRIBUTE_OPENHOOK cannot currently be set after ntdb_open.
  604. */
  605. enum NTDB_ERROR ntdb_set_attribute(struct ntdb_context *ntdb,
  606. const union ntdb_attribute *attr);
  607. /**
  608. * ntdb_unset_attribute - reset an attribute for an existing ntdb
  609. * @ntdb: the ntdb context returned from ntdb_open()
  610. * @type: the attribute type to unset.
  611. *
  612. * This unsets an attribute on a NTDB, returning it to the defaults
  613. * (where applicable).
  614. *
  615. * Note that it only makes sense for NTDB_ATTRIBUTE_LOG and NTDB_ATTRIBUTE_FLOCK
  616. * to be unset.
  617. */
  618. void ntdb_unset_attribute(struct ntdb_context *ntdb,
  619. enum ntdb_attribute_type type);
  620. /**
  621. * ntdb_name - get the name of a ntdb
  622. * @ntdb: the ntdb context returned from ntdb_open()
  623. *
  624. * This returns a copy of the name string, made at ntdb_open() time.
  625. *
  626. * This is mostly useful for logging.
  627. */
  628. const char *ntdb_name(const struct ntdb_context *ntdb);
  629. /**
  630. * ntdb_fd - get the file descriptor of a ntdb
  631. * @ntdb: the ntdb context returned from ntdb_open()
  632. *
  633. * This returns the file descriptor for the underlying database file, or -1
  634. * for NTDB_INTERNAL.
  635. */
  636. int ntdb_fd(const struct ntdb_context *ntdb);
  637. /**
  638. * ntdb_foreach - iterate through every open NTDB.
  639. * @fn: the function to call for every NTDB
  640. * @p: the pointer to hand to @fn
  641. *
  642. * NTDB internally keeps track of all open TDBs; this function allows you to
  643. * iterate through them. If @fn returns non-zero, traversal stops.
  644. */
  645. #define ntdb_foreach(fn, p) \
  646. ntdb_foreach_(typesafe_cb_preargs(int, void *, (fn), (p), \
  647. struct ntdb_context *), (p))
  648. void ntdb_foreach_(int (*fn)(struct ntdb_context *, void *), void *p);
  649. /**
  650. * struct ntdb_attribute_base - common fields for all ntdb attributes.
  651. */
  652. struct ntdb_attribute_base {
  653. enum ntdb_attribute_type attr;
  654. union ntdb_attribute *next;
  655. };
  656. /**
  657. * enum ntdb_log_level - log levels for ntdb_attribute_log
  658. * @NTDB_LOG_ERROR: used to log unrecoverable errors such as I/O errors
  659. * or internal consistency failures.
  660. * @NTDB_LOG_USE_ERROR: used to log usage errors such as invalid parameters
  661. * or writing to a read-only database.
  662. * @NTDB_LOG_WARNING: used for informational messages on issues which
  663. * are unusual but handled by NTDB internally, such
  664. * as a failure to mmap or failure to open /dev/urandom.
  665. * It's also used when ntdb_open() fails without O_CREAT
  666. * because a file does not exist.
  667. */
  668. enum ntdb_log_level {
  669. NTDB_LOG_ERROR,
  670. NTDB_LOG_USE_ERROR,
  671. NTDB_LOG_WARNING
  672. };
  673. /**
  674. * struct ntdb_attribute_log - log function attribute
  675. *
  676. * This attribute provides a hook for you to log errors.
  677. */
  678. struct ntdb_attribute_log {
  679. struct ntdb_attribute_base base; /* .attr = NTDB_ATTRIBUTE_LOG */
  680. void (*fn)(struct ntdb_context *ntdb,
  681. enum ntdb_log_level level,
  682. enum NTDB_ERROR ecode,
  683. const char *message,
  684. void *data);
  685. void *data;
  686. };
  687. /**
  688. * struct ntdb_attribute_hash - hash function attribute
  689. *
  690. * This attribute allows you to provide an alternative hash function.
  691. * This hash function will be handed keys from the database; it will also
  692. * be handed the 8-byte NTDB_HASH_MAGIC value for checking the header (the
  693. * ntdb_open() will fail if the hash value doesn't match the header).
  694. *
  695. * Note that if your hash function gives different results on
  696. * different machine endians, your ntdb will no longer work across
  697. * different architectures!
  698. */
  699. struct ntdb_attribute_hash {
  700. struct ntdb_attribute_base base; /* .attr = NTDB_ATTRIBUTE_HASH */
  701. uint32_t (*fn)(const void *key, size_t len, uint32_t seed,
  702. void *data);
  703. void *data;
  704. };
  705. /**
  706. * struct ntdb_attribute_seed - hash function seed attribute
  707. *
  708. * The hash function seed is normally taken from /dev/urandom (or equivalent)
  709. * but can be set manually here. This is mainly for testing purposes.
  710. */
  711. struct ntdb_attribute_seed {
  712. struct ntdb_attribute_base base; /* .attr = NTDB_ATTRIBUTE_SEED */
  713. uint64_t seed;
  714. };
  715. /**
  716. * struct ntdb_attribute_stats - ntdb operational statistics
  717. *
  718. * This attribute records statistics of various low-level NTDB operations.
  719. * This can be used to assist performance evaluation. This is only
  720. * useful for ntdb_get_attribute().
  721. *
  722. * New fields will be added at the end, hence the "size" argument which
  723. * indicates how large your structure is: it must be filled in before
  724. * calling ntdb_get_attribute(), which will overwrite it with the size
  725. * ntdb knows about.
  726. */
  727. struct ntdb_attribute_stats {
  728. struct ntdb_attribute_base base; /* .attr = NTDB_ATTRIBUTE_STATS */
  729. size_t size; /* = sizeof(struct ntdb_attribute_stats) */
  730. uint64_t allocs;
  731. uint64_t alloc_subhash;
  732. uint64_t alloc_chain;
  733. uint64_t alloc_bucket_exact;
  734. uint64_t alloc_bucket_max;
  735. uint64_t alloc_leftover;
  736. uint64_t alloc_coalesce_tried;
  737. uint64_t alloc_coalesce_iterate_clash;
  738. uint64_t alloc_coalesce_lockfail;
  739. uint64_t alloc_coalesce_race;
  740. uint64_t alloc_coalesce_succeeded;
  741. uint64_t alloc_coalesce_num_merged;
  742. uint64_t compares;
  743. uint64_t compare_wrong_offsetbits;
  744. uint64_t compare_wrong_keylen;
  745. uint64_t compare_wrong_rechash;
  746. uint64_t compare_wrong_keycmp;
  747. uint64_t transactions;
  748. uint64_t transaction_cancel;
  749. uint64_t transaction_nest;
  750. uint64_t transaction_expand_file;
  751. uint64_t transaction_read_direct;
  752. uint64_t transaction_read_direct_fail;
  753. uint64_t transaction_write_direct;
  754. uint64_t transaction_write_direct_fail;
  755. uint64_t traverses;
  756. uint64_t traverse_val_vanished;
  757. uint64_t expands;
  758. uint64_t frees;
  759. uint64_t locks;
  760. uint64_t lock_lowlevel;
  761. uint64_t lock_nonblock;
  762. uint64_t lock_nonblock_fail;
  763. };
  764. /**
  765. * struct ntdb_attribute_openhook - ntdb special effects hook for open
  766. *
  767. * This attribute contains a function to call once we have the OPEN_LOCK
  768. * for the ntdb, but before we've examined its contents. If this succeeds,
  769. * the ntdb will be populated if it's then zero-length.
  770. *
  771. * This is a hack to allow support for TDB-style TDB_CLEAR_IF_FIRST
  772. * behaviour.
  773. */
  774. struct ntdb_attribute_openhook {
  775. struct ntdb_attribute_base base; /* .attr = NTDB_ATTRIBUTE_OPENHOOK */
  776. enum NTDB_ERROR (*fn)(int fd, void *data);
  777. void *data;
  778. };
  779. /**
  780. * struct ntdb_attribute_flock - ntdb special effects hook for file locking
  781. *
  782. * This attribute contains function to call to place locks on a file; it can
  783. * be used to support non-blocking operations or lock proxying.
  784. *
  785. * They should return 0 on success, -1 on failure and set errno.
  786. *
  787. * An error will be logged on error if errno is neither EAGAIN nor EINTR
  788. * (normally it would only return EAGAIN if waitflag is false, and
  789. * loop internally on EINTR).
  790. */
  791. struct ntdb_attribute_flock {
  792. struct ntdb_attribute_base base; /* .attr = NTDB_ATTRIBUTE_FLOCK */
  793. int (*lock)(int fd,int rw, off_t off, off_t len, bool waitflag, void *);
  794. int (*unlock)(int fd, int rw, off_t off, off_t len, void *);
  795. void *data;
  796. };
  797. /**
  798. * struct ntdb_attribute_hashsize - ntdb hashsize setting.
  799. *
  800. * This attribute is only settable on ntdb_open; it indicates that we create
  801. * a hashtable of the given size, rather than the default.
  802. */
  803. struct ntdb_attribute_hashsize {
  804. struct ntdb_attribute_base base; /* .attr = NTDB_ATTRIBUTE_HASHSIZE */
  805. uint32_t size;
  806. };
  807. /**
  808. * struct ntdb_attribute_allocator - allocator for ntdb to use.
  809. *
  810. * You can replace malloc/free with your own allocation functions.
  811. * The allocator takes an "owner" pointer, which is either NULL (for
  812. * the initial struct ntdb_context and struct ntdb_file), or a
  813. * previously allocated pointer. This is useful for relationship
  814. * tracking, such as the talloc library.
  815. *
  816. * The expand function is realloc, but only ever used to expand an
  817. * existing allocation.
  818. *
  819. * Be careful mixing allocators: two ntdb_contexts which have the same file
  820. * open will share the same struct ntdb_file. This may be allocated by one
  821. * ntdb's allocator, and freed by the other.
  822. */
  823. struct ntdb_attribute_allocator {
  824. struct ntdb_attribute_base base; /* .attr = NTDB_ATTRIBUTE_ALLOCATOR */
  825. void *(*alloc)(const void *owner, size_t len, void *priv_data);
  826. void *(*expand)(void *old, size_t newlen, void *priv_data);
  827. void (*free)(void *old, void *priv_data);
  828. void *priv_data;
  829. };
  830. /**
  831. * union ntdb_attribute - ntdb attributes.
  832. *
  833. * This represents all the known attributes.
  834. *
  835. * See also:
  836. * struct ntdb_attribute_log, struct ntdb_attribute_hash,
  837. * struct ntdb_attribute_seed, struct ntdb_attribute_stats,
  838. * struct ntdb_attribute_openhook, struct ntdb_attribute_flock,
  839. * struct ntdb_attribute_allocator alloc.
  840. */
  841. union ntdb_attribute {
  842. struct ntdb_attribute_base base;
  843. struct ntdb_attribute_log log;
  844. struct ntdb_attribute_hash hash;
  845. struct ntdb_attribute_seed seed;
  846. struct ntdb_attribute_stats stats;
  847. struct ntdb_attribute_openhook openhook;
  848. struct ntdb_attribute_flock flock;
  849. struct ntdb_attribute_allocator alloc;
  850. struct ntdb_attribute_hashsize hashsize;
  851. };
  852. #ifdef __cplusplus
  853. }
  854. #endif
  855. #endif /* ntdb.h */