/* * __wt_strndup -- * Duplicate a byte string of a given length (and NUL-terminate). */ int __wt_strndup(WT_SESSION_IMPL *session, const void *str, size_t len, void *retp) { void *p; if (str == NULL) { *(void **)retp = NULL; return (0); } WT_RET(__wt_malloc(session, len + 1, &p)); /* * Don't change this to strncpy, we rely on this function to duplicate * "strings" that contain nul bytes. */ memcpy(p, str, len); ((uint8_t *)p)[len] = '\0'; *(void **)retp = p; return (0); }
/* * __wt_getenv -- * Get a non-NULL, greater than zero-length environment variable. */ int __wt_getenv(WT_SESSION_IMPL *session, const char *variable, const char **envp) { DWORD size, windows_error; *envp = NULL; if ((size = GetEnvironmentVariableA(variable, NULL, 0)) <= 1) return (0); WT_RET(__wt_malloc(session, (size_t)size, envp)); /* We expect the number of bytes not including nul terminator. */ if (GetEnvironmentVariableA(variable, *envp, size) == size - 1) return (0); windows_error = __wt_getlasterror(); __wt_errx(session, "GetEnvironmentVariableA: %s: %s", variable, __wt_formatmessage(session, windows_error)); return (__wt_map_windows_error(windows_error)); }
/* * __wt_conn_optrack_setup -- * Set up operation logging. */ int __wt_conn_optrack_setup(WT_SESSION_IMPL *session, const char *cfg[], bool reconfig) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; WT_DECL_ITEM(buf); WT_DECL_RET; conn = S2C(session); /* Once an operation tracking path has been set it can't be changed. */ if (!reconfig) { WT_RET(__wt_config_gets(session, cfg, "operation_tracking.path", &cval)); WT_RET(__wt_strndup(session, cval.str, cval.len, &conn->optrack_path)); } WT_RET(__wt_config_gets(session, cfg, "operation_tracking.enabled", &cval)); if (cval.val == 0) { if (F_ISSET(conn, WT_CONN_OPTRACK)) { WT_RET(__wt_conn_optrack_teardown(session, reconfig)); F_CLR(conn, WT_CONN_OPTRACK); } return (0); } if (F_ISSET(conn, WT_CONN_READONLY)) /* Operation tracking isn't supported in read-only mode */ WT_RET_MSG(session, EINVAL, "Operation tracking is incompatible with read only " "configuration."); if (F_ISSET(conn, WT_CONN_OPTRACK)) /* Already enabled, nothing else to do */ return (0); /* * Operation tracking files will include the ID of the creating process * in their name, so we can distinguish between log files created by * different WiredTiger processes in the same directory. We cache the * process id for future use. */ conn->optrack_pid = __wt_process_id(); /* * Open the file in the same directory that will hold a map of * translations between function names and function IDs. If the file * exists, remove it. */ WT_RET(__wt_scr_alloc(session, 0, &buf)); WT_ERR(__wt_filename_construct(session, conn->optrack_path, "optrack-map", conn->optrack_pid, UINT32_MAX, buf)); WT_ERR(__wt_open(session, (const char *)buf->data, WT_FS_OPEN_FILE_TYPE_REGULAR, WT_FS_OPEN_CREATE, &conn->optrack_map_fh)); WT_ERR(__wt_spin_init(session, &conn->optrack_map_spinlock, "optrack map spinlock")); WT_ERR(__wt_malloc(session, WT_OPTRACK_BUFSIZE, &conn->dummy_session.optrack_buf)); /* Set operation tracking on */ F_SET(conn, WT_CONN_OPTRACK); err: __wt_scr_free(session, &buf); return (ret); }
WT_ERR(__wt_buf_fmt(session, tmp, "%s.copy", to)); WT_ERR(__wt_remove_if_exists(session, to, false)); WT_ERR(__wt_remove_if_exists(session, tmp->data, false)); /* Open the from and temporary file handles. */ WT_ERR(__wt_open(session, from, WT_FS_OPEN_FILE_TYPE_REGULAR, 0, &ffh)); WT_ERR(__wt_open(session, tmp->data, WT_FS_OPEN_FILE_TYPE_REGULAR, WT_FS_OPEN_CREATE | WT_FS_OPEN_EXCLUSIVE, &tfh)); /* * Allocate a copy buffer. Don't use a scratch buffer, this thing is * big, and we don't want it hanging around. */ #define WT_BACKUP_COPY_SIZE (128 * 1024) WT_ERR(__wt_malloc(session, WT_BACKUP_COPY_SIZE, &buf)); /* Get the file's size, then copy the bytes. */ WT_ERR(__wt_filesize(session, ffh, &size)); for (offset = 0; size > 0; size -= n, offset += n) { n = WT_MIN(size, WT_BACKUP_COPY_SIZE); WT_ERR(__wt_read(session, ffh, offset, (size_t)n, buf)); WT_ERR(__wt_write(session, tfh, offset, (size_t)n, buf)); } /* Close the from handle, then swap the temporary file into place. */ WT_ERR(__wt_close(session, &ffh)); WT_ERR(__wt_fsync(session, tfh, true)); WT_ERR(__wt_close(session, &tfh)); ret = __wt_fs_rename(session, tmp->data, to, true);