Skip to content
This repository has been archived by the owner on Feb 20, 2021. It is now read-only.

Commit

Permalink
Fixed VM corruption due to child fclosing the VM file directly or ind…
Browse files Browse the repository at this point in the history
…irectly calling exit(), now replaced with _exit() in all the sensible places. Masked a few signals from IO threads.
  • Loading branch information
antirez committed Jan 31, 2010
1 parent d5d55fc commit 478c2c6
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
1 change: 1 addition & 0 deletions TODO
Expand Up @@ -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.

Expand Down
28 changes: 18 additions & 10 deletions redis.c
Expand Up @@ -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 ============================== */
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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++;
}

Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 478c2c6

Please sign in to comment.