diff options
author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2012-04-26 08:09:34 +1000 |
---|---|---|
committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2012-04-26 08:09:34 +1000 |
commit | 4426f9a5317d7eda10a43e6cf76f154c17e81f64 (patch) | |
tree | d6aa0ecdf87fe7e58a3754f86b5e7e9f2962f750 /ctdb/lib/tdb/common/open.c | |
parent | db411aaada39593c80f92e46be31d3473bf4639f (diff) | |
parent | 8f643897bbd33ea0c120dc06586434b8a2592b1f (diff) | |
download | samba-4426f9a5317d7eda10a43e6cf76f154c17e81f64.tar.gz samba-4426f9a5317d7eda10a43e6cf76f154c17e81f64.tar.xz samba-4426f9a5317d7eda10a43e6cf76f154c17e81f64.zip |
Merge remote branch 'amitay/tdb-sync'
(This used to be ctdb commit 8052ee0a6bda3fa88501d77b2d53315be2b75ec1)
Diffstat (limited to 'ctdb/lib/tdb/common/open.c')
-rw-r--r-- | ctdb/lib/tdb/common/open.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/ctdb/lib/tdb/common/open.c b/ctdb/lib/tdb/common/open.c index 66539c3f6c..8836f8442e 100644 --- a/ctdb/lib/tdb/common/open.c +++ b/ctdb/lib/tdb/common/open.c @@ -129,7 +129,7 @@ static int tdb_already_open(dev_t device, try to call tdb_error or tdb_errname, just do strerror(errno). @param name may be NULL for internal databases. */ -struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, +_PUBLIC_ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) { return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); @@ -162,7 +162,7 @@ static bool check_header_hash(struct tdb_context *tdb, return check_header_hash(tdb, false, m1, m2); } -struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, +_PUBLIC_ 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) @@ -197,6 +197,32 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->log.log_private = NULL; } + if (name == NULL && (tdb_flags & TDB_INTERNAL)) { + name = "__TDB_INTERNAL__"; + } + + if (name == NULL) { + tdb->name = discard_const_p(char, "__NULL__"); + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: called with name == NULL\n")); + tdb->name = NULL; + errno = EINVAL; + goto fail; + } + + /* now make a copy of the name, as the caller memory might went away */ + if (!(tdb->name = (char *)strdup(name))) { + /* + * set the name as the given string, so that tdb_name() will + * work in case of an error. + */ + tdb->name = discard_const_p(char, name); + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't strdup(%s)\n", + name)); + tdb->name = NULL; + errno = ENOMEM; + goto fail; + } + if (hash_fn) { tdb->hash_fn = hash_fn; hash_alg = "the user defined"; @@ -359,12 +385,17 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, goto fail; } - if (!(tdb->name = (char *)strdup(name))) { - errno = ENOMEM; + /* Beware truncation! */ + tdb->map_size = st.st_size; + if (tdb->map_size != st.st_size) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "len %llu too large!\n", (long long)st.st_size)); + errno = EIO; goto fail; } - tdb->map_size = st.st_size; tdb->device = st.st_dev; tdb->inode = st.st_ino; tdb_mmap(tdb); @@ -436,11 +467,11 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, else tdb_munmap(tdb); } - SAFE_FREE(tdb->name); if (tdb->fd != -1) if (close(tdb->fd) != 0) TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n")); SAFE_FREE(tdb->lockrecs); + SAFE_FREE(tdb->name); SAFE_FREE(tdb); errno = save_errno; return NULL; @@ -451,7 +482,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, * Set the maximum number of dead records per hash chain */ -void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) +_PUBLIC_ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) { tdb->max_dead_records = max_dead; } @@ -461,7 +492,7 @@ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) * * @returns -1 for error; 0 for success. **/ -int tdb_close(struct tdb_context *tdb) +_PUBLIC_ int tdb_close(struct tdb_context *tdb) { struct tdb_context **i; int ret = 0; @@ -502,13 +533,13 @@ int tdb_close(struct tdb_context *tdb) } /* register a loging function */ -void tdb_set_logging_function(struct tdb_context *tdb, - const struct tdb_logging_context *log_ctx) +_PUBLIC_ void tdb_set_logging_function(struct tdb_context *tdb, + const struct tdb_logging_context *log_ctx) { tdb->log = *log_ctx; } -void *tdb_get_logging_private(struct tdb_context *tdb) +_PUBLIC_ void *tdb_get_logging_private(struct tdb_context *tdb) { return tdb->log.log_private; } @@ -556,7 +587,9 @@ static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); goto fail; } - tdb_mmap(tdb); + if (tdb_mmap(tdb) != 0) { + goto fail; + } #endif /* fake pread or pwrite */ /* We may still think we hold the active lock. */ @@ -577,13 +610,13 @@ fail: /* reopen a tdb - this can be used after a fork to ensure that we have an independent seek pointer from our parent and to re-establish locks */ -int tdb_reopen(struct tdb_context *tdb) +_PUBLIC_ int tdb_reopen(struct tdb_context *tdb) { return tdb_reopen_internal(tdb, tdb->flags & TDB_CLEAR_IF_FIRST); } /* reopen all tdb's */ -int tdb_reopen_all(int parent_longlived) +_PUBLIC_ int tdb_reopen_all(int parent_longlived) { struct tdb_context *tdb; |