diff options
author | Susan LoVerso <sue@mongodb.com> | 2016-02-16 12:08:59 -0500 |
---|---|---|
committer | Susan LoVerso <sue@mongodb.com> | 2016-02-16 12:08:59 -0500 |
commit | 48cbd17938a8016244a863442e7216ed09eca740 (patch) | |
tree | 1de9a8c41469cd43b7dd57ad49eaa5b437601c17 | |
parent | adb0461954b8cabdec5e745146238bf59c596e33 (diff) | |
download | mongo-48cbd17938a8016244a863442e7216ed09eca740.tar.gz |
WT-2349 Changes from review comments. Add WT-specific error codes.
-rw-r--r-- | dist/api_err.py | 2 | ||||
-rw-r--r-- | dist/s_string.ok | 1 | ||||
-rw-r--r-- | src/conn/api_strerror.c | 2 | ||||
-rw-r--r-- | src/conn/conn_api.c | 81 | ||||
-rw-r--r-- | src/docs/spell.ok | 1 | ||||
-rw-r--r-- | src/include/extern.h | 3 | ||||
-rw-r--r-- | src/include/wiredtiger.in | 4 | ||||
-rw-r--r-- | src/lsm/lsm_manager.c | 1 | ||||
-rw-r--r-- | src/os_posix/os_errno.c | 16 | ||||
-rw-r--r-- | src/os_win/os_errno.c | 22 | ||||
-rw-r--r-- | src/session/session_api.c | 11 |
11 files changed, 100 insertions, 44 deletions
diff --git a/dist/api_err.py b/dist/api_err.py index 09332d508a2..a17c68ee196 100644 --- a/dist/api_err.py +++ b/dist/api_err.py @@ -56,6 +56,8 @@ errors = [ This error is generated when wiredtiger_open is configured to run in-memory, and an insert or update operation requires more than the configured cache size to complete.''', undoc=True), + Error('WT_PERM_DENIED', -31808, + 'permission denied (internal)', undoc=True), ] # Update the #defines in the wiredtiger.in file. diff --git a/dist/s_string.ok b/dist/s_string.ok index 83d8f417c17..179815f5277 100644 --- a/dist/s_string.ok +++ b/dist/s_string.ok @@ -873,6 +873,7 @@ rS rb rbrace rbracket +rdonly rduppo readlock readonly diff --git a/src/conn/api_strerror.c b/src/conn/api_strerror.c index edb11957556..87864f7f4b0 100644 --- a/src/conn/api_strerror.c +++ b/src/conn/api_strerror.c @@ -40,6 +40,8 @@ __wt_wiredtiger_error(int error) return ("WT_RUN_RECOVERY: recovery must be run to continue"); case WT_CACHE_FULL: return ("WT_CACHE_FULL: operation would overflow cache"); + case WT_PERM_DENIED: + return ("WT_PERM_DENIED: permission denied (internal)"); } /* diff --git a/src/conn/conn_api.c b/src/conn/conn_api.c index 79cba904008..40eb7e2b1a9 100644 --- a/src/conn/conn_api.c +++ b/src/conn/conn_api.c @@ -1404,7 +1404,7 @@ __conn_single(WT_SESSION_IMPL *session, const char *cfg[]) WT_FH *fh; size_t len; wt_off_t size; - bool exist, is_create; + bool bytelock, exist, is_create; char buf[256]; conn = S2C(session); @@ -1416,6 +1416,7 @@ __conn_single(WT_SESSION_IMPL *session, const char *cfg[]) if (F_ISSET(conn, WT_CONN_READONLY)) is_create = false; + bytelock = true; __wt_spin_lock(session, &__wt_process.spinlock); /* @@ -1483,55 +1484,65 @@ __conn_single(WT_SESSION_IMPL *session, const char *cfg[]) * XXX Ignoring the error does allow multiple read-only * connections to exist at the same time on a read-only directory. */ - if (F_ISSET(conn, WT_CONN_READONLY) && - (ret == EACCES || ret == ENOENT)) { + if (F_ISSET(conn, WT_CONN_READONLY)) { /* * If we got an expected permission or non-existence error * then skip the byte lock. */ - ret = 0; - goto open_wt; + ret = __wt_map_error_rdonly(ret); + if (ret == WT_NOTFOUND || ret == WT_PERM_DENIED) { + bytelock = false; + ret = 0; + } } WT_ERR(ret); + if (bytelock) { + /* + * Lock a byte of the file: if we don't get the lock, some other + * process is holding it, we're done. The file may be + * zero-length, and that's OK, the underlying call supports + * locking past the end-of-file. + */ + if (__wt_bytelock(conn->lock_fh, (wt_off_t)0, true) != 0) + WT_ERR_MSG(session, EBUSY, + "WiredTiger database is already being managed by " + "another process"); - /* - * Lock a byte of the file: if we don't get the lock, some other process - * is holding it, we're done. The file may be zero-length, and that's - * OK, the underlying call supports locking past the end-of-file. - */ - if (__wt_bytelock(conn->lock_fh, (wt_off_t)0, true) != 0) - WT_ERR_MSG(session, EBUSY, - "WiredTiger database is already being managed by another " - "process"); - - /* - * If the size of the lock file is non-zero, we created it (or won a - * locking race with the thread that created it, it doesn't matter). - * - * Write something into the file, zero-length files make me nervous. - * - * The test against the expected length is sheer paranoia (the length - * should be 0 or correct), but it shouldn't hurt. - */ + /* + * If the size of the lock file is non-zero, we created it (or + * won a locking race with the thread that created it, it + * doesn't matter). + * + * Write something into the file, zero-length files make me + * nervous. + * + * The test against the expected length is sheer paranoia (the + * length should be 0 or correct), but it shouldn't hurt. + */ #define WT_SINGLETHREAD_STRING "WiredTiger lock file\n" - WT_ERR(__wt_filesize(session, conn->lock_fh, &size)); - if (size != strlen(WT_SINGLETHREAD_STRING)) - WT_ERR(__wt_write(session, conn->lock_fh, (wt_off_t)0, - strlen(WT_SINGLETHREAD_STRING), WT_SINGLETHREAD_STRING)); + WT_ERR(__wt_filesize(session, conn->lock_fh, &size)); + if (size != strlen(WT_SINGLETHREAD_STRING)) + WT_ERR(__wt_write(session, conn->lock_fh, (wt_off_t)0, + strlen(WT_SINGLETHREAD_STRING), + WT_SINGLETHREAD_STRING)); + + } -open_wt: /* We own the lock file, optionally create the WiredTiger file. */ ret = __wt_open(session, WT_WIREDTIGER, is_create, false, 0, &fh); + /* * If we're read-only, check for success as well as handled errors. * Even if we're able to open the WiredTiger file successfully, we - * do not try to lock it. The lock file test for read-only is the - * only one we do. + * do not try to lock it. The lock file test above is the only + * one we do for read-only. */ - if (F_ISSET(conn, WT_CONN_READONLY) && - (ret == 0 || ret == EACCES || ret == ENOENT)) - ret = 0; - else { + if (F_ISSET(conn, WT_CONN_READONLY)) { + ret = __wt_map_error_rdonly(ret); + if (ret == 0 || ret == WT_NOTFOUND || ret == WT_PERM_DENIED) + ret = 0; + WT_ERR(ret); + } else { WT_ERR(ret); /* diff --git a/src/docs/spell.ok b/src/docs/spell.ok index 80597302cbb..39a8c50545d 100644 --- a/src/docs/spell.ok +++ b/src/docs/spell.ok @@ -377,6 +377,7 @@ rVv rdbms rdlock readlock +readonly realclean realloc realloc'd diff --git a/src/include/extern.h b/src/include/extern.h index ed9d8d2fbb2..f4ebda6f42d 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -490,6 +490,7 @@ extern int __wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp extern int __wt_dlsym(WT_SESSION_IMPL *session, WT_DLH *dlh, const char *name, bool fail, void *sym_ret); extern int __wt_dlclose(WT_SESSION_IMPL *session, WT_DLH *dlh); extern int __wt_errno(void); +extern int __wt_map_error_rdonly(int error); extern const char *__wt_strerror(WT_SESSION_IMPL *session, int error, char *errbuf, size_t errlen); extern int __wt_exist(WT_SESSION_IMPL *session, const char *filename, bool *existp); extern void __wt_fallocate_config(WT_SESSION_IMPL *session, WT_FH *fh); @@ -612,7 +613,7 @@ extern WT_DATA_SOURCE *__wt_schema_get_source(WT_SESSION_IMPL *session, const ch extern int __wt_str_name_check(WT_SESSION_IMPL *session, const char *str); extern int __wt_name_check(WT_SESSION_IMPL *session, const char *str, size_t len); extern int __wt_schema_worker(WT_SESSION_IMPL *session, const char *uri, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[], uint32_t open_flags); -extern int __wt_session_notsup_cfg( WT_SESSION *wt_session, const char *config); +extern int __wt_session_notsup_config(WT_SESSION *wt_session, const char *config); extern int __wt_session_notsup_uri( WT_SESSION *wt_session, const char *uri, const char *config); extern int __wt_session_reset_cursors(WT_SESSION_IMPL *session, bool free_buffers); extern int __wt_session_copy_values(WT_SESSION_IMPL *session); diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in index 7d529e728ac..93eb2d4be8f 100644 --- a/src/include/wiredtiger.in +++ b/src/include/wiredtiger.in @@ -3004,6 +3004,10 @@ const char *wiredtiger_version(int *majorp, int *minorp, int *patchp); */ #define WT_CACHE_FULL -31807 /*! @endcond */ +/*! @cond internal */ +/*! Permission denied (internal). */ +#define WT_PERM_DENIED -31808 +/*! @endcond */ /* * Error return section: END * DO NOT EDIT: automatically built by dist/api_err.py. diff --git a/src/lsm/lsm_manager.c b/src/lsm/lsm_manager.c index 6fd96aa2af3..cf581475d2c 100644 --- a/src/lsm/lsm_manager.c +++ b/src/lsm/lsm_manager.c @@ -622,6 +622,7 @@ __wt_lsm_manager_push_entry(WT_SESSION_IMPL *session, manager = &S2C(session)->lsm_manager; + WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_READONLY)); /* * Don't add merges or bloom filter creates if merges * or bloom filters are disabled in the tree. diff --git a/src/os_posix/os_errno.c b/src/os_posix/os_errno.c index a58ae88447e..a0f1202c6ef 100644 --- a/src/os_posix/os_errno.c +++ b/src/os_posix/os_errno.c @@ -23,6 +23,22 @@ __wt_errno(void) } /* + * __wt_map_error_rdonly -- + * Map an error into a WiredTiger error code specific for + * read-only operation which intercepts based on certain types + * of failures. + */ +int +__wt_map_error_rdonly(int error) +{ + if (error == ENOENT) + return (WT_NOTFOUND); + else if (error == EACCES) + return (WT_PERM_DENIED); + return (error); +} + +/* * __wt_strerror -- * POSIX implementation of WT_SESSION.strerror and wiredtiger_strerror. */ diff --git a/src/os_win/os_errno.c b/src/os_win/os_errno.c index 6a9daf8443f..e87d4c59c1b 100644 --- a/src/os_win/os_errno.c +++ b/src/os_win/os_errno.c @@ -17,7 +17,8 @@ static const int windows_error_offset = -29000; * Windows errors are from 0 - 15999 according to the documentation */ static DWORD -__wt_map_error_to_windows_error(int error) { +__wt_map_error_to_windows_error(int error) +{ /* Ensure we do not exceed the error range Also validate he do not get any COM errors (which are negative integers) @@ -32,11 +33,28 @@ __wt_map_error_to_windows_error(int error) { * Return a positive integer, a decoded Windows error */ static int -__wt_map_windows_error_to_error(DWORD winerr) { +__wt_map_windows_error_to_error(DWORD winerr) +{ return (winerr + windows_error_offset); } /* + * __wt_map_error_rdonly -- + * Map an error into a WiredTiger error code specific for + * read-only operation which intercepts based on certain types + * of failures. + */ +int +__wt_map_error_rdonly(int winerr) +{ + if (winerr == ERROR_FILE_NOT_FOUND) + return (WT_NOTFOUND); + else if (winerr == ERROR_ACCESS_DENIED) + return (WT_PERM_DENIED); + return (winerr); +} + +/* * __wt_errno -- * Return errno, or WT_ERROR if errno not set. */ diff --git a/src/session/session_api.c b/src/session/session_api.c index e2723c660fe..abaa369b383 100644 --- a/src/session/session_api.c +++ b/src/session/session_api.c @@ -13,12 +13,11 @@ static int __session_snapshot(WT_SESSION *, const char *); static int __session_rollback_transaction(WT_SESSION *, const char *); /* - * __wt_session_notsup_cfg -- + * __wt_session_notsup_config -- * Unsupported session actions that have a signature of a config string. */ int -__wt_session_notsup_cfg( - WT_SESSION *wt_session, const char *config) +__wt_session_notsup_config(WT_SESSION *wt_session, const char *config) { WT_SESSION_IMPL *session; @@ -1471,9 +1470,9 @@ __open_session(WT_CONNECTION_IMPL *conn, */ if (F_ISSET(conn, WT_CONN_READONLY)) { wt_session = &session_ret->iface; - wt_session->checkpoint = __wt_session_notsup_cfg; - wt_session->log_flush = __wt_session_notsup_cfg; - wt_session->transaction_sync = __wt_session_notsup_cfg; + wt_session->checkpoint = __wt_session_notsup_config; + wt_session->log_flush = __wt_session_notsup_config; + wt_session->transaction_sync = __wt_session_notsup_config; wt_session->compact = __wt_session_notsup_uri; wt_session->create = __wt_session_notsup_uri; |