提交 478c2c6f 编写于 作者: A antirez

Fixed VM corruption due to child fclosing the VM file directly or indirectly...

Fixed VM corruption due to child fclosing the VM file directly or indirectly calling exit(), now replaced with _exit() in all the sensible places. Masked a few signals from IO threads.
上级 d5d55fc3
......@@ -18,6 +18,7 @@ Virtual Memory sub-TODO:
* EXISTS should avoid loading the object if possible without too make the code too specialized.
* vm-min-age <seconds> option
* Make sure objects loaded from the VM are specially encoded when possible.
* Check what happens performance-wise if instead to create threads again and again the same threads are reused forever. Note: this requires a way to disable this clients in the child, but waiting for empty new jobs queue can be enough.
* Hashes (GET/SET/DEL/INCRBY/EXISTS/FIELDS/LEN/MSET/MGET). Special encoding for hashes with < N keys.
......
......@@ -221,7 +221,7 @@
#define APPENDFSYNC_EVERYSEC 2
/* We can print the stacktrace, so our assert is defined this way: */
#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),exit(1)))
#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
static void _redisAssert(char *estr, char *file, int line);
/*================================= Data types ============================== */
......@@ -3163,9 +3163,9 @@ static int rdbSaveBackground(char *filename) {
if (server.vm_enabled) vmReopenSwapFile();
close(server.fd);
if (rdbSave(filename) == REDIS_OK) {
exit(0);
_exit(0);
} else {
exit(1);
_exit(1);
}
} else {
/* Parent */
......@@ -6992,9 +6992,9 @@ static int rewriteAppendOnlyFileBackground(void) {
close(server.fd);
snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid());
if (rewriteAppendOnlyFile(tmpfile) == REDIS_OK) {
exit(0);
_exit(0);
} else {
exit(1);
_exit(1);
}
} else {
/* Parent */
......@@ -7315,12 +7315,12 @@ static robj *vmReadObjectFromSwap(off_t page, int type) {
redisLog(REDIS_WARNING,
"Unrecoverable VM problem in vmReadObjectFromSwap(): can't seek: %s",
strerror(errno));
exit(1);
_exit(1);
}
o = rdbLoadObject(type,server.vm_fp);
if (o == NULL) {
redisLog(REDIS_WARNING, "Unrecoverable VM problem in vmReadObjectFromSwap(): can't load object from swap file: %s", strerror(errno));
exit(1);
_exit(1);
}
if (server.vm_enabled) pthread_mutex_unlock(&server.io_swapfile_mutex);
return o;
......@@ -7835,8 +7835,15 @@ static void *IOThreadEntryPoint(void *arg) {
static void spawnIOThread(void) {
pthread_t thread;
sigset_t mask, omask;
sigemptyset(&mask);
sigaddset(&mask,SIGCHLD);
sigaddset(&mask,SIGHUP);
sigaddset(&mask,SIGPIPE);
pthread_sigmask(SIG_SETMASK, &mask, &omask);
pthread_create(&thread,&server.io_threads_attr,IOThreadEntryPoint,NULL);
pthread_sigmask(SIG_SETMASK, &omask, NULL);
server.io_active_threads++;
}
......@@ -7870,12 +7877,13 @@ static void waitEmptyIOJobsQueue(void) {
}
static void vmReopenSwapFile(void) {
fclose(server.vm_fp);
/* Note: we don't close the old one as we are in the child process
* and don't want to mess at all with the original file object. */
server.vm_fp = fopen(server.vm_swap_file,"r+b");
if (server.vm_fp == NULL) {
redisLog(REDIS_WARNING,"Can't re-open the VM swap file: %s. Exiting.",
server.vm_swap_file);
exit(1);
_exit(1);
}
server.vm_fd = fileno(server.vm_fp);
}
......@@ -8299,7 +8307,7 @@ static void segvHandler(int sig, siginfo_t *info, void *secret) {
}
}
/* free(messages); Don't call free() with possibly corrupted memory. */
exit(0);
_exit(0);
}
static void setupSigSegvAction(void) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册