summaryrefslogtreecommitdiffstats
path: root/src/lib/kdb/kdb_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/kdb/kdb_log.c')
-rw-r--r--src/lib/kdb/kdb_log.c198
1 files changed, 90 insertions, 108 deletions
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
index 71f0a330e5..c988dcbceb 100644
--- a/src/lib/kdb/kdb_log.c
+++ b/src/lib/kdb/kdb_log.c
@@ -34,9 +34,6 @@ static int pagesize = 0;
ulog = log_ctx->ulog; \
assert(ulog != NULL)
-static int extend_file_to(int fd, unsigned int new_size);
-static void ulog_reset(kdb_hlog_t *ulog);
-
static inline krb5_boolean
time_equal(const kdbe_time_t *a, const kdbe_time_t *b)
{
@@ -53,24 +50,9 @@ time_current(kdbe_time_t *out)
out->useconds = timestamp.tv_usec;
}
-krb5_error_code
-ulog_lock(krb5_context ctx, int mode)
-{
- kdb_log_context *log_ctx = NULL;
- kdb_hlog_t *ulog = NULL;
-
- if (ctx == NULL)
- return KRB5_LOG_ERROR;
- if (ctx->kdblog_context == NULL ||
- ctx->kdblog_context->iproprole == IPROP_NULL)
- return 0;
- INIT_ULOG(ctx);
- return krb5_lock_file(ctx, log_ctx->ulogfd, mode);
-}
-
/* Sync update entry to disk. */
static krb5_error_code
-ulog_sync_update(kdb_hlog_t *ulog, kdb_ent_header_t *upd)
+sync_update(kdb_hlog_t *ulog, kdb_ent_header_t *upd)
{
unsigned long start, end, size;
@@ -93,7 +75,6 @@ ulog_sync_update(kdb_hlog_t *ulog, kdb_ent_header_t *upd)
void
ulog_sync_header(kdb_hlog_t *ulog)
{
-
if (!pagesize)
pagesize = getpagesize();
@@ -104,6 +85,39 @@ ulog_sync_header(kdb_hlog_t *ulog)
}
}
+/* Extend update log file. */
+static int
+extend_file_to(int fd, unsigned int new_size)
+{
+ off_t current_offset;
+ static const char zero[512];
+ ssize_t wrote_size;
+ size_t write_size;
+
+ current_offset = lseek(fd, 0, SEEK_END);
+ if (current_offset < 0)
+ return -1;
+ if (new_size > INT_MAX) {
+ errno = EINVAL;
+ return -1;
+ }
+ while (current_offset < (off_t)new_size) {
+ write_size = new_size - current_offset;
+ if (write_size > 512)
+ write_size = 512;
+ wrote_size = write(fd, zero, write_size);
+ if (wrote_size < 0)
+ return -1;
+ if (wrote_size == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ current_offset += wrote_size;
+ write_size = new_size - current_offset;
+ }
+ return 0;
+}
+
/*
* Resize the array elements. We reinitialize the update log rather than
* unrolling the the log and copying it over to a temporary log for obvious
@@ -111,8 +125,8 @@ ulog_sync_header(kdb_hlog_t *ulog)
* need for resizing should be very small.
*/
static krb5_error_code
-ulog_resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
- unsigned int recsize)
+resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
+ unsigned int recsize)
{
unsigned int new_block, new_size;
@@ -142,6 +156,32 @@ ulog_resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
return 0;
}
+static void
+reset_header(kdb_hlog_t *ulog)
+{
+ memset(ulog, 0, sizeof(*ulog));
+ ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
+ ulog->db_version_num = KDB_VERSION;
+ ulog->kdb_state = KDB_STABLE;
+ ulog->kdb_block = ULOG_BLOCK;
+ time_current(&ulog->kdb_last_time);
+}
+
+krb5_error_code
+ulog_lock(krb5_context ctx, int mode)
+{
+ kdb_log_context *log_ctx = NULL;
+ kdb_hlog_t *ulog = NULL;
+
+ if (ctx == NULL)
+ return KRB5_LOG_ERROR;
+ if (ctx->kdblog_context == NULL ||
+ ctx->kdblog_context->iproprole == IPROP_NULL)
+ return 0;
+ INIT_ULOG(ctx);
+ return krb5_lock_file(ctx, log_ctx->ulogfd, mode);
+}
+
/*
* Add an entry to the update log. The layout of the update log looks like:
*
@@ -176,7 +216,7 @@ ulog_add_update(krb5_context context, kdb_incr_update_t *upd)
recsize = sizeof(kdb_ent_header_t) + upd_size;
if (recsize > ulog->kdb_block) {
- retval = ulog_resize(ulog, ulogentries, ulogfd, recsize);
+ retval = resize(ulog, ulogentries, ulogfd, recsize);
if (retval)
return retval;
}
@@ -184,14 +224,14 @@ ulog_add_update(krb5_context context, kdb_incr_update_t *upd)
/* If we have reached the last possible serial number, reinitialize the
* ulog and start over. Slaves will do a full resync. */
if (ulog->kdb_last_sno == (kdb_sno_t)-1)
- ulog_reset(ulog);
+ reset_header(ulog);
/* Get the next serial number and save it for finish_update() to index. */
cur_sno = ulog->kdb_last_sno + 1;
upd->kdb_entry_sno = cur_sno;
i = (cur_sno - 1) % ulogentries;
- indx_log = (kdb_ent_header_t *)INDEX(ulog, i);
+ indx_log = INDEX(ulog, i);
memset(indx_log, 0, ulog->kdb_block);
indx_log->kdb_umagic = KDB_ULOG_MAGIC;
@@ -207,7 +247,7 @@ ulog_add_update(krb5_context context, kdb_incr_update_t *upd)
if (!xdr_kdb_incr_update_t(&xdrs, upd))
return KRB5_LOG_CONV;
- retval = ulog_sync_update(ulog, indx_log);
+ retval = sync_update(ulog, indx_log);
if (retval)
return retval;
@@ -220,7 +260,7 @@ ulog_add_update(krb5_context context, kdb_incr_update_t *upd)
if (cur_sno > ulogentries) {
/* Once we've circled, kdb_first_sno is the sno of the next entry. */
i = upd->kdb_entry_sno % ulogentries;
- indx_log = (kdb_ent_header_t *)INDEX(ulog, i);
+ indx_log = INDEX(ulog, i);
ulog->kdb_first_sno = indx_log->kdb_entry_sno;
ulog->kdb_first_time = indx_log->kdb_time;
} else if (cur_sno == 1) {
@@ -249,12 +289,12 @@ ulog_finish_update(krb5_context context, kdb_incr_update_t *upd)
i = (upd->kdb_entry_sno - 1) % ulogentries;
- indx_log = (kdb_ent_header_t *)INDEX(ulog, i);
+ indx_log = INDEX(ulog, i);
indx_log->kdb_commit = TRUE;
ulog->kdb_state = KDB_STABLE;
- retval = ulog_sync_update(ulog, indx_log);
+ retval = sync_update(ulog, indx_log);
if (retval)
return retval;
@@ -262,23 +302,6 @@ ulog_finish_update(krb5_context context, kdb_incr_update_t *upd)
return 0;
}
-/* Set the header log details on the slave and sync it to file. */
-static void
-ulog_finish_update_slave(kdb_hlog_t *ulog, kdb_last_t lastentry)
-{
- ulog->kdb_last_sno = lastentry.last_sno;
- ulog->kdb_last_time = lastentry.last_time;
- ulog_sync_header(ulog);
-}
-
-/* Delete an entry to the update log. */
-krb5_error_code
-ulog_delete_update(krb5_context context, kdb_incr_update_t *upd)
-{
- upd->kdb_deleted = TRUE;
- return ulog_add_update(context, upd);
-}
-
/* Used by the slave to update its hash db from* the incr update log. Must be
* called with lock held. */
krb5_error_code
@@ -289,7 +312,7 @@ ulog_replay(krb5_context context, kdb_incr_result_t *incr_ret, char **db_args)
int i, no_of_updates;
krb5_error_code retval;
krb5_principal dbprinc;
- kdb_last_t errlast;
+ kdb_last_t errlast, *last;
char *dbprincstr;
kdb_log_context *log_ctx;
kdb_hlog_t *ulog = NULL;
@@ -305,6 +328,7 @@ ulog_replay(krb5_context context, kdb_incr_result_t *incr_ret, char **db_args)
errlast.last_sno = (unsigned int)0;
errlast.last_time.seconds = (unsigned int)0;
errlast.last_time.useconds = (unsigned int)0;
+ last = &errlast;
retval = krb5_db_open(context, db_args,
KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN);
@@ -348,29 +372,20 @@ ulog_replay(krb5_context context, kdb_incr_result_t *incr_ret, char **db_args)
upd++;
}
+ last = &incr_ret->lastentry;
+
cleanup:
if (fupd)
ulog_free_entries(fupd, no_of_updates);
- if (retval)
- ulog_finish_update_slave(ulog, errlast);
- else
- ulog_finish_update_slave(ulog, incr_ret->lastentry);
+ /* Record a new last serial number and timestamp in the ulog header. */
+ ulog->kdb_last_sno = last->last_sno;
+ ulog->kdb_last_time = last->last_time;
+ ulog_sync_header(ulog);
return retval;
}
-static void
-ulog_reset(kdb_hlog_t *ulog)
-{
- memset(ulog, 0, sizeof(*ulog));
- ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
- ulog->db_version_num = KDB_VERSION;
- ulog->kdb_state = KDB_STABLE;
- ulog->kdb_block = ULOG_BLOCK;
- time_current(&ulog->kdb_last_time);
-}
-
/* Reinitialize the log header. Locking is the caller's responsibility. */
void
ulog_init_header(krb5_context context)
@@ -379,7 +394,7 @@ ulog_init_header(krb5_context context)
kdb_hlog_t *ulog;
INIT_ULOG(context);
- ulog_reset(ulog);
+ reset_header(ulog);
ulog_sync_header(ulog);
}
@@ -499,7 +514,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries,
}
if (ulog->kdb_hmagic != KDB_ULOG_HDR_MAGIC || caller == FKLOAD) {
- ulog_reset(ulog);
+ reset_header(ulog);
if (caller != FKPROPLOG)
ulog_sync_header(ulog);
ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
@@ -520,7 +535,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries,
if (ulog->kdb_num != 0 &&
(ulog->kdb_last_sno > ulog->kdb_num ||
ulog->kdb_num > ulogentries)) {
- ulog_reset(ulog);
+ reset_header(ulog);
ulog_sync_header(ulog);
}
@@ -541,7 +556,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries,
/* Get the last set of updates seen, (last+1) to n is returned. */
krb5_error_code
-ulog_get_entries(krb5_context context, kdb_last_t last,
+ulog_get_entries(krb5_context context, const kdb_last_t *last,
kdb_incr_result_t *ulog_handle)
{
XDR xdrs;
@@ -564,7 +579,7 @@ ulog_get_entries(krb5_context context, kdb_last_t last,
/* If another process terminated mid-update, reset the ulog and force full
* resyncs. */
if (ulog->kdb_state != KDB_STABLE)
- ulog_reset(ulog);
+ reset_header(ulog);
/*
* We need to lock out other processes here, such as kadmin.local, since we
@@ -579,26 +594,26 @@ ulog_get_entries(krb5_context context, kdb_last_t last,
/* If we have the same sno and timestamp, return a nil update. If a
* different timestamp, the sno was reused and we need a full resync. */
- if (last.last_sno == ulog->kdb_last_sno) {
- ulog_handle->ret = time_equal(&last.last_time, &ulog->kdb_last_time) ?
+ if (last->last_sno == ulog->kdb_last_sno) {
+ ulog_handle->ret = time_equal(&last->last_time, &ulog->kdb_last_time) ?
UPDATE_NIL : UPDATE_FULL_RESYNC_NEEDED;
goto cleanup;
}
/* We may have overflowed the update log or shrunk the log, or the client
* may have created its ulog. */
- if (last.last_sno > ulog->kdb_last_sno ||
- last.last_sno < ulog->kdb_first_sno) {
+ if (last->last_sno > ulog->kdb_last_sno ||
+ last->last_sno < ulog->kdb_first_sno) {
ulog_handle->lastentry.last_sno = ulog->kdb_last_sno;
ulog_handle->ret = UPDATE_FULL_RESYNC_NEEDED;
goto cleanup;
}
- sno = last.last_sno;
+ sno = last->last_sno;
indx = (sno - 1) % ulogentries;
- indx_log = (kdb_ent_header_t *)INDEX(ulog, indx);
+ indx_log = INDEX(ulog, indx);
- if (!time_equal(&indx_log->kdb_time, &last.last_time)) {
+ if (!time_equal(&indx_log->kdb_time, &last->last_time)) {
/* We have time stamp mismatch or we no longer have the slave's last
* sno, so we brute force it. */
ulog_handle->ret = UPDATE_FULL_RESYNC_NEEDED;
@@ -616,7 +631,7 @@ ulog_get_entries(krb5_context context, kdb_last_t last,
for (; sno < ulog->kdb_last_sno; sno++) {
indx = sno % ulogentries;
- indx_log = (kdb_ent_header_t *)INDEX(ulog, indx);
+ indx_log = INDEX(ulog, indx);
memset(upd, 0, sizeof(kdb_incr_update_t));
xdrmem_create(&xdrs, (char *)indx_log->entry_data,
@@ -657,36 +672,3 @@ ulog_set_role(krb5_context ctx, iprop_role role)
ctx->kdblog_context->iproprole = role;
return 0;
}
-
-/* Extend update log file. */
-static int
-extend_file_to(int fd, unsigned int new_size)
-{
- off_t current_offset;
- static const char zero[512];
- ssize_t wrote_size;
- size_t write_size;
-
- current_offset = lseek(fd, 0, SEEK_END);
- if (current_offset < 0)
- return -1;
- if (new_size > INT_MAX) {
- errno = EINVAL;
- return -1;
- }
- while (current_offset < (off_t)new_size) {
- write_size = new_size - current_offset;
- if (write_size > 512)
- write_size = 512;
- wrote_size = write(fd, zero, write_size);
- if (wrote_size < 0)
- return -1;
- if (wrote_size == 0) {
- errno = EINVAL;
- return -1;
- }
- current_offset += wrote_size;
- write_size = new_size - current_offset;
- }
- return 0;
-}