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.c99
1 files changed, 63 insertions, 36 deletions
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
index b800fa6fe2..4ecc34057c 100644
--- a/src/lib/kdb/kdb_log.c
+++ b/src/lib/kdb/kdb_log.c
@@ -536,12 +536,50 @@ error:
return (retval);
}
+static void
+ulog_reset(kdb_hlog_t *ulog)
+{
+ (void) 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;
+}
+
/*
* Map the log file to memory for performance and simplicity.
*
* Called by: if iprop_enabled then ulog_map();
* Assumes that the caller will terminate on ulog_map, hence munmap and
* closing of the fd are implicitly performed by the caller.
+ *
+ * Semantics for various values of caller:
+ *
+ * - FKPROPLOG
+ *
+ * Don't create if it doesn't exist, map as MAP_PRIVATE.
+ *
+ * - FKPROPD
+ *
+ * Create and initialize if need be, map as MAP_SHARED.
+ *
+ * - FKLOAD
+ *
+ * Create if need be, initialize (even if the ulog was already present), map
+ * as MAP_SHARED. (Intended for kdb5_util load of iprop dump.)
+ *
+ * - FKCOMMAND
+ *
+ * Create and [re-]initialize if need be, size appropriately, map as
+ * MAP_SHARED. (Intended for kdb5_util create and kdb5_util load of
+ * non-iprop dump.)
+ *
+ * - FKADMIN
+ *
+ * Create and [re-]initialize if need be, size appropriately, map as
+ * MAP_SHARED, and check consistency and recover as necessary. (Intended
+ * for kadmind and kadmin.local.)
+ *
* Returns 0 on success else failure.
*/
krb5_error_code
@@ -566,7 +604,8 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries,
return (errno);
}
- if ((ulogfd = open(logname, O_RDWR+O_CREAT, 0600)) == -1) {
+ ulogfd = open(logname, O_RDWR | O_CREAT, 0600);
+ if (ulogfd == -1) {
return (errno);
}
@@ -625,28 +664,30 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries,
log_ctx->ulogentries = ulogentries;
log_ctx->ulogfd = ulogfd;
- if (ulog->kdb_hmagic != KDB_ULOG_HDR_MAGIC) {
- if (ulog->kdb_hmagic == 0) {
- /*
- * New update log
- */
- (void) memset(ulog, 0, sizeof (kdb_hlog_t));
+ retval = ulog_lock(context, KRB5_LOCKMODE_EXCLUSIVE);
+ if (retval)
+ return retval;
- ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
- ulog->db_version_num = KDB_VERSION;
- ulog->kdb_state = KDB_STABLE;
- ulog->kdb_block = ULOG_BLOCK;
- if (!(caller == FKPROPLOG))
- ulog_sync_header(ulog);
- } else {
- return (KRB5_LOG_CORRUPT);
- }
+ if (ulog->kdb_hmagic != KDB_ULOG_HDR_MAGIC && ulog->kdb_hmagic != 0) {
+ ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
+ return (KRB5_LOG_CORRUPT);
+ }
+
+ if (ulog->kdb_hmagic != KDB_ULOG_HDR_MAGIC || caller == FKLOAD) {
+ ulog_reset(ulog);
+ if (caller != FKPROPLOG)
+ ulog_sync_header(ulog);
+ ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
+ return (0);
+ }
+
+ if ((caller == FKPROPLOG) || (caller == FKPROPD)) {
+ /* kproplog and kpropd don't need to do anything else. */
+ ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
+ return (0);
}
if (caller == FKADMIND) {
- retval = ulog_lock(context, KRB5_LOCKMODE_EXCLUSIVE);
- if (retval)
- return retval;
switch (ulog->kdb_state) {
case KDB_STABLE:
case KDB_UNSTABLE:
@@ -655,9 +696,8 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries,
*/
retval = ulog_check(context, ulog, db_args);
ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
- if (retval == KRB5_LOG_CORRUPT) {
+ if (retval)
return (retval);
- }
break;
case KDB_CORRUPT:
ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
@@ -669,32 +709,19 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries,
ulog_lock(context, KRB5_LOCKMODE_UNLOCK);
return (KRB5_LOG_ERROR);
}
- } else if ((caller == FKPROPLOG) || (caller == FKPROPD)) {
- /*
- * kproplog and kpropd don't need to do anything else
- */
- return (0);
}
+ assert(caller == FKADMIND || caller == FKCOMMAND);
/*
* Reinit ulog if the log is being truncated or expanded after
* we have circled.
*/
- retval = ulog_lock(context, KRB5_LOCKMODE_EXCLUSIVE);
- if (retval)
- return retval;
if (ulog->kdb_num != ulogentries) {
if ((ulog->kdb_num != 0) &&
((ulog->kdb_last_sno > ulog->kdb_num) ||
(ulog->kdb_num > ulogentries))) {
- (void) memset(ulog, 0, sizeof (kdb_hlog_t));
-
- ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
- ulog->db_version_num = KDB_VERSION;
- ulog->kdb_state = KDB_STABLE;
- ulog->kdb_block = ULOG_BLOCK;
-
+ ulog_reset(ulog);
ulog_sync_header(ulog);
}