summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2016-11-07 11:25:56 +1100
committerGitHub <noreply@github.com>2016-11-07 11:25:56 +1100
commit2fe91f73f7def64508c945a7dfaac03fd9e8495c (patch)
tree2d7ce7e25386a9cccadea3c397f770efa8f91ade
parentf418cea41b61f47fda740751495f9f5d39d814fd (diff)
downloadmongo-2fe91f73f7def64508c945a7dfaac03fd9e8495c.tar.gz
WT-2968 Fix a segfault when a drop races with closing a backup cursor. (#3127)
We were clearing the shared pointer to the list of filenames in the backup, then releasing the hotbackup lock before clearing the hotbackup flag. That means drops need to check both the flag and that the pointer is non-NULL.
-rw-r--r--src/schema/schema_util.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/schema/schema_util.c b/src/schema/schema_util.c
index 808a7fc36cf..433224a868e 100644
--- a/src/schema/schema_util.c
+++ b/src/schema/schema_util.c
@@ -27,12 +27,17 @@ __wt_schema_backup_check(WT_SESSION_IMPL *session, const char *name)
if (!conn->hot_backup)
return (0);
__wt_readlock(session, conn->hot_backup_lock);
- if (!conn->hot_backup) {
+ /*
+ * There is a window at the end of a backup where the list has been
+ * cleared from the connection but the flag is still set. It is safe
+ * to drop at that point.
+ */
+ if (!conn->hot_backup ||
+ (backup_list = conn->hot_backup_list) == NULL) {
__wt_readunlock(session, conn->hot_backup_lock);
return (0);
}
- for (i = 0, backup_list = conn->hot_backup_list;
- backup_list[i] != NULL; ++i) {
+ for (i = 0; backup_list[i] != NULL; ++i) {
if (strcmp(backup_list[i], name) == 0) {
ret = EBUSY;
break;