summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSusan LoVerso <sue@mongodb.com>2016-02-16 12:08:59 -0500
committerSusan LoVerso <sue@mongodb.com>2016-02-16 12:08:59 -0500
commit48cbd17938a8016244a863442e7216ed09eca740 (patch)
tree1de9a8c41469cd43b7dd57ad49eaa5b437601c17
parentadb0461954b8cabdec5e745146238bf59c596e33 (diff)
downloadmongo-48cbd17938a8016244a863442e7216ed09eca740.tar.gz
WT-2349 Changes from review comments. Add WT-specific error codes.
-rw-r--r--dist/api_err.py2
-rw-r--r--dist/s_string.ok1
-rw-r--r--src/conn/api_strerror.c2
-rw-r--r--src/conn/conn_api.c81
-rw-r--r--src/docs/spell.ok1
-rw-r--r--src/include/extern.h3
-rw-r--r--src/include/wiredtiger.in4
-rw-r--r--src/lsm/lsm_manager.c1
-rw-r--r--src/os_posix/os_errno.c16
-rw-r--r--src/os_win/os_errno.c22
-rw-r--r--src/session/session_api.c11
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;