[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
(ITS#8350) lmdb SIGBUS error on full partition and possible double free issue
Full_Name: Jeremiah Morrill
Version: 0.9
OS: Linux (Ubuntu14)
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (70.173.183.164)
Two possible issues. Semi-related.
The first:
On a full storage partition, when creating a new database, I get a SIGBUS. I
believe it is caused by the locks successfully mmap()ing, but not really having
the storage to back it. I hacked in a "posix_fallocate" to make sure the
storage space is there and it appeared to fix it. I have no idea what the
unintended consequences of this change may be.
Here is the diff:
void
@@ -4863,6 +4868,14 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode,
int *excl)
void *m = mmap(NULL, rsize, PROT_READ|PROT_WRITE, MAP_SHARED,
env->me_lfd, 0);
if (m == MAP_FAILED) goto fail_errno;
+
+ rc = posix_fallocate(env->me_lfd, 0, rsize);
+
+ if (rc) {
+ munmap(m, rsize);
+ goto fail;
+ }
+
env->me_txns = m;
#endif
}
I'm not sure if this next one is an issue or just incorrect usage on my part.
So take with a grain of salt.
After getting an EIO (deliberate out of storage space) from a mdb_txn_commit,
the transaction would be mdb_txn_abort()ed. I then would close then env which
would get a SIGABORT from a double-free on the env_close0 with env->txn0.
The hack I put in there to avoid this was in the mdb_txn_end. I check if txn ==
env->me_txn0, and if it is, to set env->me_txn0 to NULL.
Here's the diff:
@@ -3244,12 +3244,17 @@ mdb_txn_end(MDB_txn *txn, unsigned mode)
}
pthread_mutex_unlock(&env->me_rpmutex);
tl[0].mid = 0;
- if (mode & MDB_END_FREE)
+ if (mode & MDB_END_FREE)
free(tl);
}
#endif
- if (mode & MDB_END_FREE)
- free(txn);
+ if (mode & MDB_END_FREE) {
+ /* avoid double free on env close */
+ if(txn == env->me_txn0){
+ env->me_txn0 = NULL;
+ }
+ free(txn);
+ }
}