diff options
37 files changed, 362 insertions, 187 deletions
diff --git a/dist/log.py b/dist/log.py index 8743dd3a71c..23f5bf193f2 100644 --- a/dist/log.py +++ b/dist/log.py @@ -270,11 +270,13 @@ __wt_logop_%(name)s_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, %(arg_decls)s) { +\tWT_DECL_RET; \tconst char *fmt = WT_UNCHECKED_STRING(%(fmt)s); \tuint32_t optype, size; -\tWT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, -\t &optype, &size%(arg_names)s)); +\tif ((ret = __wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, +\t &optype, &size%(arg_names)s)) != 0) +\t\tWT_RET_MSG(session, ret, "logop_%(name)s: unpack failure"); \tWT_ASSERT(session, optype == %(macro)s); \t*pp += size; diff --git a/dist/s_errno b/dist/s_errno new file mode 100644 index 00000000000..9981842e458 --- /dev/null +++ b/dist/s_errno @@ -0,0 +1,73 @@ +#! /bin/sh + +# Complain about code that returns a system error value without an associated +# verbose message. +# +# This script is a kluge and isn't run by default. + +t=__wt.$$ +trap 'rm -f $t' 0 1 2 3 13 15 + +cd .. + +# Strip out a list of errors that will be flagged, but are OK. +error_ok() +{ + sed -e '/ERET(/d' \ + -e '/WT_ERR_MSG(/d' \ + -e '/WT_ERR_TEST(/d' \ + -e '/WT_PANIC_ERR(/d' \ + -e '/WT_PANIC_RET(/d' \ + -e '/WT_RET_MSG(/d' \ + -e '/\/intpack.i:.*EINVAL/d'\ + -e '/\/intpack.i:.*ENOMEM/d'\ + -e '/\/pack_impl.c:.*EINVAL/d'\ + -e '/\/pack_impl.c:.*ENOMEM/d'\ + -e '/\/pack_stream.c:.*ENOMEM/d'\ + -e '/\/packing.i:.*EINVAL/d'\ + -e '/__config_err(/d' \ + -e '/__wt_block_panic(/d' \ + -e '/__wt_err(/d' \ + -e '/__wt_errx(/d' \ + -e '/csv_error(/d' \ + -e '/nop_error(/d' \ + -e '/rotn_error(/d' \ + -e '/zlib_error(/d' +} + +# Loop through source files. +for f in `find ext src -name '*.[ci]'`; do + if expr "$f" : 'ext/datasources/helium/helium.c' > /dev/null; then + continue + fi + if expr "$f" : 'src/os_win/os_winerr.c' > /dev/null; then + continue + fi + if expr "$f" : 'src/utilities/.*' > /dev/null; then + continue + fi + + # Strip include files, + # then use the C preprocessor to strip comments, + # then turn each file into a single line, + # then chunk the file by semicolons, + # then search for explicit error returns (ignoring EBUSY), + # then prepend the file name to each line, + # then skip known calls that include verbose messages. + sed '/^#include/d' $f | + ${CC:-cc} -E - | + tr -s '\012' ' ' | tr ';' '\012' | + egrep -w 'EPERM|ENOENT|ESRCH|EINTR|EIO|ENXIO|E2BIG|ENOEXEC|EBADF|ECHILD|EDEADLK|ENOMEM|EACCES|EFAULT|ENOTBLK|EEXIST|EXDEV|ENODEV|ENOTDIR|EISDIR|EINVAL|ENFILE|EMFILE|ENOTTY|ETXTBSY|EFBIG|ENOSPC|ESPIPE|EROFS|EMLINK|EPIPE|EDOM|ERANGE|EAGAIN|EWOULDBLOCK|EINPROGRESS|EALREADY|ENOTSOCK|EDESTADDRREQ|EMSGSIZE|EPROTOTYPE|ENOPROTOOPT|EPROTONOSUPPORT|ESOCKTNOSUPPORT|EOPNOTSUPP|ENOTSUP|EPFNOSUPPORT|EAFNOSUPPORT|EADDRINUSE|EADDRNOTAVAIL|ENETDOWN|ENETUNREACH|ENETRESET|ECONNABORTED|ECONNRESET|ENOBUFS|EISCONN|ENOTCONN|ESHUTDOWN|ETOOMANYREFS|ETIMEDOUT|ECONNREFUSED|ELOOP|ENAMETOOLONG|EHOSTDOWN|EHOSTUNREACH|ENOTEMPTY|EPROCLIM|EUSERS|EDQUOT|ESTALE|EREMOTE|EBADRPC|ERPCMISMATCH|EPROGUNAVAIL|EPROGMISMATCH|EPROCUNAVAIL|ENOLCK|ENOSYS|EFTYPE|EAUTH|ENEEDAUTH|EIDRM|ENOMSG|EOVERFLOW|ECANCELED|EILSEQ|ENOATTR|EDOOFUS|EBADMSG|EMULTIHOP|ENOLINK|EPROTO|ENOTCAPABLE|ECAPMODE|ENOTRECOVERABLE|EOWNERDEAD|ELAST|ERESTART|EJUSTRETURN|ENOIOCTL|EDIRIOCTL' | + sed -e 's/^[ ]*//' \ + -e "s;^;$f: ;" | + error_ok +done > $t + +test -s $t && { + echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" + echo 'Unexpected error usage.' + echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" + cat $t + exit 1 +} +exit 0 diff --git a/dist/s_string.ok b/dist/s_string.ok index 7cf96aec399..65c74b61995 100644 --- a/dist/s_string.ok +++ b/dist/s_string.ok @@ -842,6 +842,7 @@ localtime logf logmgr lognum +logop logread logrec logsize diff --git a/dist/s_void b/dist/s_void index e5e9f97c0b7..b9c3f5e0ef7 100644 --- a/dist/s_void +++ b/dist/s_void @@ -32,6 +32,7 @@ func_ok() -e '/int __bm_stat$/d' \ -e '/int __checkpoint_presync$/d' \ -e '/int __compact_uri_analyze$/d' \ + -e '/int __config_parser_close$/d' \ -e '/int __curlog_reset$/d' \ -e '/int __handle_close_default$/d' \ -e '/int __handle_progress_default$/d' \ @@ -63,6 +64,7 @@ func_ok() -e '/int __wt_stat_join_desc$/d' \ -e '/int __wt_win_directory_list_free$/d' \ -e '/int bdb_compare_reverse$/d' \ + -e '/int csv_error$/d' \ -e '/int csv_terminate$/d' \ -e '/int demo_file_close$/d' \ -e '/int demo_file_lock$/d' \ @@ -81,6 +83,7 @@ func_ok() -e '/int main$/d' \ -e '/int nop_decompress$/d' \ -e '/int nop_decrypt$/d' \ + -e '/int nop_error$/d' \ -e '/int nop_pre_size$/d' \ -e '/int nop_sizing$/d' \ -e '/int nop_terminate$/d' \ @@ -90,14 +93,14 @@ func_ok() -e '/int rotn_error$/d' \ -e '/int rotn_sizing$/d' \ -e '/int rotn_terminate$/d' \ + -e '/int snappy_pre_size$/d' \ + -e '/int snappy_terminate$/d' \ -e '/int uri2name$/d' \ -e '/int usage$/d' \ -e '/int util_err$/d' \ -e '/int wiredtiger_extension_init$/d' \ -e '/int wiredtiger_extension_terminate$/d' \ -e '/int wiredtiger_pack_close$/d' \ - -e '/int snappy_pre_size$/d' \ - -e '/int snappy_terminate$/d' \ -e '/int zlib_error$/d' \ -e '/int zlib_terminate$/d' \ -e '/int zstd_error$/d' \ diff --git a/ext/compressors/zlib/zlib_compress.c b/ext/compressors/zlib/zlib_compress.c index 9ee8fe3bd8b..0539569015f 100644 --- a/ext/compressors/zlib/zlib_compress.c +++ b/ext/compressors/zlib/zlib_compress.c @@ -392,19 +392,27 @@ err: if ((tret = deflateEnd(zs)) != Z_OK && tret != Z_DATA_ERROR) #if 0 /* Decompress the result and confirm it matches the original source. */ if (ret == 0 && last_slot > 0) { + WT_EXTENSION_API *wt_api; void *decomp; size_t result_len; + wt_api = ((ZLIB_COMPRESSOR *)compressor)->wt_api; + if ((decomp = zalloc( - &opaque, 1, (uint32_t)best_zs->total_in + 100)) == NULL) + &opaque, 1, (uint32_t)best_zs->total_in + 100)) == NULL) { + (void)wt_api->err_printf(wt_api, session, + "zlib_compress_raw: zalloc failure"); return (ENOMEM); + } if ((ret = zlib_decompress( compressor, session, dst, (size_t)best_zs->total_out, decomp, (size_t)best_zs->total_in + 100, &result_len)) == 0) - if (memcmp(src, decomp, result_len) != 0) - ret = zlib_error(compressor, session, - "deflate compare with original source", - Z_DATA_ERROR); + if (memcmp(src, decomp, result_len) != 0) { + (void)wt_api->err_printf(wt_api, session, + "zlib_compress_raw: " + "deflate compare with original source"); + return (WT_ERROR); + } zfree(&opaque, decomp); } #endif diff --git a/ext/encryptors/nop/nop_encrypt.c b/ext/encryptors/nop/nop_encrypt.c index eac7d8f4632..eb311f09909 100644 --- a/ext/encryptors/nop/nop_encrypt.c +++ b/ext/encryptors/nop/nop_encrypt.c @@ -38,13 +38,29 @@ typedef struct { WT_ENCRYPTOR encryptor; /* Must come first */ - WT_EXTENSION_API *wt_api; /* Extension API */ + WT_EXTENSION_API *wtext; /* Extension API */ - unsigned long nop_calls; /* Count of calls */ + unsigned long nop_calls; /* Count of calls */ } NOP_ENCRYPTOR; /*! [WT_ENCRYPTOR initialization structure] */ +/* + * nop_error -- + * Display an error from this module in a standard way. + */ +static int +nop_error( + NOP_ENCRYPTOR *encryptor, WT_SESSION *session, int err, const char *msg) +{ + WT_EXTENSION_API *wtext; + + wtext = encryptor->wtext; + (void)wtext->err_printf(wtext, session, + "nop encryption: %s: %s", msg, wtext->strerror(wtext, NULL, err)); + return (err); +} + /*! [WT_ENCRYPTOR encrypt] */ /* * nop_encrypt -- @@ -63,7 +79,8 @@ nop_encrypt(WT_ENCRYPTOR *encryptor, WT_SESSION *session, ++nop_encryptor->nop_calls; /* Call count */ if (dst_len < src_len) - return (ENOMEM); + return (nop_error(nop_encryptor, session, + ENOMEM, "encrypt buffer not big enough")); memcpy(dst, src, src_len); *result_lenp = src_len; @@ -169,7 +186,7 @@ wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config) nop_encryptor->encryptor.sizing = nop_sizing; nop_encryptor->encryptor.terminate = nop_terminate; - nop_encryptor->wt_api = connection->get_extension_api(connection); + nop_encryptor->wtext = connection->get_extension_api(connection); /* Load the encryptor */ return (connection->add_encryptor( diff --git a/ext/encryptors/rotn/rotn_encrypt.c b/ext/encryptors/rotn/rotn_encrypt.c index 4d614e2e409..23a7ad79a7d 100644 --- a/ext/encryptors/rotn/rotn_encrypt.c +++ b/ext/encryptors/rotn/rotn_encrypt.c @@ -89,8 +89,8 @@ typedef struct { * Display an error from this module in a standard way. */ static int -rotn_error(ROTN_ENCRYPTOR *encryptor, WT_SESSION *session, int err, - const char *msg) +rotn_error( + ROTN_ENCRYPTOR *encryptor, WT_SESSION *session, int err, const char *msg) { WT_EXTENSION_API *wtext; @@ -189,7 +189,8 @@ rotn_encrypt(WT_ENCRYPTOR *encryptor, WT_SESSION *session, (void)session; /* Unused */ if (dst_len < src_len + CHKSUM_LEN + IV_LEN) - return (ENOMEM); + return (rotn_error(rotn_encryptor, session, + ENOMEM, "encrypt buffer not big enough")); /* * !!! Most implementations would verify any needed @@ -333,7 +334,8 @@ rotn_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session, * In this demonstration, we expect keyid to be a number. */ if ((keyid_val = atoi(keyid.str)) < 0) { - ret = EINVAL; + ret = rotn_error(rotn_encryptor, + NULL, EINVAL, "rotn_customize: invalid keyid"); goto err; } if ((rotn_encryptor->keyid = malloc(keyid.len + 1)) == NULL) { @@ -364,7 +366,8 @@ rotn_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session, else if ('A' <= secret.str[i] && secret.str[i] <= 'Z') base = 'A'; else { - ret = EINVAL; + ret = rotn_error(rotn_encryptor, NULL, + EINVAL, "rotn_customize: invalid key"); goto err; } base -= (u_char)keyid_val; diff --git a/ext/extractors/csv/csv_extractor.c b/ext/extractors/csv/csv_extractor.c index 698a9d6fa96..40e03f7ec1a 100644 --- a/ext/extractors/csv/csv_extractor.c +++ b/ext/extractors/csv/csv_extractor.c @@ -54,6 +54,22 @@ typedef struct { } CSV_EXTRACTOR; /* + * csv_error -- + * Display an error from this module in a standard way. + */ +static int +csv_error(const CSV_EXTRACTOR *csv_extractor, + WT_SESSION *session, int err, const char *msg) +{ + WT_EXTENSION_API *wt_api; + + wt_api = csv_extractor->wt_api; + (void)wt_api->err_printf(wt_api, session, + "csv extraction: %s: %s", msg, wt_api->strerror(wt_api, NULL, err)); + return (err); +} + +/* * csv_extract -- * WiredTiger CSV extraction. */ @@ -61,11 +77,11 @@ static int csv_extract(WT_EXTRACTOR *extractor, WT_SESSION *session, const WT_ITEM *key, const WT_ITEM *value, WT_CURSOR *result_cursor) { - char *copy, *p, *pend, *valstr; const CSV_EXTRACTOR *csv_extractor; - int i, ret, val; - size_t len; WT_EXTENSION_API *wtapi; + size_t len; + int i, ret, val; + char *copy, *p, *pend, *valstr; (void)key; /* Unused parameters */ @@ -98,8 +114,10 @@ csv_extract(WT_EXTRACTOR *extractor, WT_SESSION *session, copy[len] = '\0'; if (csv_extractor->format_isnum) { if ((val = atoi(copy)) < 0) { + ret = csv_error(csv_extractor, + session, EINVAL, "invalid key value"); free(copy); - return (EINVAL); + return (ret); } result_cursor->set_key(result_cursor, val); } else @@ -125,29 +143,38 @@ csv_customize(WT_EXTRACTOR *extractor, WT_SESSION *session, CSV_EXTRACTOR *csv_extractor; WT_CONFIG_ITEM field, format; WT_CONFIG_PARSER *parser; - WT_EXTENSION_API *wtapi; - int ret; + WT_EXTENSION_API *wt_api; long field_num; + int ret; (void)session; /* Unused parameters */ (void)uri; /* Unused parameters */ orig = (const CSV_EXTRACTOR *)extractor; - wtapi = orig->wt_api; - if ((ret = wtapi->config_parser_open(wtapi, session, appcfg->str, + wt_api = orig->wt_api; + if ((ret = wt_api->config_parser_open(wt_api, session, appcfg->str, appcfg->len, &parser)) != 0) return (ret); if ((ret = parser->get(parser, "field", &field)) != 0 || (ret = parser->get(parser, "format", &format)) != 0) { - if (ret == WT_NOTFOUND) - return (EINVAL); + if (ret == WT_NOTFOUND) { + (void)wt_api->err_printf( + wt_api, session, "field or format not found"); + return (WT_NOTFOUND); + } return (ret); } field_num = strtol(field.str, NULL, 10); - if (field_num < 0 || field_num > INT_MAX) + if (field_num < 0 || field_num > INT_MAX) { + (void)wt_api->err_printf( + wt_api, session, "field: invalid format"); return (EINVAL); - if (format.len != 1 || (format.str[0] != 'S' && format.str[0] != 'i')) + } + if (format.len != 1 || (format.str[0] != 'S' && format.str[0] != 'i')) { + (void)wt_api->err_printf( + wt_api, session, "format: invalid format"); return (EINVAL); + } if ((csv_extractor = calloc(1, sizeof(CSV_EXTRACTOR))) == NULL) return (errno); diff --git a/src/async/async_api.c b/src/async/async_api.c index bac4dc01bae..54bcb7cd26c 100644 --- a/src/async/async_api.c +++ b/src/async/async_api.c @@ -144,7 +144,7 @@ retry: */ if (op == NULL || op->state != WT_ASYNCOP_FREE) { WT_STAT_CONN_INCR(session, async_full); - WT_RET(EBUSY); + return (EBUSY); } /* * Set the state of this op handle as READY for the user to use. @@ -232,7 +232,7 @@ __async_start(WT_SESSION_IMPL *session) uint32_t i, session_flags; conn = S2C(session); - conn->async_cfg = 1; + conn->async_cfg = true; /* * Async is on, allocate the WT_ASYNC structure and initialize the ops. */ @@ -339,16 +339,16 @@ __wt_async_reconfig(WT_SESSION_IMPL *session, const char *cfg[]) * 2. If async is off, and the user wants it on, start it. * 3. If not a toggle and async is off, we're done. */ - if (conn->async_cfg > 0 && !run) { + if (conn->async_cfg && !run) { /* Case 1 */ WT_TRET(__wt_async_flush(session)); ret = __wt_async_destroy(session); - conn->async_cfg = 0; + conn->async_cfg = false; return (ret); - } else if (conn->async_cfg == 0 && run) + } else if (!conn->async_cfg && run) /* Case 2 */ return (__async_start(session)); - else if (conn->async_cfg == 0) + else if (!conn->async_cfg) /* Case 3 */ return (0); @@ -599,7 +599,8 @@ __wt_async_new_op(WT_SESSION_IMPL *session, const char *uri, conn = S2C(session); if (!conn->async_cfg) - return (ENOTSUP); + WT_RET_MSG( + session, ENOTSUP, "Asynchronous operations not configured"); op = NULL; WT_ERR(__async_new_op_alloc(session, uri, config, &op)); diff --git a/src/block/block_ext.c b/src/block/block_ext.c index b02fea8707d..26acc8c560f 100644 --- a/src/block/block_ext.c +++ b/src/block/block_ext.c @@ -344,7 +344,8 @@ __block_off_remove(WT_SESSION_IMPL *session, WT_BLOCK *block, __block_size_srch(el->sz, ext->size, sstack); szp = *sstack[0]; if (szp == NULL || szp->size != ext->size) - return (EINVAL); + WT_PANIC_RET(session, EINVAL, + "extent not found in by-size list during remove"); __block_off_srch(szp->off, off, astack, true); ext = *astack[0]; if (ext == NULL || ext->off != off) diff --git a/src/bloom/bloom.c b/src/bloom/bloom.c index 3afada05dda..dde08d8a982 100644 --- a/src/bloom/bloom.c +++ b/src/bloom/bloom.c @@ -65,7 +65,9 @@ __bloom_setup( WT_BLOOM *bloom, uint64_t n, uint64_t m, uint32_t factor, uint32_t k) { if (k < 2) - return (EINVAL); + WT_RET_MSG(bloom->session, EINVAL, + "bloom filter hash values to be set/tested must be " + "greater than 2"); bloom->k = k; bloom->factor = factor; @@ -342,7 +344,12 @@ __wt_bloom_intersection(WT_BLOOM *bloom, WT_BLOOM *other) if (bloom->k != other->k || bloom->factor != other->factor || bloom->m != other->m || bloom->n != other->n) - return (EINVAL); + WT_RET_MSG(bloom->session, EINVAL, + "bloom filter intersection configuration mismatch: (" + "%" PRIu32 "/%" PRIu32 ", %" PRIu32 "/%" PRIu32 ", " + "%" PRIu64 "/%" PRIu64 ", %" PRIu64 "/%" PRIu64 ")", + bloom->k, other->k, bloom->factor, other->factor, + bloom->m, other->m, bloom->n, other->n); nbytes = __bitstr_size(bloom->m); for (i = 0; i < nbytes; i++) diff --git a/src/btree/bt_cursor.c b/src/btree/bt_cursor.c index 41ae457b0fe..0454ea7c20e 100644 --- a/src/btree/bt_cursor.c +++ b/src/btree/bt_cursor.c @@ -37,21 +37,20 @@ __cursor_size_chk(WT_SESSION_IMPL *session, WT_ITEM *kv) if (kv->size <= WT_GIGABYTE) return (0); - /* - * There are two checks: what we are willing to store in the tree, and - * what the block manager can actually write. - */ + /* Check what we are willing to store in the tree. */ if (kv->size > WT_BTREE_MAX_OBJECT_SIZE) - ret = EINVAL; - else { - size = kv->size; - ret = bm->write_size(bm, session, &size); - } - if (ret != 0) - WT_RET_MSG(session, ret, + WT_RET_MSG(session, EINVAL, "item size of %" WT_SIZET_FMT " exceeds the maximum " - "supported size", + "supported WiredTiger size of %d", + kv->size, WT_BTREE_MAX_OBJECT_SIZE); + + /* Check what the block manager can actually write. */ + size = kv->size; + if ((ret = bm->write_size(bm, session, &size)) != 0) + WT_RET_MSG(session, ret, + "item size of %" WT_SIZET_FMT " refused by block manager", kv->size); + return (0); } @@ -858,7 +857,8 @@ __wt_btcur_next_random(WT_CURSOR_BTREE *cbt) * value from a column-store, if there were any reason to do so. */ if (btree->type != BTREE_ROW) - WT_RET(ENOTSUP); + WT_RET_MSG(session, ENOTSUP, + "WT_CURSOR.next_random only supported by row-store tables"); WT_STAT_CONN_INCR(session, cursor_next); WT_STAT_DATA_INCR(session, cursor_next); diff --git a/src/config/config_api.c b/src/config/config_api.c index 8820b81a410..76a51903588 100644 --- a/src/config/config_api.c +++ b/src/config/config_api.c @@ -19,9 +19,6 @@ __config_parser_close(WT_CONFIG_PARSER *wt_config_parser) config_parser = (WT_CONFIG_PARSER_IMPL *)wt_config_parser; - if (config_parser == NULL) - return (EINVAL); - __wt_free(config_parser->session, config_parser); return (0); } @@ -38,9 +35,6 @@ __config_parser_get(WT_CONFIG_PARSER *wt_config_parser, config_parser = (WT_CONFIG_PARSER_IMPL *)wt_config_parser; - if (config_parser == NULL) - return (EINVAL); - return (__wt_config_subgets(config_parser->session, &config_parser->config_item, key, cval)); } @@ -57,9 +51,6 @@ __config_parser_next(WT_CONFIG_PARSER *wt_config_parser, config_parser = (WT_CONFIG_PARSER_IMPL *)wt_config_parser; - if (config_parser == NULL) - return (EINVAL); - return (__wt_config_next(&config_parser->config, key, cval)); } diff --git a/src/config/config_check.c b/src/config/config_check.c index d0aa09a96c1..2f372651cb9 100644 --- a/src/config/config_check.c +++ b/src/config/config_check.c @@ -128,8 +128,7 @@ config_check(WT_SESSION_IMPL *session, badtype = false; } else WT_RET_MSG(session, EINVAL, - "unknown configuration type: '%s'", - checks[i].type); + "unknown configuration type: '%s'", checks[i].type); if (badtype) WT_RET_MSG(session, EINVAL, diff --git a/src/conn/conn_api.c b/src/conn/conn_api.c index 04c29e957a3..a6e0f57f02e 100644 --- a/src/conn/conn_api.c +++ b/src/conn/conn_api.c @@ -1451,7 +1451,7 @@ __conn_single(WT_SESSION_IMPL *session, const char *cfg[]) WT_FH *fh; size_t len; wt_off_t size; - bool bytelock, exist, is_create; + bool bytelock, exist, is_create, match; char buf[256]; conn = S2C(session); @@ -1477,13 +1477,14 @@ __conn_single(WT_SESSION_IMPL *session, const char *cfg[]) * won't open a database in multiple threads, but we don't want to have * it fail the first time, but succeed the second. */ + match = false; TAILQ_FOREACH(t, &__wt_process.connqh, q) if (t->home != NULL && t != conn && strcmp(t->home, conn->home) == 0) { - ret = EBUSY; + match = true; break; } - if (ret != 0) + if (match) WT_ERR_MSG(session, EBUSY, "WiredTiger database is already being managed by another " "thread in this process"); diff --git a/src/conn/conn_log.c b/src/conn/conn_log.c index 34743034877..8198b3a1a02 100644 --- a/src/conn/conn_log.c +++ b/src/conn/conn_log.c @@ -87,14 +87,16 @@ __logmgr_config( if (reconfig && ((enabled && !FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)) || (!enabled && FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)))) - return (EINVAL); + WT_RET_MSG(session, EINVAL, + "log manager reconfigure: enabled mismatch with existing " + "setting"); /* Logging is incompatible with in-memory */ if (enabled) { WT_RET(__wt_config_gets(session, cfg, "in_memory", &cval)); if (cval.val != 0) WT_RET_MSG(session, EINVAL, - "In memory configuration incompatible with " + "In-memory configuration incompatible with " "log=(enabled=true)"); } @@ -137,8 +139,7 @@ __logmgr_config( if (!reconfig) { WT_RET(__wt_config_gets(session, cfg, "log.file_max", &cval)); conn->log_file_max = (wt_off_t)cval.val; - WT_STAT_CONN_SET(session, - log_max_filesize, conn->log_file_max); + WT_STAT_CONN_SET(session, log_max_filesize, conn->log_file_max); } /* diff --git a/src/cursor/cur_index.c b/src/cursor/cur_index.c index ea742cac435..eb5e15ae5c3 100644 --- a/src/cursor/cur_index.c +++ b/src/cursor/cur_index.c @@ -38,7 +38,9 @@ __curindex_set_value(WT_CURSOR *cursor, ...) WT_SESSION_IMPL *session; JOINABLE_CURSOR_API_CALL(cursor, session, set_value, NULL); - ret = ENOTSUP; + WT_ERR_MSG(session, ENOTSUP, + "WT_CURSOR.set_value not supported for index cursors"); + err: cursor->saved_err = ret; F_CLR(cursor, WT_CURSTD_VALUE_SET); API_END(session, ret); diff --git a/src/cursor/cur_join.c b/src/cursor/cur_join.c index 88eecfddef8..8936c6e3563 100644 --- a/src/cursor/cur_join.c +++ b/src/cursor/cur_join.c @@ -38,8 +38,8 @@ __wt_curjoin_joined(WT_CURSOR *cursor) WT_SESSION_IMPL *session; session = (WT_SESSION_IMPL *)cursor->session; - __wt_errx(session, "cursor is being used in a join"); - return (ENOTSUP); + + WT_RET_MSG(session, ENOTSUP, "cursor is being used in a join"); } /* @@ -1304,11 +1304,15 @@ __wt_curjoin_open(WT_SESSION_IMPL *session, WT_STATIC_ASSERT(offsetof(WT_CURSOR_JOIN, iface) == 0); + if (owner != NULL) + WT_RET_MSG(session, EINVAL, + "unable to initialize a join cursor with existing owner"); + if (!WT_PREFIX_SKIP(uri, "join:")) - return (EINVAL); + return (__wt_unexpected_object_type(session, uri, "join:")); tablename = uri; if (!WT_PREFIX_SKIP(tablename, "table:")) - return (EINVAL); + return (__wt_unexpected_object_type(session, uri, "table:")); columns = strchr(tablename, '('); if (columns == NULL) @@ -1336,9 +1340,6 @@ __wt_curjoin_open(WT_SESSION_IMPL *session, WT_ERR(__wt_strdup(session, columns, &cjoin->projection)); } - if (owner != NULL) - WT_ERR(EINVAL); - WT_ERR(__wt_cursor_init(cursor, uri, owner, cfg, cursorp)); if (0) { diff --git a/src/cursor/cur_json.c b/src/cursor/cur_json.c index bb24e88cba5..093ec3c59ac 100644 --- a/src/cursor/cur_json.c +++ b/src/cursor/cur_json.c @@ -492,11 +492,9 @@ __wt_json_token(WT_SESSION *wt_session, const char *src, int *toktype, uc = (const u_char *)src; if (__wt_hex2byte(&uc[1], &ignored) || - __wt_hex2byte(&uc[3], &ignored)) { - __wt_errx(session, + __wt_hex2byte(&uc[3], &ignored)) + WT_RET_MSG(session, EINVAL, "invalid Unicode within JSON string"); - return (-1); - } src += 4; } backslash = false; @@ -569,7 +567,10 @@ __wt_json_token(WT_SESSION *wt_session, const char *src, int *toktype, } *toklen = (size_t)(src - *tokstart); *toktype = result; - return (result < 0 ? EINVAL : 0); + + if (result < 0) + WT_RET_MSG(session, EINVAL, "illegal token in JSON"); + return (0); } /* @@ -606,24 +607,20 @@ __wt_json_tokname(int toktype) static int json_string_arg(WT_SESSION_IMPL *session, const char **jstr, WT_ITEM *item) { - WT_DECL_RET; int tok; const char *tokstart; - WT_RET(__wt_json_token((WT_SESSION *)session, *jstr, &tok, &tokstart, - &item->size)); + WT_RET(__wt_json_token( + (WT_SESSION *)session, *jstr, &tok, &tokstart, &item->size)); if (tok == 's') { *jstr = tokstart + item->size; /* The tokenizer includes the '"' chars */ item->data = tokstart + 1; item->size -= 2; - ret = 0; - } else { - __wt_errx(session, "expected JSON <string>, got %s", - __wt_json_tokname(tok)); - ret = EINVAL; - } - return (ret); + } else + WT_RET_MSG(session, EINVAL, + "expected JSON <string>, got %s", __wt_json_tokname(tok)); + return (0); } /* @@ -648,11 +645,9 @@ json_int_arg(WT_SESSION_IMPL *session, const char **jstr, int64_t *ip) WT_RET_MSG(session, EINVAL, "JSON <int> extraneous input"); *jstr = tokstart + toksize; - } else { - __wt_errx(session, "expected JSON <int>, got %s", - __wt_json_tokname(tok)); - return (EINVAL); - } + } else + WT_RET_MSG(session, EINVAL, + "expected JSON <int>, got %s", __wt_json_tokname(tok)); return (0); } @@ -678,22 +673,20 @@ json_uint_arg(WT_SESSION_IMPL *session, const char **jstr, uint64_t *up) WT_RET_MSG(session, EINVAL, "JSON <int> extraneous input"); *jstr = tokstart + toksize; - } else { - __wt_errx(session, "expected unsigned JSON <int>, got %s", + } else + WT_RET_MSG(session, EINVAL, + "expected unsigned JSON <int>, got %s", __wt_json_tokname(tok)); - return (EINVAL); - } return (0); } #define JSON_EXPECT_TOKEN_GET(session, jstr, tokval, start, sz) do { \ int __tok; \ WT_RET(__wt_json_token((WT_SESSION *)session, jstr, &__tok, &start, &sz));\ - if (__tok != tokval) { \ - __wt_errx(session, "expected JSON %s, got %s", \ + if (__tok != tokval) \ + WT_RET_MSG(session, EINVAL, \ + "expected JSON %s, got %s", \ __wt_json_tokname(tokval), __wt_json_tokname(__tok)); \ - return (EINVAL); \ - } \ jstr = start + sz; \ } while (0) @@ -782,11 +775,10 @@ __json_pack_size( JSON_EXPECT_TOKEN_GET(session, jstr, 's', tokstart, toksize); WT_RET(__pack_name_next(&packname, &name)); if (toksize - 2 != name.len || - strncmp(tokstart + 1, name.str, toksize - 2) != 0) { - __wt_errx(session, "JSON expected %s name: \"%.*s\"", + strncmp(tokstart + 1, name.str, toksize - 2) != 0) + WT_RET_MSG(session, EINVAL, + "JSON expected %s name: \"%.*s\"", iskey ? "key" : "value", (int)name.len, name.str); - return (EINVAL); - } JSON_EXPECT_TOKEN(session, jstr, ':'); WT_PACK_JSON_GET(session, pv, jstr); total += __pack_size(session, &pv); @@ -861,9 +853,8 @@ __wt_json_strlen(const char *src, size_t srclen) /* * __wt_json_strncpy -- - * Copy bytes of string in JSON format to a destination, - * up to dstlen bytes. If dstlen is greater than the needed size, - * the result if zero padded. + * Copy bytes of string in JSON format to a destination, up to dstlen + * bytes. If dstlen is greater than the needed size, the result if zero padded. */ int __wt_json_strncpy(WT_SESSION *wt_session, char **pdst, size_t dstlen, @@ -884,18 +875,16 @@ __wt_json_strncpy(WT_SESSION *wt_session, char **pdst, size_t dstlen, if ((ch = *src++) == '\\') switch (ch = *src++) { case 'u': - if (__wt_hex2byte((const u_char *)src, &hi)) - return (EINVAL); - src += 2; - if (__wt_hex2byte((const u_char *)src, &lo)) - return (EINVAL); - src += 2; - if (hi != 0) { - __wt_errx(NULL, "Unicode \"%6.6s\"" - " byte out of range in JSON", + if (__wt_hex2byte((const u_char *)src, &hi) || + __wt_hex2byte((const u_char *)src + 2, &lo)) + WT_RET_MSG(session, EINVAL, + "invalid Unicode within JSON string"); + src += 4; + if (hi != 0) + WT_RET_MSG(session, EINVAL, + "Unicode \"%6.6s\" byte out of " + "range in JSON", src - 6); - return (EINVAL); - } *dst++ = (char)lo; break; case 'f': @@ -920,7 +909,8 @@ __wt_json_strncpy(WT_SESSION *wt_session, char **pdst, size_t dstlen, *dst++ = ch; } if (src != srcend) - return (ENOMEM); + WT_RET_MSG(session, + ENOMEM, "JSON string copy destination buffer too small"); *pdst = dst; while (dst < dstend) *dst++ = '\0'; diff --git a/src/cursor/cur_metadata.c b/src/cursor/cur_metadata.c index fd00acdf0ab..10e2fdf28be 100644 --- a/src/cursor/cur_metadata.c +++ b/src/cursor/cur_metadata.c @@ -48,7 +48,10 @@ __schema_source_config(WT_SESSION_IMPL *session, WT_ERR(__wt_buf_fmt(session, buf, "%.*s", (int)cval.len, cval.str)); srch->set_key(srch, buf->data); if ((ret = srch->search(srch)) == WT_NOTFOUND) - WT_ERR(EINVAL); + WT_ERR_MSG(session, EINVAL, + "metadata information for source configuration \"%s\" " + "not found", + (char *)buf->data); WT_ERR(ret); WT_ERR(srch->get_value(srch, &v)); WT_ERR(__wt_strdup(session, v, result)); diff --git a/src/cursor/cur_stat.c b/src/cursor/cur_stat.c index b36416debe1..5fde64c74ca 100644 --- a/src/cursor/cur_stat.c +++ b/src/cursor/cur_stat.c @@ -383,7 +383,8 @@ __curstat_file_init(WT_SESSION_IMPL *session, if (F_ISSET(cst, WT_STAT_TYPE_SIZE)) { filename = uri; if (!WT_PREFIX_SKIP(filename, "file:")) - return (EINVAL); + return ( + __wt_unexpected_object_type(session, uri, "file:")); __wt_stat_dsrc_init_single(&cst->u.dsrc_stats); WT_RET(__wt_block_manager_named_size(session, filename, &size)); cst->u.dsrc_stats.block_size = size; diff --git a/src/cursor/cur_table.c b/src/cursor/cur_table.c index 6543d54e90f..502d93639a8 100644 --- a/src/cursor/cur_table.c +++ b/src/cursor/cur_table.c @@ -892,7 +892,7 @@ __wt_curtable_open(WT_SESSION_IMPL *session, tablename = uri; if (!WT_PREFIX_SKIP(tablename, "table:")) - return (EINVAL); + return (__wt_unexpected_object_type(session, uri, "table:")); columns = strchr(tablename, '('); if (columns == NULL) size = strlen(tablename); diff --git a/src/include/btree.i b/src/include/btree.i index daf2eb158c1..e48189d50ea 100644 --- a/src/include/btree.i +++ b/src/include/btree.i @@ -1425,9 +1425,11 @@ __wt_page_swap_func( * page not having been released, and that's not the case. */ if (LF_ISSET(WT_READ_NOTFOUND_OK) && ret == WT_NOTFOUND) - return (EINVAL); + WT_RET_MSG(session, + EINVAL, "page-release WT_NOTFOUND error mapped to EINVAL"); if (LF_ISSET(WT_READ_RESTART_OK) && ret == WT_RESTART) - return (EINVAL); + WT_RET_MSG(session, + EINVAL, "page-release WT_RESTART error mapped to EINVAL"); return (ret); } diff --git a/src/include/connection.h b/src/include/connection.h index 4e8e88bf6e4..7d3d07a6abc 100644 --- a/src/include/connection.h +++ b/src/include/connection.h @@ -293,7 +293,7 @@ struct __wt_connection_impl { WT_CONNECTION_STATS *stat_array; WT_ASYNC *async; /* Async structure */ - int async_cfg; /* Global async configuration */ + bool async_cfg; /* Global async configuration */ uint32_t async_size; /* Async op array size */ uint32_t async_workers; /* Number of async workers */ diff --git a/src/include/extern.h b/src/include/extern.h index da5f78bb526..69140d87eaa 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -638,6 +638,7 @@ extern int __wt_panic(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((cold extern int __wt_illegal_value(WT_SESSION_IMPL *session, const char *name) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_object_unsupported(WT_SESSION_IMPL *session, const char *uri) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_bad_object_type(WT_SESSION_IMPL *session, const char *uri) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_unexpected_object_type( WT_SESSION_IMPL *session, const char *uri, const char *expect) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_library_init(void) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_breakpoint(void); extern void __wt_attach(WT_SESSION_IMPL *session); @@ -745,7 +746,7 @@ extern int __wt_ext_transaction_visible( WT_EXTENSION_API *wt_api, WT_SESSION *w extern void __wt_txn_op_free(WT_SESSION_IMPL *session, WT_TXN_OP *op); extern int __wt_txn_log_op(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_log_commit(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern int __wt_txn_checkpoint_logread( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, WT_LSN *ckpt_lsn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_checkpoint_logread(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, WT_LSN *ckpt_lsn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_checkpoint_log( WT_SESSION_IMPL *session, bool full, uint32_t flags, WT_LSN *lsnp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_truncate_log( WT_SESSION_IMPL *session, WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_txn_truncate_end(WT_SESSION_IMPL *session); diff --git a/src/log/log_auto.c b/src/log/log_auto.c index 34bccd0ede4..c2b38184405 100644 --- a/src/log/log_auto.c +++ b/src/log/log_auto.c @@ -119,11 +119,13 @@ __wt_logop_col_put_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, uint64_t *recnop, WT_ITEM *valuep) { + WT_DECL_RET; const char *fmt = WT_UNCHECKED_STRING(IIIru); uint32_t optype, size; - WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, - &optype, &size, fileidp, recnop, valuep)); + if ((ret = __wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, + &optype, &size, fileidp, recnop, valuep)) != 0) + WT_RET_MSG(session, ret, "logop_col_put: unpack failure"); WT_ASSERT(session, optype == WT_LOGOP_COL_PUT); *pp += size; @@ -192,11 +194,13 @@ __wt_logop_col_remove_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, uint64_t *recnop) { + WT_DECL_RET; const char *fmt = WT_UNCHECKED_STRING(IIIr); uint32_t optype, size; - WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, - &optype, &size, fileidp, recnop)); + if ((ret = __wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, + &optype, &size, fileidp, recnop)) != 0) + WT_RET_MSG(session, ret, "logop_col_remove: unpack failure"); WT_ASSERT(session, optype == WT_LOGOP_COL_REMOVE); *pp += size; @@ -252,11 +256,13 @@ __wt_logop_col_truncate_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, uint64_t *startp, uint64_t *stopp) { + WT_DECL_RET; const char *fmt = WT_UNCHECKED_STRING(IIIrr); uint32_t optype, size; - WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, - &optype, &size, fileidp, startp, stopp)); + if ((ret = __wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, + &optype, &size, fileidp, startp, stopp)) != 0) + WT_RET_MSG(session, ret, "logop_col_truncate: unpack failure"); WT_ASSERT(session, optype == WT_LOGOP_COL_TRUNCATE); *pp += size; @@ -315,11 +321,13 @@ __wt_logop_row_put_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, WT_ITEM *keyp, WT_ITEM *valuep) { + WT_DECL_RET; const char *fmt = WT_UNCHECKED_STRING(IIIuu); uint32_t optype, size; - WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, - &optype, &size, fileidp, keyp, valuep)); + if ((ret = __wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, + &optype, &size, fileidp, keyp, valuep)) != 0) + WT_RET_MSG(session, ret, "logop_row_put: unpack failure"); WT_ASSERT(session, optype == WT_LOGOP_ROW_PUT); *pp += size; @@ -394,11 +402,13 @@ __wt_logop_row_remove_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, WT_ITEM *keyp) { + WT_DECL_RET; const char *fmt = WT_UNCHECKED_STRING(IIIu); uint32_t optype, size; - WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, - &optype, &size, fileidp, keyp)); + if ((ret = __wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, + &optype, &size, fileidp, keyp)) != 0) + WT_RET_MSG(session, ret, "logop_row_remove: unpack failure"); WT_ASSERT(session, optype == WT_LOGOP_ROW_REMOVE); *pp += size; @@ -464,11 +474,13 @@ __wt_logop_row_truncate_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, WT_ITEM *startp, WT_ITEM *stopp, uint32_t *modep) { + WT_DECL_RET; const char *fmt = WT_UNCHECKED_STRING(IIIuuI); uint32_t optype, size; - WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, - &optype, &size, fileidp, startp, stopp, modep)); + if ((ret = __wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, + &optype, &size, fileidp, startp, stopp, modep)) != 0) + WT_RET_MSG(session, ret, "logop_row_truncate: unpack failure"); WT_ASSERT(session, optype == WT_LOGOP_ROW_TRUNCATE); *pp += size; diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c index 067c527a21a..c20673563d9 100644 --- a/src/lsm/lsm_cursor.c +++ b/src/lsm/lsm_cursor.c @@ -1678,7 +1678,7 @@ __wt_clsm_open(WT_SESSION_IMPL *session, lsm_tree = NULL; if (!WT_PREFIX_MATCH(uri, "lsm:")) - return (EINVAL); + return (__wt_unexpected_object_type(session, uri, "lsm:")); if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) WT_RET_MSG(session, EINVAL, diff --git a/src/schema/schema_create.c b/src/schema/schema_create.c index ed88e687a19..020d5e72c13 100644 --- a/src/schema/schema_create.c +++ b/src/schema/schema_create.c @@ -70,7 +70,7 @@ __create_file(WT_SESSION_IMPL *session, filename = uri; if (!WT_PREFIX_SKIP(filename, "file:")) - WT_RET_MSG(session, EINVAL, "Expected a 'file:' URI: %s", uri); + return (__wt_unexpected_object_type(session, uri, "file:")); /* Check if the file already exists. */ if (!is_metadata && (ret = @@ -193,7 +193,8 @@ __create_colgroup(WT_SESSION_IMPL *session, tablename = name; if (!WT_PREFIX_SKIP(tablename, "colgroup:")) - return (EINVAL); + return ( + __wt_unexpected_object_type(session, name, "colgroup:")); cgname = strchr(tablename, ':'); if (cgname != NULL) { tlen = (size_t)(cgname - tablename); @@ -384,7 +385,7 @@ __create_index(WT_SESSION_IMPL *session, tablename = name; if (!WT_PREFIX_SKIP(tablename, "index:")) - return (EINVAL); + return (__wt_unexpected_object_type(session, name, "index:")); idxname = strchr(tablename, ':'); if (idxname == NULL) WT_RET_MSG(session, EINVAL, "Invalid index name, " @@ -570,7 +571,7 @@ __create_table(WT_SESSION_IMPL *session, tablename = name; if (!WT_PREFIX_SKIP(tablename, "table:")) - return (EINVAL); + return (__wt_unexpected_object_type(session, name, "table:")); if ((ret = __wt_schema_get_table(session, tablename, strlen(tablename), false, &table)) == 0) { diff --git a/src/schema/schema_drop.c b/src/schema/schema_drop.c index 96bd3452e1f..65c955cf1e9 100644 --- a/src/schema/schema_drop.c +++ b/src/schema/schema_drop.c @@ -26,7 +26,7 @@ __drop_file( filename = uri; if (!WT_PREFIX_SKIP(filename, "file:")) - return (EINVAL); + return (__wt_unexpected_object_type(session, uri, "file:")); WT_RET(__wt_schema_backup_check(session, filename)); /* Close all btree handles associated with this file. */ diff --git a/src/schema/schema_rename.c b/src/schema/schema_rename.c index 8b3660c61e6..f512482c162 100644 --- a/src/schema/schema_rename.c +++ b/src/schema/schema_rename.c @@ -24,10 +24,11 @@ __rename_file( newvalue = oldvalue = NULL; filename = uri; + if (!WT_PREFIX_SKIP(filename, "file:")) + return (__wt_unexpected_object_type(session, uri, "file:")); newfile = newuri; - if (!WT_PREFIX_SKIP(filename, "file:") || - !WT_PREFIX_SKIP(newfile, "file:")) - return (EINVAL); + if (!WT_PREFIX_SKIP(newfile, "file:")) + return (__wt_unexpected_object_type(session, newuri, "file:")); WT_RET(__wt_schema_backup_check(session, filename)); WT_RET(__wt_schema_backup_check(session, newfile)); diff --git a/src/session/session_api.c b/src/session/session_api.c index fbf171dcfc1..3afea383b08 100644 --- a/src/session/session_api.c +++ b/src/session/session_api.c @@ -920,8 +920,7 @@ __session_join(WT_SESSION *wt_session, WT_CURSOR *join_cursor, "table for join cursor does not match table for " "ref_cursor"); if (F_ISSET(ref_cursor, WT_CURSTD_JOINED)) - WT_ERR_MSG(session, EINVAL, - "cursor already used in a join"); + WT_ERR_MSG(session, EINVAL, "cursor already used in a join"); /* "ge" is the default */ range = WT_CURJOIN_END_GT | WT_CURJOIN_END_EQ; @@ -937,7 +936,9 @@ __session_join(WT_SESSION *wt_session, WT_CURSOR *join_cursor, else if (WT_STRING_MATCH("eq", cval.str, cval.len)) range = WT_CURJOIN_END_EQ; else if (!WT_STRING_MATCH("ge", cval.str, cval.len)) - WT_ERR(EINVAL); + WT_ERR_MSG(session, EINVAL, + "compare=%.*s not supported", + (int)cval.len, cval.str); } WT_ERR(__wt_config_gets(session, cfg, "count", &cval)); if (cval.len != 0) @@ -948,12 +949,13 @@ __session_join(WT_SESSION *wt_session, WT_CURSOR *join_cursor, if (WT_STRING_MATCH("bloom", cval.str, cval.len)) LF_SET(WT_CURJOIN_ENTRY_BLOOM); else if (!WT_STRING_MATCH("default", cval.str, cval.len)) - WT_ERR(EINVAL); + WT_ERR_MSG(session, EINVAL, + "strategy=%.*s not supported", + (int)cval.len, cval.str); } WT_ERR(__wt_config_gets(session, cfg, "bloom_bit_count", &cval)); if ((uint64_t)cval.val > UINT32_MAX) - WT_ERR_MSG(session, EINVAL, - "bloom_bit_count: value too large"); + WT_ERR_MSG(session, EINVAL, "bloom_bit_count: value too large"); bloom_bit_count = (uint32_t)cval.val; WT_ERR(__wt_config_gets(session, cfg, "bloom_hash_count", &cval)); if ((uint64_t)cval.val > UINT32_MAX) @@ -1011,7 +1013,9 @@ __session_salvage(WT_SESSION *wt_session, const char *uri, const char *config) SESSION_API_CALL(session, salvage, config, cfg); if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) - WT_ERR(ENOTSUP); + WT_ERR_MSG(session, ENOTSUP, + "WT_SESSION.salvage not supported for in-memory " + "configurations"); /* Block out checkpoints to avoid spurious EBUSY errors. */ WT_WITH_CHECKPOINT_LOCK(session, ret, @@ -1315,7 +1319,9 @@ __session_verify(WT_SESSION *wt_session, const char *uri, const char *config) SESSION_API_CALL(session, verify, config, cfg); if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) - WT_ERR(ENOTSUP); + WT_ERR_MSG(session, ENOTSUP, + "WT_SESSION.verify not supported for in-memory " + "configurations"); /* Block out checkpoints to avoid spurious EBUSY errors. */ WT_WITH_CHECKPOINT_LOCK(session, ret, @@ -1560,7 +1566,9 @@ __session_checkpoint(WT_SESSION *wt_session, const char *config) SESSION_API_CALL(session, checkpoint, config, cfg); if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) - WT_ERR(ENOTSUP); + WT_ERR_MSG(session, ENOTSUP, + "WT_SESSION.checkpoint not supported for in-memory " + "configurations"); /* * Checkpoints require a snapshot to write a transactionally consistent diff --git a/src/support/err.c b/src/support/err.c index 3ecbab1cbe9..e48225c2c13 100644 --- a/src/support/err.c +++ b/src/support/err.c @@ -562,3 +562,16 @@ __wt_bad_object_type(WT_SESSION_IMPL *session, const char *uri) WT_RET_MSG(session, ENOTSUP, "unknown object type: %s", uri); } + +/* + * __wt_unexpected_object_type -- + * Print a standard error message when given an unexpected object type. + */ +int +__wt_unexpected_object_type( + WT_SESSION_IMPL *session, const char *uri, const char *expect) + WT_GCC_FUNC_ATTRIBUTE((cold)) +{ + WT_RET_MSG(session, + EINVAL, "uri %s doesn't match expected \"%s\"", uri, expect); +} diff --git a/src/support/hazard.c b/src/support/hazard.c index 46b63ac6129..b1978dbe97a 100644 --- a/src/support/hazard.c +++ b/src/support/hazard.c @@ -121,13 +121,11 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref, bool *busyp return (0); } - __wt_errx(session, - "session %p: hazard pointer table full", (void *)session); #ifdef HAVE_DIAGNOSTIC __hazard_dump(session); #endif - - return (ENOMEM); + WT_RET_MSG(session, ENOMEM, + "session %p: hazard pointer table full", (void *)session); } /* diff --git a/src/support/huffman.c b/src/support/huffman.c index 3ec282915ca..afc785b39a9 100644 --- a/src/support/huffman.c +++ b/src/support/huffman.c @@ -823,7 +823,8 @@ __wt_huffman_decode(WT_SESSION_IMPL *session, void *huffman_arg, * where that's not true. */ if (from_len_bits < len) /* corrupted */ - WT_ERR(EINVAL); + WT_ERR_MSG(session, EINVAL, + "huffman decompression detected input corruption"); from_len_bits -= len; WT_ASSERT(session, diff --git a/src/txn/txn_log.c b/src/txn/txn_log.c index f9dd9bee807..f1b78879d76 100644 --- a/src/txn/txn_log.c +++ b/src/txn/txn_log.c @@ -262,20 +262,20 @@ err: __wt_logrec_free(session, &logrec); * Read a log record for a checkpoint operation. */ int -__wt_txn_checkpoint_logread( - WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, - WT_LSN *ckpt_lsn) +__wt_txn_checkpoint_logread(WT_SESSION_IMPL *session, + const uint8_t **pp, const uint8_t *end, WT_LSN *ckpt_lsn) { - WT_ITEM ckpt_snapshot; + WT_DECL_RET; + WT_ITEM ckpt_snapshot_unused; uint32_t ckpt_file, ckpt_offset; - u_int ckpt_nsnapshot; + u_int ckpt_nsnapshot_unused; const char *fmt = WT_UNCHECKED_STRING(IIIU); - WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, + if ((ret = __wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, &ckpt_file, &ckpt_offset, - &ckpt_nsnapshot, &ckpt_snapshot)); - WT_UNUSED(ckpt_nsnapshot); - WT_UNUSED(ckpt_snapshot); + &ckpt_nsnapshot_unused, &ckpt_snapshot_unused)) != 0) + WT_RET_MSG(session, + ret, "txn_checkpoint_logread: unpack failure"); WT_SET_LSN(ckpt_lsn, ckpt_file, ckpt_offset); *pp = end; return (0); diff --git a/src/txn/txn_recover.c b/src/txn/txn_recover.c index ae21e58d9b6..65811aa3bf4 100644 --- a/src/txn/txn_recover.c +++ b/src/txn/txn_recover.c @@ -231,9 +231,12 @@ __txn_op_apply( /* Reset the cursor so it doesn't block eviction. */ if (cursor != NULL) WT_ERR(cursor->reset(cursor)); + return (0); -err: if (ret != 0) - __wt_err(session, ret, "Operation failed during recovery"); +err: __wt_err(session, ret, + "operation apply failed during recovery: operation type %d " + "at LSN %" PRIu32 "/%" PRIu32, + optype, lsnp->l.file, lsnp->l.offset); return (ret); } @@ -263,12 +266,14 @@ __txn_log_recover(WT_SESSION_IMPL *session, WT_ITEM *logrec, WT_LSN *lsnp, WT_LSN *next_lsnp, void *cookie, int firstrecord) { + WT_DECL_RET; WT_RECOVERY *r; - const uint8_t *end, *p; - uint64_t txnid; + uint64_t txnid_unused; uint32_t rectype; + const uint8_t *end, *p; WT_UNUSED(next_lsnp); + r = cookie; p = WT_LOG_SKIP_HEADER(logrec->data); end = (const uint8_t *)logrec->data + logrec->size; @@ -285,8 +290,10 @@ __txn_log_recover(WT_SESSION_IMPL *session, break; case WT_LOGREC_COMMIT: - WT_RET(__wt_vunpack_uint(&p, WT_PTRDIFF(end, p), &txnid)); - WT_UNUSED(txnid); + if ((ret = __wt_vunpack_uint( + &p, WT_PTRDIFF(end, p), &txnid_unused)) != 0) + WT_RET_MSG( + session, ret, "txn_log_recover: unpack failure"); WT_RET(__txn_commit_apply(r, lsnp, &p, end)); break; } diff --git a/test/suite/test_async03.py b/test/suite/test_async03.py index 98851885f70..4859360924a 100644 --- a/test/suite/test_async03.py +++ b/test/suite/test_async03.py @@ -54,12 +54,11 @@ class test_async03(wttest.WiredTigerTestCase): tablearg = 'table:' + self.table_name1 self.session.create(tablearg, 'key_format=S,value_format=S') - # Populate table with async inserts, callback checks - # to ensure key/value is correct. callback = Callback() - self.assertRaises(wiredtiger.WiredTigerError, - lambda: self.conn.async_new_op(tablearg, None, callback)) + msg = '/Asynchronous operations not configured/' + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: self.conn.async_new_op(tablearg, None, callback), msg) self.conn.async_flush() |