summaryrefslogtreecommitdiffstats
path: root/ctdb/lib/tdb/common/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'ctdb/lib/tdb/common/open.c')
-rw-r--r--ctdb/lib/tdb/common/open.c61
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;