/* * __wt_log_system_record -- * Write a system log record for the previous LSN. */ int __wt_log_system_record( WT_SESSION_IMPL *session, WT_FH *log_fh, WT_LSN *lsn) { WT_DECL_ITEM(logrec_buf); WT_DECL_RET; WT_LOG *log; WT_LOG_RECORD *logrec; WT_LOGSLOT tmp; WT_MYSLOT myslot; const char *fmt = WT_UNCHECKED_STRING(I); uint32_t rectype = WT_LOGREC_SYSTEM; size_t recsize; log = S2C(session)->log; WT_RET(__wt_logrec_alloc(session, log->allocsize, &logrec_buf)); memset((uint8_t *)logrec_buf->mem, 0, log->allocsize); WT_ERR(__wt_struct_size(session, &recsize, fmt, rectype)); WT_ERR(__wt_struct_pack(session, (uint8_t *)logrec_buf->data + logrec_buf->size, recsize, fmt, rectype)); logrec_buf->size += recsize; WT_ERR(__wt_logop_prev_lsn_pack(session, logrec_buf, lsn)); WT_ASSERT(session, logrec_buf->size <= log->allocsize); logrec = (WT_LOG_RECORD *)logrec_buf->mem; /* * We know system records are this size. And we have to adjust * the size now because we're not going through the normal log * write path and the packing functions needed the correct offset * earlier. */ logrec_buf->size = logrec->len = log->allocsize; /* We do not compress nor encrypt this record. */ logrec->checksum = 0; logrec->flags = 0; __wt_log_record_byteswap(logrec); logrec->checksum = __wt_checksum(logrec, log->allocsize); #ifdef WORDS_BIGENDIAN logrec->checksum = __wt_bswap32(logrec->checksum); #endif WT_CLEAR(tmp); memset(&myslot, 0, sizeof(myslot)); myslot.slot = &tmp; __wt_log_slot_activate(session, &tmp); /* * Override the file handle to the one we're using. */ tmp.slot_fh = log_fh; WT_ERR(__wt_log_fill(session, &myslot, true, logrec_buf, NULL)); err: __wt_logrec_free(session, &logrec_buf); return (ret); }
/* * __wt_log_slot_init -- * Initialize the slot array. */ int __wt_log_slot_init(WT_SESSION_IMPL *session, bool alloc) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_LOG *log; WT_LOGSLOT *slot; int32_t i; conn = S2C(session); log = conn->log; for (i = 0; i < WT_SLOT_POOL; i++) log->slot_pool[i].slot_state = WT_LOG_SLOT_FREE; /* * Allocate memory for buffers now that the arrays are setup. Separate * this from the loop above to make error handling simpler. */ /* * !!! If the buffer size is too close to the log file size, we will * switch log files very aggressively. Scale back the buffer for * small log file sizes. */ if (alloc) { log->slot_buf_size = (uint32_t)WT_MIN( (size_t)conn->log_file_max / 10, WT_LOG_SLOT_BUF_SIZE); for (i = 0; i < WT_SLOT_POOL; i++) { WT_ERR(__wt_buf_init(session, &log->slot_pool[i].slot_buf, log->slot_buf_size)); F_SET(&log->slot_pool[i], WT_SLOT_INIT_FLAGS); } WT_STAT_CONN_SET(session, log_buffer_size, log->slot_buf_size * WT_SLOT_POOL); } /* * Set up the available slot from the pool the first time. */ slot = &log->slot_pool[0]; /* * We cannot initialize the release LSN in the activate function * because that function can be called after a log file switch. * The release LSN is usually the same as the slot_start_lsn except * around a log file switch. */ slot->slot_release_lsn = log->alloc_lsn; __wt_log_slot_activate(session, slot); log->active_slot = slot; log->pool_index = 0; if (0) { err: while (--i >= 0) __wt_buf_free(session, &log->slot_pool[i].slot_buf); } return (ret); }