From 6506c87aab5567ae855d1f75dc9b41e1a091f542 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Thu, 23 Jan 2014 18:15:24 -0500 Subject: Modernize iprop code * Don't use "extern" for kdb_log.h prototypes. * Avoid passing structures by value. * Avoid the need to cast the result of the INDEX macro, and use char * instead of unsigned long for pointer arithmetic. * Reorganize kdb_log.c so static helpers are at the top and don't use the "ulog_" prefix. * Get rid of ulog_finish_update_slave since it's more concise to open-code it in ulog_replay. * Get rid of ulog_delete_update. In krb5_db_delete_principal, just call ulog_add_update with kdb_deleted set in upd. * Modernize coding style of kproplog.c. Use k5memdup0 instead of snprintf in print_str to convert a byte range to a C string. Remove an unnecesary textdomain call; libkrb5 takes care of calling bindtextdomain in the library initializer. * Modernize coding style of kpropd.c and kprop.c. No functional changes. --- src/lib/kdb/kdb5.c | 3 +- src/lib/kdb/kdb_log.c | 198 +++++++++++++++++++++++--------------------------- 2 files changed, 92 insertions(+), 109 deletions(-) (limited to 'src/lib/kdb') diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index 93293bac19..ca2040d3bc 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -978,8 +978,9 @@ krb5_db_delete_principal(krb5_context kcontext, krb5_principal search_for) upd.kdb_princ_name.utf8str_t_val = princ_name; upd.kdb_princ_name.utf8str_t_len = strlen(princ_name); + upd.kdb_deleted = TRUE; - status = ulog_delete_update(kcontext, &upd); + status = ulog_add_update(kcontext, &upd); if (status) goto cleanup; } 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; -} -- cgit