tdb/include/tdb.h

ソースコードを見る。

データ構造

struct  TDB_DATA
struct  tdb_logging_context

型定義

typedef tdb_context TDB_CONTEXT
typedef int(*) tdb_traverse_func (struct tdb_context *, TDB_DATA, TDB_DATA, void *)
typedef void(*) tdb_log_func (struct tdb_context *, enum tdb_debug_level, const char *,...) PRINTF_ATTRIBUTE(3
typedef void(*) typedef unsigned
int(*) 
tdb_hash_func (TDB_DATA *key)

列挙型

enum  TDB_ERROR {
  TDB_SUCCESS = 0, TDB_ERR_CORRUPT, TDB_ERR_IO,
  TDB_ERR_LOCK, TDB_ERR_OOM, TDB_ERR_EXISTS,
  TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, TDB_ERR_NOEXIST,
  TDB_ERR_EINVAL, TDB_ERR_RDONLY
}
enum  tdb_debug_level {
  TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, TDB_DEBUG_WARNING,
  TDB_DEBUG_TRACE
}

関数

tdb_contexttdb_open (const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode)
tdb_contexttdb_open_ex (const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, const struct tdb_logging_context *log_ctx, tdb_hash_func hash_fn)
void tdb_set_max_dead (struct tdb_context *tdb, int max_dead)
int tdb_reopen (struct tdb_context *tdb)
int tdb_reopen_all (int parent_longlived)
void tdb_set_logging_function (struct tdb_context *tdb, const struct tdb_logging_context *log_ctx)
enum TDB_ERROR tdb_error (struct tdb_context *tdb)
const char * tdb_errorstr (struct tdb_context *tdb)
TDB_DATA tdb_fetch (struct tdb_context *tdb, TDB_DATA key)
int tdb_parse_record (struct tdb_context *tdb, TDB_DATA key, int(*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data)
int tdb_delete (struct tdb_context *tdb, TDB_DATA key)
int tdb_store (struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
int tdb_append (struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
int tdb_close (struct tdb_context *tdb)
 Close a database.
TDB_DATA tdb_firstkey (struct tdb_context *tdb)
TDB_DATA tdb_nextkey (struct tdb_context *tdb, TDB_DATA key)
int tdb_traverse (struct tdb_context *tdb, tdb_traverse_func fn, void *)
int tdb_traverse_read (struct tdb_context *tdb, tdb_traverse_func fn, void *)
int tdb_exists (struct tdb_context *tdb, TDB_DATA key)
int tdb_lockall (struct tdb_context *tdb)
int tdb_unlockall (struct tdb_context *tdb)
int tdb_lockall_read (struct tdb_context *tdb)
int tdb_unlockall_read (struct tdb_context *tdb)
const char * tdb_name (struct tdb_context *tdb)
int tdb_fd (struct tdb_context *tdb)
tdb_log_func tdb_log_fn (struct tdb_context *tdb)
void * tdb_get_logging_private (struct tdb_context *tdb)
int tdb_transaction_start (struct tdb_context *tdb)
int tdb_transaction_commit (struct tdb_context *tdb)
int tdb_transaction_cancel (struct tdb_context *tdb)
int tdb_transaction_recover (struct tdb_context *tdb)
int tdb_get_seqnum (struct tdb_context *tdb)
int tdb_hash_size (struct tdb_context *tdb)
size_t tdb_map_size (struct tdb_context *tdb)
int tdb_get_flags (struct tdb_context *tdb)
int tdb_chainlock (struct tdb_context *tdb, TDB_DATA key)
int tdb_chainunlock (struct tdb_context *tdb, TDB_DATA key)
int tdb_chainlock_read (struct tdb_context *tdb, TDB_DATA key)
int tdb_chainunlock_read (struct tdb_context *tdb, TDB_DATA key)
void tdb_setalarm_sigptr (struct tdb_context *tdb, volatile sig_atomic_t *sigptr)
void tdb_dump_all (struct tdb_context *tdb)
int tdb_printfreelist (struct tdb_context *tdb)
int tdb_validate_freelist (struct tdb_context *tdb, int *pnum_entries)

変数

TDB_DATA tdb_null


型定義

typedef struct tdb_context TDB_CONTEXT

tdb.h80 行で定義されています。

typedef int(*) tdb_traverse_func(struct tdb_context *, TDB_DATA, TDB_DATA, void *)

tdb.h82 行で定義されています。

typedef void(*) tdb_log_func(struct tdb_context *, enum tdb_debug_level, const char *,...) PRINTF_ATTRIBUTE(3

tdb.h83 行で定義されています。

typedef void(*) typedef unsigned int(*) tdb_hash_func(TDB_DATA *key)

tdb.h84 行で定義されています。


列挙型

enum TDB_ERROR

列挙型の値:
TDB_SUCCESS 
TDB_ERR_CORRUPT 
TDB_ERR_IO 
TDB_ERR_LOCK 
TDB_ERR_OOM 
TDB_ERR_EXISTS 
TDB_ERR_NOLOCK 
TDB_ERR_LOCK_TIMEOUT 
TDB_ERR_NOEXIST 
TDB_ERR_EINVAL 
TDB_ERR_RDONLY 

tdb.h54 行で定義されています。

enum tdb_debug_level

列挙型の値:
TDB_DEBUG_FATAL 
TDB_DEBUG_ERROR 
TDB_DEBUG_WARNING 
TDB_DEBUG_TRACE 

tdb.h59 行で定義されています。


関数

struct tdb_context* tdb_open ( const char *  name,
int  hash_size,
int  tdb_flags,
int  open_flags,
mode_t  mode 
)

open.c133 行で定義されています。

参照先 tdb_open_ex().

参照元 backup_tdb()create_tdb()dump_tdb()hash_a_service()main()move_rec()open_tdb()py_tdb_open()smb_share_mode_db_open()tdb_validate_freelist()torture_mangle()verify_tdb().

00135 {
00136         return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL);
00137 }

struct tdb_context* tdb_open_ex ( const char *  name,
int  hash_size,
int  tdb_flags,
int  open_flags,
mode_t  mode,
const struct tdb_logging_context log_ctx,
tdb_hash_func  hash_fn 
)

open.c146 行で定義されています。

参照先 default_tdb_hash()errnotdb_logging_context::log_fnnull_log_fn()strdup()strerror()tdbtdb_already_open()tdb_convert()TDB_DEBUG_ERRORTDB_DEBUG_FATALTDB_DEBUG_WARNINGtdb_io_init()tdb_mmap()tdb_munmap()tdb_new_database()tdb_transaction_recover()tdbs.

参照元 main()mangle_hash_init()reset_stat_cache()tdb_open()tdb_open_log().

00150 {
00151         struct tdb_context *tdb;
00152         struct stat st;
00153         int rev = 0, locked = 0;
00154         unsigned char *vp;
00155         u32 vertest;
00156 
00157         if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) {
00158                 /* Can't log this */
00159                 errno = ENOMEM;
00160                 goto fail;
00161         }
00162         tdb_io_init(tdb);
00163         tdb->fd = -1;
00164         tdb->name = NULL;
00165         tdb->map_ptr = NULL;
00166         tdb->flags = tdb_flags;
00167         tdb->open_flags = open_flags;
00168         if (log_ctx) {
00169                 tdb->log = *log_ctx;
00170         } else {
00171                 tdb->log.log_fn = null_log_fn;
00172                 tdb->log.log_private = NULL;
00173         }
00174         tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash;
00175 
00176         /* cache the page size */
00177         tdb->page_size = getpagesize();
00178         if (tdb->page_size <= 0) {
00179                 tdb->page_size = 0x2000;
00180         }
00181 
00182         if ((open_flags & O_ACCMODE) == O_WRONLY) {
00183                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n",
00184                          name));
00185                 errno = EINVAL;
00186                 goto fail;
00187         }
00188         
00189         if (hash_size == 0)
00190                 hash_size = DEFAULT_HASH_SIZE;
00191         if ((open_flags & O_ACCMODE) == O_RDONLY) {
00192                 tdb->read_only = 1;
00193                 /* read only databases don't do locking or clear if first */
00194                 tdb->flags |= TDB_NOLOCK;
00195                 tdb->flags &= ~TDB_CLEAR_IF_FIRST;
00196         }
00197 
00198         /* internal databases don't mmap or lock, and start off cleared */
00199         if (tdb->flags & TDB_INTERNAL) {
00200                 tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP);
00201                 tdb->flags &= ~TDB_CLEAR_IF_FIRST;
00202                 if (tdb_new_database(tdb, hash_size) != 0) {
00203                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!"));
00204                         goto fail;
00205                 }
00206                 goto internal;
00207         }
00208 
00209         if ((tdb->fd = open(name, open_flags, mode)) == -1) {
00210                 TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n",
00211                          name, strerror(errno)));
00212                 goto fail;      /* errno set by open(2) */
00213         }
00214 
00215         /* ensure there is only one process initialising at once */
00216         if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
00217                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get global lock on %s: %s\n",
00218                          name, strerror(errno)));
00219                 goto fail;      /* errno set by tdb_brlock */
00220         }
00221 
00222         /* we need to zero database if we are the only one with it open */
00223         if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
00224             (locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))) {
00225                 open_flags |= O_CREAT;
00226                 if (ftruncate(tdb->fd, 0) == -1) {
00227                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
00228                                  "failed to truncate %s: %s\n",
00229                                  name, strerror(errno)));
00230                         goto fail; /* errno set by ftruncate */
00231                 }
00232         }
00233 
00234         errno = 0;
00235         if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
00236             || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
00237             || (tdb->header.version != TDB_VERSION
00238                 && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
00239                 /* its not a valid database - possibly initialise it */
00240                 if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
00241                         if (errno == 0) {
00242                                 errno = EIO; /* ie bad format or something */
00243                         }
00244                         goto fail;
00245                 }
00246                 rev = (tdb->flags & TDB_CONVERT);
00247         }
00248         vp = (unsigned char *)&tdb->header.version;
00249         vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) |
00250                   (((u32)vp[2]) << 8) | (u32)vp[3];
00251         tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0;
00252         if (!rev)
00253                 tdb->flags &= ~TDB_CONVERT;
00254         else {
00255                 tdb->flags |= TDB_CONVERT;
00256                 tdb_convert(&tdb->header, sizeof(tdb->header));
00257         }
00258         if (fstat(tdb->fd, &st) == -1)
00259                 goto fail;
00260 
00261         if (tdb->header.rwlocks != 0) {
00262                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n"));
00263                 goto fail;
00264         }
00265 
00266         /* Is it already in the open list?  If so, fail. */
00267         if (tdb_already_open(st.st_dev, st.st_ino)) {
00268                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
00269                          "%s (%d,%d) is already open in this process\n",
00270                          name, (int)st.st_dev, (int)st.st_ino));
00271                 errno = EBUSY;
00272                 goto fail;
00273         }
00274 
00275         if (!(tdb->name = (char *)strdup(name))) {
00276                 errno = ENOMEM;
00277                 goto fail;
00278         }
00279 
00280         tdb->map_size = st.st_size;
00281         tdb->device = st.st_dev;
00282         tdb->inode = st.st_ino;
00283         tdb->max_dead_records = 0;
00284         tdb_mmap(tdb);
00285         if (locked) {
00286                 if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) {
00287                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
00288                                  "failed to take ACTIVE_LOCK on %s: %s\n",
00289                                  name, strerror(errno)));
00290                         goto fail;
00291                 }
00292 
00293         }
00294 
00295         /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if
00296            we didn't get the initial exclusive lock as we need to let all other
00297            users know we're using it. */
00298 
00299         if (tdb_flags & TDB_CLEAR_IF_FIRST) {
00300                 /* leave this lock in place to indicate it's in use */
00301                 if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1)
00302                         goto fail;
00303         }
00304 
00305         /* if needed, run recovery */
00306         if (tdb_transaction_recover(tdb) == -1) {
00307                 goto fail;
00308         }
00309 
00310  internal:
00311         /* Internal (memory-only) databases skip all the code above to
00312          * do with disk files, and resume here by releasing their
00313          * global lock and hooking into the active list. */
00314         if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1) == -1)
00315                 goto fail;
00316         tdb->next = tdbs;
00317         tdbs = tdb;
00318         return tdb;
00319 
00320  fail:
00321         { int save_errno = errno;
00322 
00323         if (!tdb)
00324                 return NULL;
00325         
00326         if (tdb->map_ptr) {
00327                 if (tdb->flags & TDB_INTERNAL)
00328                         SAFE_FREE(tdb->map_ptr);
00329                 else
00330                         tdb_munmap(tdb);
00331         }
00332         SAFE_FREE(tdb->name);
00333         if (tdb->fd != -1)
00334                 if (close(tdb->fd) != 0)
00335                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n"));
00336         SAFE_FREE(tdb);
00337         errno = save_errno;
00338         return NULL;
00339         }
00340 }

void tdb_set_max_dead ( struct tdb_context tdb,
int  max_dead 
)

open.c346 行で定義されています。

参照先 tdb_context::max_dead_recordstdb.

参照元 brl_init()locking_init()message_init().

00347 {
00348         tdb->max_dead_records = max_dead;
00349 }

int tdb_reopen ( struct tdb_context tdb  ) 

open.c404 行で定義されています。

参照先 tdb_lock_type::counttdb_context::deviceerrnotdb_context::fdtdb_context::flagstdb_context::global_locktdb_context::inodetdb_context::methodstdb_context::nametdb_context::num_lockstdb_context::open_flagsstrerror()tdbtdb_methods::tdb_brlocktdb_close()TDB_DEBUG_ERRORTDB_DEBUG_FATALtdb_mmap()tdb_munmap()tdb_context::transaction.

参照元 tdb_reopen_all()wins_write_database().

00405 {
00406         struct stat st;
00407 
00408         if (tdb->flags & TDB_INTERNAL) {
00409                 return 0; /* Nothing to do. */
00410         }
00411 
00412         if (tdb->num_locks != 0 || tdb->global_lock.count) {
00413                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n"));
00414                 goto fail;
00415         }
00416 
00417         if (tdb->transaction != 0) {
00418                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n"));
00419                 goto fail;
00420         }
00421 
00422         if (tdb_munmap(tdb) != 0) {
00423                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
00424                 goto fail;
00425         }
00426         if (close(tdb->fd) != 0)
00427                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n"));
00428         tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
00429         if (tdb->fd == -1) {
00430                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno)));
00431                 goto fail;
00432         }
00433         if ((tdb->flags & TDB_CLEAR_IF_FIRST) && 
00434             (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1)) {
00435                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n"));
00436                 goto fail;
00437         }
00438         if (fstat(tdb->fd, &st) != 0) {
00439                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno)));
00440                 goto fail;
00441         }
00442         if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
00443                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n"));
00444                 goto fail;
00445         }
00446         tdb_mmap(tdb);
00447 
00448         return 0;
00449 
00450 fail:
00451         tdb_close(tdb);
00452         return -1;
00453 }

int tdb_reopen_all ( int  parent_longlived  ) 

open.c456 行で定義されています。

参照先 tdb_context::flagstdb_context::nexttdbtdb_reopen()tdbs.

参照元 addrec_db()fork_child_dc_connect()fork_domain_child()open_sockets_smbd().

00457 {
00458         struct tdb_context *tdb;
00459 
00460         for (tdb=tdbs; tdb; tdb = tdb->next) {
00461                 /*
00462                  * If the parent is longlived (ie. a
00463                  * parent daemon architecture), we know
00464                  * it will keep it's active lock on a
00465                  * tdb opened with CLEAR_IF_FIRST. Thus
00466                  * for child processes we don't have to
00467                  * add an active lock. This is essential
00468                  * to improve performance on systems that
00469                  * keep POSIX locks as a non-scalable data
00470                  * structure in the kernel.
00471                  */
00472                 if (parent_longlived) {
00473                         /* Ensure no clear-if-first. */
00474                         tdb->flags &= ~TDB_CLEAR_IF_FIRST;
00475                 }
00476 
00477                 if (tdb_reopen(tdb) != 0)
00478                         return -1;
00479         }
00480 
00481         return 0;
00482 }

void tdb_set_logging_function ( struct tdb_context tdb,
const struct tdb_logging_context log_ctx 
)

open.c391 行で定義されています。

参照先 tdb_context::logtdb.

00393 {
00394         tdb->log = *log_ctx;
00395 }

enum TDB_ERROR tdb_error ( struct tdb_context tdb  ) 

error.c31 行で定義されています。

参照先 tdb_context::ecodetdb.

参照元 allocate_print_jobid()tdb_change_int32_atomic()tdb_change_uint32_atomic()yield_connection().

00032 {
00033         return tdb->ecode;
00034 }

const char* tdb_errorstr ( struct tdb_context tdb  ) 

error.c50 行で定義されています。

参照先 tdb_errname::ecodetdb_context::ecodeemaptdb_errname::estringtdb.

参照元 claim_connection()count_current_connections()count_fn()idmap_tdb_remove_mapping()idmap_tdb_set_mapping()info_tdb()initialize_winbindd_cache()net_enum_pipes()register_message_flags()tdb_ass_subscript()tdb_delete_samacct_only()tdb_update_ridrec_only()tdb_update_samacct_only()tdbsam_delete_sam_account()tdbsam_getsampwnam()tdbsam_getsampwrid()upgrade_to_version_3()yield_connection().

00051 {
00052         u32 i;
00053         for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++)
00054                 if (tdb->ecode == emap[i].ecode)
00055                         return emap[i].estring;
00056         return "Invalid error code";
00057 }

TDB_DATA tdb_fetch ( struct tdb_context tdb,
TDB_DATA  key 
)

tdb.c144 行で定義されています。

参照先 TDB_DATA::dptrtdb_context::hash_fntdbtdb_alloc_read()tdb_find_lock_hash()tdb_nulltdb_unlock().

参照元 _reg_perfcount_assemble_global()_reg_perfcount_get_64()_reg_perfcount_get_counter_data()_reg_perfcount_get_counter_info()_reg_perfcount_get_instance_info()_reg_perfcount_get_numinst()_reg_perfcount_multi_sz_from_tdb()add_aliasmem()add_fd_to_close_entry()addrec_db()brl_get_locks_internal()cache_retrieve_response()compare_db()decrement_windows_lock_ref_count()delete_printer_driver()dump_tdb()enum_group_mapping()find_name_on_wins_subnet()first_record()gencache_get()gencache_iterate()get_a_printer_2()get_a_printer_driver_3()get_eventlog_record()get_group_map_from_gid()get_group_map_from_ntname()get_group_map_from_sid()get_jobs_changed_data()get_ntforms()get_posix_pending_close_entries()get_privileges()get_queue_status()get_share_mode_lock()get_stored_queue_info()get_updating_pid()get_windows_lock_ref_count()group_map_remove()idmap_cache_map_id()idmap_cache_map_sid()idmap_tdb_id_to_sid()idmap_tdb_remove_mapping()idmap_tdb_set_mapping()idmap_tdb_sid_to_id()increment_windows_lock_ref_count()lang_msg()login_cache_read()make_way_for_eventlogs()message_send_pid_internal()messages_pending_for_pid()move_rec()netsamlogon_cache_get()next_record()one_alias_membership()pjob_store()pjobid_to_rap()print_job_find()print_queue_status()rap_jobid_delete()rap_to_pjobid()reduce_windows_lock_ref_count()reg_perfcount_get_base_index()register_message_flags()remove_from_jobs_changed()retrieve_all_messages()secrets_fetch()session_yield()set_driver_init_2()show_tdb()smb_change_share_mode_entry()smb_create_share_mode_entry_ex()smb_delete_share_mode_entry()smb_get_share_mode_entries()tdb_append()tdb_fetch_bystring()tdb_fetch_int32_byblob()tdb_fetch_uint32_byblob()tdb_hnd_subscript()tdbsam_convert()tdbsam_getsampwent()tdbsam_getsampwnam()tdbsam_getsampwrid()upgrade_to_version_3()wcache_cached_creds_exist()wcache_fetch_raw()wcache_remove_oldest_cached_creds().

00145 {
00146         tdb_off_t rec_ptr;
00147         struct list_struct rec;
00148         TDB_DATA ret;
00149         u32 hash;
00150 
00151         /* find which hash bucket it is in */
00152         hash = tdb->hash_fn(&key);
00153         if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec)))
00154                 return tdb_null;
00155 
00156         ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len,
00157                                   rec.data_len);
00158         ret.dsize = rec.data_len;
00159         tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
00160         return ret;
00161 }

int tdb_parse_record ( struct tdb_context tdb,
TDB_DATA  key,
int(*)(TDB_DATA key, TDB_DATA data, void *private_data)  parser,
void *  private_data 
)

tdb.c179 行で定義されています。

参照先 tdb_context::hash_fntdbTDB_ERR_NOEXISTtdb_find_lock_hash()tdb_parse_data()tdb_unlock().

参照元 get_delete_on_close_flag().

00183 {
00184         tdb_off_t rec_ptr;
00185         struct list_struct rec;
00186         int ret;
00187         u32 hash;
00188 
00189         /* find which hash bucket it is in */
00190         hash = tdb->hash_fn(&key);
00191 
00192         if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
00193                 return TDB_ERRCODE(TDB_ERR_NOEXIST, 0);
00194         }
00195 
00196         ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
00197                              rec.data_len, parser, private_data);
00198 
00199         tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
00200 
00201         return ret;
00202 }

int tdb_delete ( struct tdb_context tdb,
TDB_DATA  key 
)

tdb.c374 行で定義されています。

参照先 tdb_context::hash_fntdbtdb_delete_hash().

参照元 addrec_db()byte_range_lock_destructor()cache_cleanup_response()cache_store_response()convert_fn()count_fn()cull_traverse()del_a_printer()del_aliasmem()del_driver_init()delete_a_form()delete_close_entries()delete_pipe_opendb()delete_printer_driver()delete_tdb()delete_windows_lock_ref_count()do_delete_fn()gencache_del()gencache_get()group_map_remove()idmap_cache_del()idmap_cache_map_id()idmap_cache_map_sid()idmap_tdb_remove_mapping()idmap_tdb_set_mapping()login_cache_delentry()merge_test()message_notify()netsamlogon_cache_get()netsamlogon_clear_cached_user()normalize_printers_fn()pjob_delete()rap_jobid_delete()remove_name_from_wins_namelist()sec_desc_upg_fn()secrets_delete()session_claim()session_yield()set_updating_pid()share_mode_lock_destructor()smb_delete_share_mode_entry()tdb_ass_subscript()tdb_delete_bystring()tdb_delete_samacct_only()tdb_trans_delete()tdb_traverse_delete_fn()tdbsam_delete_sam_account()traverse_fn()traverse_fn_cleanup()upgrade_to_version_3()wcache_delete()wcache_remove_oldest_cached_creds()yield_connection().

00375 {
00376         u32 hash = tdb->hash_fn(&key);
00377         return tdb_delete_hash(tdb, key, hash);
00378 }

int tdb_store ( struct tdb_context tdb,
TDB_DATA  key,
TDB_DATA  dbuf,
int  flag 
)

tdb.c414 行で定義されています。

参照先 list_struct::data_lenTDB_DATA::dptrTDB_DATA::dsizetdb_context::ecodelist_struct::full_hashtdb_context::hash_fnlist_struct::key_lenlist_struct::magiclist_struct::nexttdb_context::read_onlytdbtdb_allocate()tdb_delete_hash()TDB_ERR_EXISTSTDB_ERR_NOEXISTTDB_ERR_OOMTDB_ERR_RDONLYtdb_exists_hash()tdb_find_dead()tdb_increment_seqnum()tdb_lock()tdb_ofs_read()tdb_ofs_write()tdb_purge_dead()tdb_rec_write()TDB_SUCCESStdb_unlock()tdb_update_hash()tdb_context::traverse_read.

参照元 add_a_printer_driver_3()add_aliasmem()add_fd_to_close_entry()add_mapping_entry()addrec_db()byte_range_lock_destructor()cache_store_response()centry_end()claim_connection()convert_fn()copy_fn()decrement_windows_lock_ref_count()del_aliasmem()gencache_set()idmap_cache_set()idmap_cache_set_negative_id()idmap_cache_set_negative_sid()idmap_tdb_set_mapping()increment_windows_lock_ref_count()insert_tdb()load_msg()login_cache_write()merge_test()message_send_pid_internal()move_rec()normalize_printers_fn()pjob_store()pjobid_to_rap()print_queue_update_internal()reduce_windows_lock_ref_count()regdb_store_keys_internal()register_message_flags()remove_from_jobs_changed()retrieve_all_messages()seen_insert()session_claim()set_privileges()set_updating_pid()share_mode_lock_destructor()smb_change_share_mode_entry()smb_create_share_mode_entry_ex()smb_delete_share_mode_entry()store_or_replace_wins_namerec()store_pipe_opendb()store_queue_struct()store_tdb()tdb_append()tdb_ass_subscript()tdb_store_bystring()tdb_store_int32_byblob()tdb_store_uint32_byblob()tdb_trans_store()tdb_update_ridrec_only()tdb_update_samacct_only()tdbsam_convert()traverse_fn()unexpected_packet()update_a_printer_2()update_driver_init_2()upgrade_to_version_3()write_eventlog_tdb()write_ntforms().

00415 {
00416         struct list_struct rec;
00417         u32 hash;
00418         tdb_off_t rec_ptr;
00419         char *p = NULL;
00420         int ret = -1;
00421 
00422         if (tdb->read_only || tdb->traverse_read) {
00423                 tdb->ecode = TDB_ERR_RDONLY;
00424                 return -1;
00425         }
00426 
00427         /* find which hash bucket it is in */
00428         hash = tdb->hash_fn(&key);
00429         if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
00430                 return -1;
00431 
00432         /* check for it existing, on insert. */
00433         if (flag == TDB_INSERT) {
00434                 if (tdb_exists_hash(tdb, key, hash)) {
00435                         tdb->ecode = TDB_ERR_EXISTS;
00436                         goto fail;
00437                 }
00438         } else {
00439                 /* first try in-place update, on modify or replace. */
00440                 if (tdb_update_hash(tdb, key, hash, dbuf) == 0) {
00441                         goto done;
00442                 }
00443                 if (tdb->ecode == TDB_ERR_NOEXIST &&
00444                     flag == TDB_MODIFY) {
00445                         /* if the record doesn't exist and we are in TDB_MODIFY mode then
00446                          we should fail the store */
00447                         goto fail;
00448                 }
00449         }
00450         /* reset the error code potentially set by the tdb_update() */
00451         tdb->ecode = TDB_SUCCESS;
00452 
00453         /* delete any existing record - if it doesn't exist we don't
00454            care.  Doing this first reduces fragmentation, and avoids
00455            coalescing with `allocated' block before it's updated. */
00456         if (flag != TDB_INSERT)
00457                 tdb_delete_hash(tdb, key, hash);
00458 
00459         /* Copy key+value *before* allocating free space in case malloc
00460            fails and we are left with a dead spot in the tdb. */
00461 
00462         if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) {
00463                 tdb->ecode = TDB_ERR_OOM;
00464                 goto fail;
00465         }
00466 
00467         memcpy(p, key.dptr, key.dsize);
00468         if (dbuf.dsize)
00469                 memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
00470 
00471         if (tdb->max_dead_records != 0) {
00472                 /*
00473                  * Allow for some dead records per hash chain, look if we can
00474                  * find one that can hold the new record. We need enough space
00475                  * for key, data and tailer. If we find one, we don't have to
00476                  * consult the central freelist.
00477                  */
00478                 rec_ptr = tdb_find_dead(
00479                         tdb, hash, &rec,
00480                         key.dsize + dbuf.dsize + sizeof(tdb_off_t));
00481 
00482                 if (rec_ptr != 0) {
00483                         rec.key_len = key.dsize;
00484                         rec.data_len = dbuf.dsize;
00485                         rec.full_hash = hash;
00486                         rec.magic = TDB_MAGIC;
00487                         if (tdb_rec_write(tdb, rec_ptr, &rec) == -1
00488                             || tdb->methods->tdb_write(
00489                                     tdb, rec_ptr + sizeof(rec),
00490                                     p, key.dsize + dbuf.dsize) == -1) {
00491                                 goto fail;
00492                         }
00493                         goto done;
00494                 }
00495         }
00496 
00497         /*
00498          * We have to allocate some space from the freelist, so this means we
00499          * have to lock it. Use the chance to purge all the DEAD records from
00500          * the hash chain under the freelist lock.
00501          */
00502 
00503         if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
00504                 goto fail;
00505         }
00506 
00507         if ((tdb->max_dead_records != 0)
00508             && (tdb_purge_dead(tdb, hash) == -1)) {
00509                 tdb_unlock(tdb, -1, F_WRLCK);
00510                 goto fail;
00511         }
00512 
00513         /* we have to allocate some space */
00514         rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec);
00515 
00516         tdb_unlock(tdb, -1, F_WRLCK);
00517 
00518         if (rec_ptr == 0) {
00519                 goto fail;
00520         }
00521 
00522         /* Read hash top into next ptr */
00523         if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1)
00524                 goto fail;
00525 
00526         rec.key_len = key.dsize;
00527         rec.data_len = dbuf.dsize;
00528         rec.full_hash = hash;
00529         rec.magic = TDB_MAGIC;
00530 
00531         /* write out and point the top of the hash chain at it */
00532         if (tdb_rec_write(tdb, rec_ptr, &rec) == -1
00533             || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1
00534             || tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) {
00535                 /* Need to tdb_unallocate() here */
00536                 goto fail;
00537         }
00538 
00539  done:
00540         ret = 0;
00541  fail:
00542         if (ret == 0) {
00543                 tdb_increment_seqnum(tdb);
00544         }
00545 
00546         SAFE_FREE(p); 
00547         tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
00548         return ret;
00549 }

int tdb_append ( struct tdb_context tdb,
TDB_DATA  key,
TDB_DATA  new_dbuf 
)

tdb.c553 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizetdb_context::ecodefailedtdb_context::hash_fntdbTDB_ERR_OOMtdb_fetch()tdb_lock()tdb_store()tdb_unlock().

参照元 add_to_jobs_changed()addrec_db()message_send_pid_internal().

00554 {
00555         u32 hash;
00556         TDB_DATA dbuf;
00557         int ret = -1;
00558 
00559         /* find which hash bucket it is in */
00560         hash = tdb->hash_fn(&key);
00561         if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
00562                 return -1;
00563 
00564         dbuf = tdb_fetch(tdb, key);
00565 
00566         if (dbuf.dptr == NULL) {
00567                 dbuf.dptr = (char *)malloc(new_dbuf.dsize);
00568         } else {
00569                 char *new_dptr = (char *)realloc(dbuf.dptr,
00570                                             dbuf.dsize + new_dbuf.dsize);
00571                 if (new_dptr == NULL) {
00572                         free(dbuf.dptr);
00573                 }
00574                 dbuf.dptr = new_dptr;
00575         }
00576 
00577         if (dbuf.dptr == NULL) {
00578                 tdb->ecode = TDB_ERR_OOM;
00579                 goto failed;
00580         }
00581 
00582         memcpy(dbuf.dptr + dbuf.dsize, new_dbuf.dptr, new_dbuf.dsize);
00583         dbuf.dsize += new_dbuf.dsize;
00584 
00585         ret = tdb_store(tdb, key, dbuf, 0);
00586         
00587 failed:
00588         tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
00589         SAFE_FREE(dbuf.dptr);
00590         return ret;
00591 }

int tdb_close ( struct tdb_context tdb  ) 

Close a database.

戻り値:
-1 for error; 0 for success.

open.c356 行で定義されています。

参照先 tdb_context::fdtdb_context::flagstdb_context::lockrecstdb_context::map_ptrtdb_context::nametdb_context::nexttdbtdb_munmap()tdb_transaction_cancel()tdbstdb_context::transaction.

参照元 _reg_perfcount_get_counter_data()_reg_perfcount_init_data_block_perf()backup_tdb()brl_shutdown()close_all_print_db()create_tdb()do_daemon_stack_trace()do_winbind_offline()do_winbind_online()elog_close_tdb()gencache_shutdown()idmap_cache_destructor()idmap_tdb_convert()idmap_tdb_open_db()idmap_tdb_tdb_close()initialize_winbindd_cache()lang_tdb_init()locking_end()login_cache_shutdown()main()move_rec()net_idmap_dump()net_status_sessions()net_status_shares()net_status_shares_parseable()netsamlogon_cache_shutdown()netsamlogon_clear_cached_user()nt_printing_init()open_schannel_session_store()open_tdb()posix_locking_end()py_tdb_close()receive_unexpected()reg_perfcount_get_base_index()reg_perfcount_get_counter_help()reg_perfcount_get_counter_names()reg_perfcount_get_perf_data_block()regdb_close()reset_stat_cache()secrets_restore_schannel_session_info()secrets_store_schannel_session_info()send_message()send_repl_message()send_sync_message()smb_share_mode_db_close()status_page()tdb_hnd_dealloc()tdb_reopen()tdb_validate_freelist()tdb_wrap_destructor()tdbsam_close()tdbsam_new_rid()tdbsam_open()verify_tdb()wcache_flush_cache().

00357 {
00358         struct tdb_context **i;
00359         int ret = 0;
00360 
00361         if (tdb->transaction) {
00362                 tdb_transaction_cancel(tdb);
00363         }
00364 
00365         if (tdb->map_ptr) {
00366                 if (tdb->flags & TDB_INTERNAL)
00367                         SAFE_FREE(tdb->map_ptr);
00368                 else
00369                         tdb_munmap(tdb);
00370         }
00371         SAFE_FREE(tdb->name);
00372         if (tdb->fd != -1)
00373                 ret = close(tdb->fd);
00374         SAFE_FREE(tdb->lockrecs);
00375 
00376         /* Remove from contexts list */
00377         for (i = &tdbs; *i; i = &(*i)->next) {
00378                 if (*i == tdb) {
00379                         *i = tdb->next;
00380                         break;
00381                 }
00382         }
00383 
00384         memset(tdb, 0, sizeof(*tdb));
00385         SAFE_FREE(tdb);
00386 
00387         return ret;
00388 }

TDB_DATA tdb_firstkey ( struct tdb_context tdb  ) 

traverse.c255 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizetdb_traverse_lock::hashlist_struct::key_lentdb_traverse_lock::lock_rwtdb_traverse_lock::offtdbtdb_alloc_read()TDB_DEBUG_FATALtdb_next_lock()tdb_nulltdb_unlock()tdb_unlock_record()tdb_context::travlocks.

参照元 compare_db()enum_group_mapping()first_record()get_group_map_from_gid()get_group_map_from_ntname()get_ntdrivers()get_ntforms()py_tdb_hnd_first_key()tdb_search_keys()tdbsam_convert()upgrade_to_version_3().

00256 {
00257         TDB_DATA key;
00258         struct list_struct rec;
00259 
00260         /* release any old lock */
00261         if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0)
00262                 return tdb_null;
00263         tdb->travlocks.off = tdb->travlocks.hash = 0;
00264         tdb->travlocks.lock_rw = F_RDLCK;
00265 
00266         /* Grab first record: locks chain and returned record. */
00267         if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0)
00268                 return tdb_null;
00269         /* now read the key */
00270         key.dsize = rec.key_len;
00271         key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize);
00272 
00273         /* Unlock the hash chain of the record we just read. */
00274         if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0)
00275                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n"));
00276         return key;
00277 }

TDB_DATA tdb_nextkey ( struct tdb_context tdb,
TDB_DATA  key 
)

traverse.c280 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeerrnolist_struct::full_hashtdb_traverse_lock::hashtdb_context::hash_fnlist_struct::key_lentdb_traverse_lock::lock_rwtdb_traverse_lock::offstrerror()tdbtdb_alloc_read()TDB_DEBUG_FATALtdb_find_lock_hash()tdb_lock()tdb_lock_record()tdb_next_lock()tdb_nulltdb_rec_read()tdb_unlock()tdb_unlock_record()tdb_context::travlocks.

参照元 compare_db()enum_group_mapping()get_group_map_from_gid()get_group_map_from_ntname()get_ntdrivers()get_ntforms()next_record()py_tdb_hnd_next_key()tdb_search_keys()tdbsam_convert()upgrade_to_version_3().

00281 {
00282         u32 oldhash;
00283         TDB_DATA key = tdb_null;
00284         struct list_struct rec;
00285         char *k = NULL;
00286 
00287         /* Is locked key the old key?  If so, traverse will be reliable. */
00288         if (tdb->travlocks.off) {
00289                 if (tdb_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw))
00290                         return tdb_null;
00291                 if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1
00292                     || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),
00293                                             rec.key_len))
00294                     || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) {
00295                         /* No, it wasn't: unlock it and start from scratch */
00296                         if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) {
00297                                 SAFE_FREE(k);
00298                                 return tdb_null;
00299                         }
00300                         if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) {
00301                                 SAFE_FREE(k);
00302                                 return tdb_null;
00303                         }
00304                         tdb->travlocks.off = 0;
00305                 }
00306 
00307                 SAFE_FREE(k);
00308         }
00309 
00310         if (!tdb->travlocks.off) {
00311                 /* No previous element: do normal find, and lock record */
00312                 tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec);
00313                 if (!tdb->travlocks.off)
00314                         return tdb_null;
00315                 tdb->travlocks.hash = BUCKET(rec.full_hash);
00316                 if (tdb_lock_record(tdb, tdb->travlocks.off) != 0) {
00317                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno)));
00318                         return tdb_null;
00319                 }
00320         }
00321         oldhash = tdb->travlocks.hash;
00322 
00323         /* Grab next record: locks chain and returned record,
00324            unlocks old record */
00325         if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) {
00326                 key.dsize = rec.key_len;
00327                 key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec),
00328                                           key.dsize);
00329                 /* Unlock the chain of this new record */
00330                 if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0)
00331                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
00332         }
00333         /* Unlock the chain of old record */
00334         if (tdb_unlock(tdb, BUCKET(oldhash), tdb->travlocks.lock_rw) != 0)
00335                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
00336         return key;
00337 }

int tdb_traverse ( struct tdb_context tdb,
tdb_traverse_func  fn,
void *   
)

traverse.c230 行で定義されています。

参照先 tdb_context::ecodetdb_context::methodstdb_context::read_onlytdbtdb_methods::tdb_brlockTDB_DEBUG_ERRORTDB_ERR_LOCKtdb_traverse_internal()tdb_traverse_read()tdb_context::traverse_read.

参照元 addrec_db()backup_tdb()brl_forall()clear_unexpected()count_current_connections()do_command()do_daemon_stack_trace()dump_tdb()dump_wins_subnet_namelist()elog_tdb_size()enum_aliasmem()fetch_all_active_wins_1b_names()idmap_tdb_convert()idmap_tdb_dump_data()info_tdb()init_group_mapping()initiate_wins_processing()load_msg()main()message_send_all()net_enum_pipes()net_idmap_dump()net_status_sessions()net_status_shares()net_status_shares_parseable()print_backend_init()print_queue_update_internal()privilege_enumerate_accounts()py_tdb_hnd_keys()py_tdb_hnd_traverse()receive_unexpected()session_traverse()share_info_db_init()share_mode_forall()status_page()sysjob_to_jobid()tdb_hnd_length()tdbsam_setsampwent()update_c_setprinter()upgrade_to_version_4()upgrade_to_version_5()verify_tdb()wcache_count_cached_creds()wcache_flush_cache()wcache_invalidate_cache()wcache_remove_oldest_cached_creds()wins_write_database().

00232 {
00233         struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
00234         int ret;
00235 
00236         if (tdb->read_only || tdb->traverse_read) {
00237                 return tdb_traverse_read(tdb, fn, private_data);
00238         }
00239         
00240         if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
00241                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse: failed to get transaction lock\n"));
00242                 tdb->ecode = TDB_ERR_LOCK;
00243                 return -1;
00244         }
00245 
00246         ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
00247 
00248         tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
00249 
00250         return ret;
00251 }

int tdb_traverse_read ( struct tdb_context tdb,
tdb_traverse_func  fn,
void *   
)

traverse.c203 行で定義されています。

参照先 tdb_context::ecodetdb_context::methodstdbtdb_methods::tdb_brlockTDB_DEBUG_ERRORTDB_ERR_LOCKtdb_traverse_internal()tdb_context::traverse_read.

参照元 addrec_db()main()tdb_traverse().

00205 {
00206         struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
00207         int ret;
00208         
00209         /* we need to get a read lock on the transaction lock here to
00210            cope with the lock ordering semantics of solaris10 */
00211         if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1) {
00212                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse_read: failed to get transaction lock\n"));
00213                 tdb->ecode = TDB_ERR_LOCK;
00214                 return -1;
00215         }
00216 
00217         tdb->traverse_read++;
00218         ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
00219         tdb->traverse_read--;
00220 
00221         tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
00222 
00223         return ret;
00224 }

int tdb_exists ( struct tdb_context tdb,
TDB_DATA  key 
)

tdb.c220 行で定義されています。

参照先 tdb_context::hash_fntdbtdb_exists_hash().

参照元 print_job_exists()py_tdb_hnd_has_key().

00221 {
00222         u32 hash = tdb->hash_fn(&key);
00223         return tdb_exists_hash(tdb, key, hash);
00224 }

int tdb_lockall ( struct tdb_context tdb  ) 

lock.c336 行で定義されています。

参照先 _tdb_lockall()tdb.

参照元 backup_tdb()load_msg()py_tdb_hnd_lock_all().

00337 {
00338         return _tdb_lockall(tdb, F_WRLCK);
00339 }

int tdb_unlockall ( struct tdb_context tdb  ) 

lock.c342 行で定義されています。

参照先 _tdb_unlockall()tdb.

参照元 load_msg()py_tdb_hnd_unlock_all().

00343 {
00344         return _tdb_unlockall(tdb, F_WRLCK);
00345 }

int tdb_lockall_read ( struct tdb_context tdb  ) 

lock.c348 行で定義されています。

参照先 _tdb_lockall()tdb.

00349 {
00350         return _tdb_lockall(tdb, F_RDLCK);
00351 }

int tdb_unlockall_read ( struct tdb_context tdb  ) 

lock.c354 行で定義されています。

参照先 _tdb_unlockall()tdb.

00355 {
00356         return _tdb_unlockall(tdb, F_RDLCK);
00357 }

const char* tdb_name ( struct tdb_context tdb  ) 

tdb.c598 行で定義されています。

参照先 tdb_context::nametdb.

参照元 _reg_perfcount_multi_sz_from_tdb()copy_fn()tdb_chainlock_with_timeout_internal()tdb_log()tdb_wrap_log().

00599 {
00600         return tdb->name;
00601 }

int tdb_fd ( struct tdb_context tdb  ) 

tdb.c608 行で定義されています。

参照先 tdb_context::fdtdb.

参照元 backup_tdb()winbindd_check_cache_size().

00609 {
00610         return tdb->fd;
00611 }

tdb_log_func tdb_log_fn ( struct tdb_context tdb  ) 

tdb.c617 行で定義されています。

参照先 tdb_context::logtdb_logging_context::log_fntdb.

00618 {
00619         return tdb->log.log_fn;
00620 }

void* tdb_get_logging_private ( struct tdb_context tdb  ) 

open.c397 行で定義されています。

参照先 tdb_context::logtdb_logging_context::log_privatetdb.

00398 {
00399         return tdb->log.log_private;
00400 }

int tdb_transaction_start ( struct tdb_context tdb  ) 

transaction.c384 行で定義されています。

参照先 tdb_lock_type::counttdb_context::ecodetdb_context::flagstdb_context::global_locktdb_transaction::hash_headstdb_header::hash_sizetdb_context::headertdb_transaction::io_methodstdb_context::map_sizetdb_context::methodstdb_transaction::nestingtdb_traverse_lock::nexttdb_context::num_lockstdb_transaction::old_map_sizetdb_context::read_onlytdbtdb_brlock()TDB_DEBUG_ERRORTDB_DEBUG_FATALTDB_DEBUG_TRACETDB_ERR_EINVALTDB_ERR_IOTDB_ERR_LOCKTDB_ERR_OOMtdb_methods::tdb_oobtdb_methods::tdb_readtdb_context::transactiontransaction_methodstransaction_write()tdb_context::traverse_readtdb_context::travlocks.

参照元 addrec_db()init_registry_data()tdb_trans_delete()tdb_trans_store().

00385 {
00386         /* some sanity checks */
00387         if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) {
00388                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction on a read-only or internal db\n"));
00389                 tdb->ecode = TDB_ERR_EINVAL;
00390                 return -1;
00391         }
00392 
00393         /* cope with nested tdb_transaction_start() calls */
00394         if (tdb->transaction != NULL) {
00395                 tdb->transaction->nesting++;
00396                 TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", 
00397                          tdb->transaction->nesting));
00398                 return 0;
00399         }
00400 
00401         if (tdb->num_locks != 0 || tdb->global_lock.count) {
00402                 /* the caller must not have any locks when starting a
00403                    transaction as otherwise we'll be screwed by lack
00404                    of nested locks in posix */
00405                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction with locks held\n"));
00406                 tdb->ecode = TDB_ERR_LOCK;
00407                 return -1;
00408         }
00409 
00410         if (tdb->travlocks.next != NULL) {
00411                 /* you cannot use transactions inside a traverse (although you can use
00412                    traverse inside a transaction) as otherwise you can end up with
00413                    deadlock */
00414                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction within a traverse\n"));
00415                 tdb->ecode = TDB_ERR_LOCK;
00416                 return -1;
00417         }
00418 
00419         tdb->transaction = (struct tdb_transaction *)
00420                 calloc(sizeof(struct tdb_transaction), 1);
00421         if (tdb->transaction == NULL) {
00422                 tdb->ecode = TDB_ERR_OOM;
00423                 return -1;
00424         }
00425 
00426         /* get the transaction write lock. This is a blocking lock. As
00427            discussed with Volker, there are a number of ways we could
00428            make this async, which we will probably do in the future */
00429         if (tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
00430                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get transaction lock\n"));
00431                 tdb->ecode = TDB_ERR_LOCK;
00432                 SAFE_FREE(tdb->transaction);
00433                 return -1;
00434         }
00435         
00436         /* get a read lock from the freelist to the end of file. This
00437            is upgraded to a write lock during the commit */
00438         if (tdb_brlock(tdb, FREELIST_TOP, F_RDLCK, F_SETLKW, 0, 0) == -1) {
00439                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n"));
00440                 tdb->ecode = TDB_ERR_LOCK;
00441                 goto fail;
00442         }
00443 
00444         /* setup a copy of the hash table heads so the hash scan in
00445            traverse can be fast */
00446         tdb->transaction->hash_heads = (u32 *)
00447                 calloc(tdb->header.hash_size+1, sizeof(u32));
00448         if (tdb->transaction->hash_heads == NULL) {
00449                 tdb->ecode = TDB_ERR_OOM;
00450                 goto fail;
00451         }
00452         if (tdb->methods->tdb_read(tdb, FREELIST_TOP, tdb->transaction->hash_heads,
00453                                    TDB_HASHTABLE_SIZE(tdb), 0) != 0) {
00454                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to read hash heads\n"));
00455                 tdb->ecode = TDB_ERR_IO;
00456                 goto fail;
00457         }
00458 
00459         /* make sure we know about any file expansions already done by
00460            anyone else */
00461         tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1);
00462         tdb->transaction->old_map_size = tdb->map_size;
00463 
00464         /* finally hook the io methods, replacing them with
00465            transaction specific methods */
00466         tdb->transaction->io_methods = tdb->methods;
00467         tdb->methods = &transaction_methods;
00468 
00469         /* by calling this transaction write here, we ensure that we don't grow the
00470            transaction linked list due to hash table updates */
00471         if (transaction_write(tdb, FREELIST_TOP, tdb->transaction->hash_heads, 
00472                               TDB_HASHTABLE_SIZE(tdb)) != 0) {
00473                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to prime hash table\n"));
00474                 tdb->ecode = TDB_ERR_IO;
00475                 goto fail;
00476         }
00477 
00478         return 0;
00479         
00480 fail:
00481         tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
00482         tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
00483         SAFE_FREE(tdb->transaction->hash_heads);
00484         SAFE_FREE(tdb->transaction);
00485         return -1;
00486 }

int tdb_transaction_commit ( struct tdb_context tdb  ) 

transaction.c783 行で定義されています。

参照先 tdb_lock_type::counttdb_transaction_el::datatdb_context::ecodetdb_transaction::elementstdb_context::flagstdb_context::global_locktdb_transaction::io_methodstdb_transaction_el::lengthtdb_context::map_sizetdb_context::methodsmethodstdb_context::nametdb_transaction::nestingtdb_transaction_el::nexttdb_context::num_lockstdb_transaction_el::offsettdb_transaction::old_map_sizetdbtdb_brlock()tdb_brlock_upgrade()TDB_DEBUG_ERRORTDB_DEBUG_FATALTDB_ERR_IOTDB_ERR_LOCKtdb_transaction_cancel()tdb_transaction_recover()tdb_context::transactiontdb_transaction::transaction_errortransaction_setup_recovery()transaction_sync().

参照元 addrec_db()init_registry_data()tdb_trans_delete()tdb_trans_store().

00784 {       
00785         const struct tdb_methods *methods;
00786         tdb_off_t magic_offset = 0;
00787         u32 zero = 0;
00788 
00789         if (tdb->transaction == NULL) {
00790                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n"));
00791                 return -1;
00792         }
00793 
00794         if (tdb->transaction->transaction_error) {
00795                 tdb->ecode = TDB_ERR_IO;
00796                 tdb_transaction_cancel(tdb);
00797                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: transaction error pending\n"));
00798                 return -1;
00799         }
00800 
00801         if (tdb->transaction->nesting != 0) {
00802                 tdb->transaction->nesting--;
00803                 return 0;
00804         }               
00805 
00806         /* check for a null transaction */
00807         if (tdb->transaction->elements == NULL) {
00808                 tdb_transaction_cancel(tdb);
00809                 return 0;
00810         }
00811 
00812         methods = tdb->transaction->io_methods;
00813         
00814         /* if there are any locks pending then the caller has not
00815            nested their locks properly, so fail the transaction */
00816         if (tdb->num_locks || tdb->global_lock.count) {
00817                 tdb->ecode = TDB_ERR_LOCK;
00818                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: locks pending on commit\n"));
00819                 tdb_transaction_cancel(tdb);
00820                 return -1;
00821         }
00822 
00823         /* upgrade the main transaction lock region to a write lock */
00824         if (tdb_brlock_upgrade(tdb, FREELIST_TOP, 0) == -1) {
00825                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to upgrade hash locks\n"));
00826                 tdb->ecode = TDB_ERR_LOCK;
00827                 tdb_transaction_cancel(tdb);
00828                 return -1;
00829         }
00830 
00831         /* get the global lock - this prevents new users attaching to the database
00832            during the commit */
00833         if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
00834                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: failed to get global lock\n"));
00835                 tdb->ecode = TDB_ERR_LOCK;
00836                 tdb_transaction_cancel(tdb);
00837                 return -1;
00838         }
00839 
00840         if (!(tdb->flags & TDB_NOSYNC)) {
00841                 /* write the recovery data to the end of the file */
00842                 if (transaction_setup_recovery(tdb, &magic_offset) == -1) {
00843                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to setup recovery data\n"));
00844                         tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1);
00845                         tdb_transaction_cancel(tdb);
00846                         return -1;
00847                 }
00848         }
00849 
00850         /* expand the file to the new size if needed */
00851         if (tdb->map_size != tdb->transaction->old_map_size) {
00852                 if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, 
00853                                              tdb->map_size - 
00854                                              tdb->transaction->old_map_size) == -1) {
00855                         tdb->ecode = TDB_ERR_IO;
00856                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: expansion failed\n"));
00857                         tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1);
00858                         tdb_transaction_cancel(tdb);
00859                         return -1;
00860                 }
00861                 tdb->map_size = tdb->transaction->old_map_size;
00862                 methods->tdb_oob(tdb, tdb->map_size + 1, 1);
00863         }
00864 
00865         /* perform all the writes */
00866         while (tdb->transaction->elements) {
00867                 struct tdb_transaction_el *el = tdb->transaction->elements;
00868 
00869                 if (methods->tdb_write(tdb, el->offset, el->data, el->length) == -1) {
00870                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n"));
00871                         
00872                         /* we've overwritten part of the data and
00873                            possibly expanded the file, so we need to
00874                            run the crash recovery code */
00875                         tdb->methods = methods;
00876                         tdb_transaction_recover(tdb); 
00877 
00878                         tdb_transaction_cancel(tdb);
00879                         tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1);
00880 
00881                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n"));
00882                         return -1;
00883                 }
00884                 tdb->transaction->elements = el->next;
00885                 free(el->data); 
00886                 free(el);
00887         } 
00888 
00889         if (!(tdb->flags & TDB_NOSYNC)) {
00890                 /* ensure the new data is on disk */
00891                 if (transaction_sync(tdb, 0, tdb->map_size) == -1) {
00892                         return -1;
00893                 }
00894 
00895                 /* remove the recovery marker */
00896                 if (methods->tdb_write(tdb, magic_offset, &zero, 4) == -1) {
00897                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to remove recovery magic\n"));
00898                         return -1;
00899                 }
00900 
00901                 /* ensure the recovery marker has been removed on disk */
00902                 if (transaction_sync(tdb, magic_offset, 4) == -1) {
00903                         return -1;
00904                 }
00905         }
00906 
00907         tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1);
00908 
00909         /*
00910           TODO: maybe write to some dummy hdr field, or write to magic
00911           offset without mmap, before the last sync, instead of the
00912           utime() call
00913         */
00914 
00915         /* on some systems (like Linux 2.6.x) changes via mmap/msync
00916            don't change the mtime of the file, this means the file may
00917            not be backed up (as tdb rounding to block sizes means that
00918            file size changes are quite rare too). The following forces
00919            mtime changes when a transaction completes */
00920 #ifdef HAVE_UTIME
00921         utime(tdb->name, NULL);
00922 #endif
00923 
00924         /* use a transaction cancel to free memory and remove the
00925            transaction locks */
00926         tdb_transaction_cancel(tdb);
00927         return 0;
00928 }

int tdb_transaction_cancel ( struct tdb_context tdb  ) 

transaction.c492 行で定義されています。

参照先 tdb_lock_type::counttdb_transaction_el::datatdb_transaction::elementstdb_context::global_locktdb_transaction::hash_headstdb_header::hash_sizetdb_context::headertdb_transaction::io_methodstdb_lock_type::listtdb_context::lockrecstdb_context::map_sizetdb_context::methodstdb_transaction::nestingtdb_transaction_el::nexttdb_context::num_lockrecstdb_context::num_lockstdb_transaction::old_map_sizetdbtdb_brlock()TDB_DEBUG_ERRORtdb_context::transactiontdb_transaction::transaction_error.

参照元 addrec_db()init_registry_data()tdb_close()tdb_trans_delete()tdb_trans_store()tdb_transaction_commit().

00493 {       
00494         if (tdb->transaction == NULL) {
00495                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n"));
00496                 return -1;
00497         }
00498 
00499         if (tdb->transaction->nesting != 0) {
00500                 tdb->transaction->transaction_error = 1;
00501                 tdb->transaction->nesting--;
00502                 return 0;
00503         }               
00504 
00505         tdb->map_size = tdb->transaction->old_map_size;
00506 
00507         /* free all the transaction elements */
00508         while (tdb->transaction->elements) {
00509                 struct tdb_transaction_el *el = tdb->transaction->elements;
00510                 tdb->transaction->elements = el->next;
00511                 free(el->data);
00512                 free(el);
00513         }
00514 
00515         /* remove any global lock created during the transaction */
00516         if (tdb->global_lock.count != 0) {
00517                 tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 4*tdb->header.hash_size);
00518                 tdb->global_lock.count = 0;
00519         }
00520 
00521         /* remove any locks created during the transaction */
00522         if (tdb->num_locks != 0) {
00523                 int i;
00524                 for (i=0;i<tdb->num_lockrecs;i++) {
00525                         tdb_brlock(tdb,FREELIST_TOP+4*tdb->lockrecs[i].list,
00526                                    F_UNLCK,F_SETLKW, 0, 1);
00527                 }
00528                 tdb->num_locks = 0;
00529                 tdb->num_lockrecs = 0;
00530                 SAFE_FREE(tdb->lockrecs);
00531         }
00532 
00533         /* restore the normal io methods */
00534         tdb->methods = tdb->transaction->io_methods;
00535 
00536         tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
00537         tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
00538         SAFE_FREE(tdb->transaction->hash_heads);
00539         SAFE_FREE(tdb->transaction);
00540         
00541         return 0;
00542 }

int tdb_transaction_recover ( struct tdb_context tdb  ) 

transaction.c936 行で定義されています。

参照先 tdb_transaction_el::datatdb_context::ecodetdb_context::fdlenlist_struct::magictdb_context::map_sizetdb_context::methodstdb_context::read_onlytdbtdb_convert()TDB_DEBUG_FATALTDB_DEBUG_TRACETDB_ERR_CORRUPTTDB_ERR_IOTDB_ERR_OOMtdb_mmap()tdb_munmap()tdb_ofs_read()tdb_ofs_write()tdb_methods::tdb_readtdb_methods::tdb_writetransaction_sync().

参照元 tdb_open_ex()tdb_transaction_commit().

00937 {
00938         tdb_off_t recovery_head, recovery_eof;
00939         unsigned char *data, *p;
00940         u32 zero = 0;
00941         struct list_struct rec;
00942 
00943         /* find the recovery area */
00944         if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) {
00945                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery head\n"));
00946                 tdb->ecode = TDB_ERR_IO;
00947                 return -1;
00948         }
00949 
00950         if (recovery_head == 0) {
00951                 /* we have never allocated a recovery record */
00952                 return 0;
00953         }
00954 
00955         /* read the recovery record */
00956         if (tdb->methods->tdb_read(tdb, recovery_head, &rec, 
00957                                    sizeof(rec), DOCONV()) == -1) {
00958                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n"));           
00959                 tdb->ecode = TDB_ERR_IO;
00960                 return -1;
00961         }
00962 
00963         if (rec.magic != TDB_RECOVERY_MAGIC) {
00964                 /* there is no valid recovery data */
00965                 return 0;
00966         }
00967 
00968         if (tdb->read_only) {
00969                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: attempt to recover read only database\n"));
00970                 tdb->ecode = TDB_ERR_CORRUPT;
00971                 return -1;
00972         }
00973 
00974         recovery_eof = rec.key_len;
00975 
00976         data = (unsigned char *)malloc(rec.data_len);
00977         if (data == NULL) {
00978                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n"));         
00979                 tdb->ecode = TDB_ERR_OOM;
00980                 return -1;
00981         }
00982 
00983         /* read the full recovery data */
00984         if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data,
00985                                    rec.data_len, 0) == -1) {
00986                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n"));             
00987                 tdb->ecode = TDB_ERR_IO;
00988                 return -1;
00989         }
00990 
00991         /* recover the file data */
00992         p = data;
00993         while (p+8 < data + rec.data_len) {
00994                 u32 ofs, len;
00995                 if (DOCONV()) {
00996                         tdb_convert(p, 8);
00997                 }
00998                 memcpy(&ofs, p, 4);
00999                 memcpy(&len, p+4, 4);
01000 
01001                 if (tdb->methods->tdb_write(tdb, ofs, p+8, len) == -1) {
01002                         free(data);
01003                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to recover %d bytes at offset %d\n", len, ofs));
01004                         tdb->ecode = TDB_ERR_IO;
01005                         return -1;
01006                 }
01007                 p += 8 + len;
01008         }
01009 
01010         free(data);
01011 
01012         if (transaction_sync(tdb, 0, tdb->map_size) == -1) {
01013                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync recovery\n"));
01014                 tdb->ecode = TDB_ERR_IO;
01015                 return -1;
01016         }
01017 
01018         /* if the recovery area is after the recovered eof then remove it */
01019         if (recovery_eof <= recovery_head) {
01020                 if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) {
01021                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n"));
01022                         tdb->ecode = TDB_ERR_IO;
01023                         return -1;                      
01024                 }
01025         }
01026 
01027         /* remove the recovery magic */
01028         if (tdb_ofs_write(tdb, recovery_head + offsetof(struct list_struct, magic), 
01029                           &zero) == -1) {
01030                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n"));
01031                 tdb->ecode = TDB_ERR_IO;
01032                 return -1;                      
01033         }
01034         
01035         /* reduce the file size to the old size */
01036         tdb_munmap(tdb);
01037         if (ftruncate(tdb->fd, recovery_eof) != 0) {
01038                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to reduce to recovery size\n"));
01039                 tdb->ecode = TDB_ERR_IO;
01040                 return -1;                      
01041         }
01042         tdb->map_size = recovery_eof;
01043         tdb_mmap(tdb);
01044 
01045         if (transaction_sync(tdb, 0, recovery_eof) == -1) {
01046                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync2 recovery\n"));
01047                 tdb->ecode = TDB_ERR_IO;
01048                 return -1;
01049         }
01050 
01051         TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %d byte database\n", 
01052                  recovery_eof));
01053 
01054         /* all done */
01055         return 0;
01056 }

int tdb_get_seqnum ( struct tdb_context tdb  ) 

tdb.c633 行で定義されています。

参照先 tdbtdb_ofs_read().

参照元 notify_init()notify_load().

00634 {
00635         tdb_off_t seqnum=0;
00636 
00637         tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
00638         return seqnum;
00639 }

int tdb_hash_size ( struct tdb_context tdb  ) 

tdb.c641 行で定義されています。

参照先 tdb_header::hash_sizetdb_context::headertdb.

参照元 backup_tdb().

00642 {
00643         return tdb->header.hash_size;
00644 }

size_t tdb_map_size ( struct tdb_context tdb  ) 

tdb.c646 行で定義されています。

参照先 tdb_context::map_sizetdb.

参照元 stat_cache_add().

00647 {
00648         return tdb->map_size;
00649 }

int tdb_get_flags ( struct tdb_context tdb  ) 

tdb.c651 行で定義されています。

参照先 tdb_context::flagstdb.

参照元 idmap_tdb_convert().

00652 {
00653         return tdb->flags;
00654 }

int tdb_chainlock ( struct tdb_context tdb,
TDB_DATA  key 
)

lock.c361 行で定義されています。

参照先 tdb_context::hash_fntdbtdb_lock().

参照元 addrec_db()brl_get_locks_internal()get_share_mode_lock()idmap_tdb_remove_mapping()idmap_tdb_set_mapping()message_send_pid_internal()py_tdb_hnd_chainlock()retrieve_all_messages()smb_lock_share_mode_entry()tdb_chainlock_with_timeout_internal()tdb_lock_bystring().

00362 {
00363         return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
00364 }

int tdb_chainunlock ( struct tdb_context tdb,
TDB_DATA  key 
)

lock.c366 行で定義されています。

参照先 tdb_context::hash_fntdbtdb_unlock().

参照元 addrec_db()byte_range_lock_destructor()idmap_tdb_remove_mapping()idmap_tdb_set_mapping()message_send_pid_internal()py_tdb_hnd_chainunlock()remove_from_jobs_changed()retrieve_all_messages()share_mode_lock_destructor()smb_unlock_share_mode_entry()tdb_unlock_bystring().

00367 {
00368         return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
00369 }

int tdb_chainlock_read ( struct tdb_context tdb,
TDB_DATA  key 
)

lock.c371 行で定義されています。

参照先 tdb_context::hash_fntdbtdb_lock().

参照元 tdb_chainlock_with_timeout_internal().

00372 {
00373         return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
00374 }

int tdb_chainunlock_read ( struct tdb_context tdb,
TDB_DATA  key 
)

lock.c376 行で定義されています。

参照先 tdb_context::hash_fntdbtdb_unlock().

参照元 tdb_read_unlock_bystring().

00377 {
00378         return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
00379 }

void tdb_setalarm_sigptr ( struct tdb_context tdb,
volatile sig_atomic_t sigptr 
)

lock.c31 行で定義されています。

参照先 tdb_context::interrupt_sig_ptrtdb.

参照元 tdb_chainlock_with_timeout_internal().

00032 {
00033         tdb->interrupt_sig_ptr = ptr;
00034 }

void tdb_dump_all ( struct tdb_context tdb  ) 

dump.c84 行で定義されています。

参照先 tdb_header::hash_sizetdb_context::headerprintf()tdbtdb_dump_chain().

参照元 do_command().

00085 {
00086         int i;
00087         for (i=0;i<tdb->header.hash_size;i++) {
00088                 tdb_dump_chain(tdb, i);
00089         }
00090         printf("freelist:\n");
00091         tdb_dump_chain(tdb, -1);
00092 }

int tdb_printfreelist ( struct tdb_context tdb  ) 

dump.c94 行で定義されています。

参照先 tdb_context::methodsprintf()tdbtdb_lock()tdb_ofs_read()tdb_methods::tdb_readtdb_unlock().

参照元 do_command().

00095 {
00096         int ret;
00097         long total_free = 0;
00098         tdb_off_t offset, rec_ptr;
00099         struct list_struct rec;
00100 
00101         if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0)
00102                 return ret;
00103 
00104         offset = FREELIST_TOP;
00105 
00106         /* read in the freelist top */
00107         if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) {
00108                 tdb_unlock(tdb, -1, F_WRLCK);
00109                 return 0;
00110         }
00111 
00112         printf("freelist top=[0x%08x]\n", rec_ptr );
00113         while (rec_ptr) {
00114                 if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, 
00115                                            sizeof(rec), DOCONV()) == -1) {
00116                         tdb_unlock(tdb, -1, F_WRLCK);
00117                         return -1;
00118                 }
00119 
00120                 if (rec.magic != TDB_FREE_MAGIC) {
00121                         printf("bad magic 0x%08x in free list\n", rec.magic);
00122                         tdb_unlock(tdb, -1, F_WRLCK);
00123                         return -1;
00124                 }
00125 
00126                 printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)] (end = 0x%08x)\n", 
00127                        rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len);
00128                 total_free += rec.rec_len;
00129 
00130                 /* move to the next record */
00131                 rec_ptr = rec.next;
00132         }
00133         printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, 
00134                (int)total_free);
00135 
00136         return tdb_unlock(tdb, -1, F_WRLCK);
00137 }

int tdb_validate_freelist ( struct tdb_context tdb,
int *  pnum_entries 
)

freelistcheck.c47 行で定義されています。

参照先 tdb_header::hash_sizetdb_context::headerlast_ptrlist_struct::nextrec_free_read()seen_insert()tdbtdb_close()TDB_ERR_CORRUPTtdb_lock()tdb_ofs_read()tdb_open()tdb_unlock().

参照元 main().

00048 {
00049         struct tdb_context *mem_tdb = NULL;
00050         struct list_struct rec;
00051         tdb_off_t rec_ptr, last_ptr;
00052         int ret = -1;
00053 
00054         *pnum_entries = 0;
00055 
00056         mem_tdb = tdb_open("flval", tdb->header.hash_size,
00057                                 TDB_INTERNAL, O_RDWR, 0600);
00058         if (!mem_tdb) {
00059                 return -1;
00060         }
00061 
00062         if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
00063                 tdb_close(mem_tdb);
00064                 return 0;
00065         }
00066 
00067         last_ptr = FREELIST_TOP;
00068 
00069         /* Store the FREELIST_TOP record. */
00070         if (seen_insert(mem_tdb, last_ptr) == -1) {
00071                 ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
00072                 goto fail;
00073         }
00074 
00075         /* read in the freelist top */
00076         if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) {
00077                 goto fail;
00078         }
00079 
00080         while (rec_ptr) {
00081 
00082                 /* If we can't store this record (we've seen it
00083                    before) then the free list has a loop and must
00084                    be corrupt. */
00085 
00086                 if (seen_insert(mem_tdb, rec_ptr)) {
00087                         ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
00088                         goto fail;
00089                 }
00090 
00091                 if (rec_free_read(tdb, rec_ptr, &rec) == -1) {
00092                         goto fail;
00093                 }
00094 
00095                 /* move to the next record */
00096                 last_ptr = rec_ptr;
00097                 rec_ptr = rec.next;
00098                 *pnum_entries += 1;
00099         }
00100 
00101         ret = 0;
00102 
00103   fail:
00104 
00105         tdb_close(mem_tdb);
00106         tdb_unlock(tdb, -1, F_WRLCK);
00107         return ret;
00108 }


変数

TDB_DATA tdb_null

tdb.c31 行で定義されています。

参照元 tdb_fetch()tdb_firstkey()tdb_nextkey().


Sambaに対してSat Aug 29 21:24:31 2009に生成されました。  doxygen 1.4.7