RM_GetContextFlags provides indication that we're in a fork child (#7783)
This commit is contained in:
parent
dfe9714c86
commit
2458e54814
@ -1603,7 +1603,7 @@ int rewriteAppendOnlyFileBackground(void) {
|
|||||||
if (hasActiveChildProcess()) return C_ERR;
|
if (hasActiveChildProcess()) return C_ERR;
|
||||||
if (aofCreatePipes() != C_OK) return C_ERR;
|
if (aofCreatePipes() != C_OK) return C_ERR;
|
||||||
openChildInfoPipe();
|
openChildInfoPipe();
|
||||||
if ((childpid = redisFork()) == 0) {
|
if ((childpid = redisFork(CHILD_TYPE_AOF)) == 0) {
|
||||||
char tmpfile[256];
|
char tmpfile[256];
|
||||||
|
|
||||||
/* Child */
|
/* Child */
|
||||||
@ -1611,7 +1611,7 @@ int rewriteAppendOnlyFileBackground(void) {
|
|||||||
redisSetCpuAffinity(server.aof_rewrite_cpulist);
|
redisSetCpuAffinity(server.aof_rewrite_cpulist);
|
||||||
snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid());
|
snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid());
|
||||||
if (rewriteAppendOnlyFile(tmpfile) == C_OK) {
|
if (rewriteAppendOnlyFile(tmpfile) == C_OK) {
|
||||||
sendChildCOWInfo(CHILD_INFO_TYPE_AOF, "AOF rewrite");
|
sendChildCOWInfo(CHILD_TYPE_AOF, "AOF rewrite");
|
||||||
exitFromChild(0);
|
exitFromChild(0);
|
||||||
} else {
|
} else {
|
||||||
exitFromChild(1);
|
exitFromChild(1);
|
||||||
|
@ -76,11 +76,11 @@ void receiveChildInfo(void) {
|
|||||||
if (read(server.child_info_pipe[0],&server.child_info_data,wlen) == wlen &&
|
if (read(server.child_info_pipe[0],&server.child_info_data,wlen) == wlen &&
|
||||||
server.child_info_data.magic == CHILD_INFO_MAGIC)
|
server.child_info_data.magic == CHILD_INFO_MAGIC)
|
||||||
{
|
{
|
||||||
if (server.child_info_data.process_type == CHILD_INFO_TYPE_RDB) {
|
if (server.child_info_data.process_type == CHILD_TYPE_RDB) {
|
||||||
server.stat_rdb_cow_bytes = server.child_info_data.cow_size;
|
server.stat_rdb_cow_bytes = server.child_info_data.cow_size;
|
||||||
} else if (server.child_info_data.process_type == CHILD_INFO_TYPE_AOF) {
|
} else if (server.child_info_data.process_type == CHILD_TYPE_AOF) {
|
||||||
server.stat_aof_cow_bytes = server.child_info_data.cow_size;
|
server.stat_aof_cow_bytes = server.child_info_data.cow_size;
|
||||||
} else if (server.child_info_data.process_type == CHILD_INFO_TYPE_MODULE) {
|
} else if (server.child_info_data.process_type == CHILD_TYPE_MODULE) {
|
||||||
server.stat_module_cow_bytes = server.child_info_data.cow_size;
|
server.stat_module_cow_bytes = server.child_info_data.cow_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1991,6 +1991,7 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
|
|||||||
|
|
||||||
/* Presence of children processes. */
|
/* Presence of children processes. */
|
||||||
if (hasActiveChildProcess()) flags |= REDISMODULE_CTX_FLAGS_ACTIVE_CHILD;
|
if (hasActiveChildProcess()) flags |= REDISMODULE_CTX_FLAGS_ACTIVE_CHILD;
|
||||||
|
if (server.in_fork_child) flags |= REDISMODULE_CTX_FLAGS_IS_CHILD;
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
@ -6899,7 +6900,7 @@ int RM_Fork(RedisModuleForkDoneHandler cb, void *user_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openChildInfoPipe();
|
openChildInfoPipe();
|
||||||
if ((childpid = redisFork()) == 0) {
|
if ((childpid = redisFork(CHILD_TYPE_MODULE)) == 0) {
|
||||||
/* Child */
|
/* Child */
|
||||||
redisSetProcTitle("redis-module-fork");
|
redisSetProcTitle("redis-module-fork");
|
||||||
} else if (childpid == -1) {
|
} else if (childpid == -1) {
|
||||||
@ -6919,7 +6920,7 @@ int RM_Fork(RedisModuleForkDoneHandler cb, void *user_data) {
|
|||||||
* retcode will be provided to the done handler executed on the parent process.
|
* retcode will be provided to the done handler executed on the parent process.
|
||||||
*/
|
*/
|
||||||
int RM_ExitFromChild(int retcode) {
|
int RM_ExitFromChild(int retcode) {
|
||||||
sendChildCOWInfo(CHILD_INFO_TYPE_MODULE, "Module fork");
|
sendChildCOWInfo(CHILD_TYPE_MODULE, "Module fork");
|
||||||
exitFromChild(retcode);
|
exitFromChild(retcode);
|
||||||
return REDISMODULE_OK;
|
return REDISMODULE_OK;
|
||||||
}
|
}
|
||||||
|
@ -1385,7 +1385,7 @@ int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {
|
|||||||
server.lastbgsave_try = time(NULL);
|
server.lastbgsave_try = time(NULL);
|
||||||
openChildInfoPipe();
|
openChildInfoPipe();
|
||||||
|
|
||||||
if ((childpid = redisFork()) == 0) {
|
if ((childpid = redisFork(CHILD_TYPE_RDB)) == 0) {
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* Child */
|
/* Child */
|
||||||
@ -1393,7 +1393,7 @@ int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {
|
|||||||
redisSetCpuAffinity(server.bgsave_cpulist);
|
redisSetCpuAffinity(server.bgsave_cpulist);
|
||||||
retval = rdbSave(filename,rsi);
|
retval = rdbSave(filename,rsi);
|
||||||
if (retval == C_OK) {
|
if (retval == C_OK) {
|
||||||
sendChildCOWInfo(CHILD_INFO_TYPE_RDB, "RDB");
|
sendChildCOWInfo(CHILD_TYPE_RDB, "RDB");
|
||||||
}
|
}
|
||||||
exitFromChild((retval == C_OK) ? 0 : 1);
|
exitFromChild((retval == C_OK) ? 0 : 1);
|
||||||
} else {
|
} else {
|
||||||
@ -2561,7 +2561,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
|
|||||||
|
|
||||||
/* Create the child process. */
|
/* Create the child process. */
|
||||||
openChildInfoPipe();
|
openChildInfoPipe();
|
||||||
if ((childpid = redisFork()) == 0) {
|
if ((childpid = redisFork(CHILD_TYPE_RDB)) == 0) {
|
||||||
/* Child */
|
/* Child */
|
||||||
int retval, dummy;
|
int retval, dummy;
|
||||||
rio rdb;
|
rio rdb;
|
||||||
@ -2576,7 +2576,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
|
|||||||
retval = C_ERR;
|
retval = C_ERR;
|
||||||
|
|
||||||
if (retval == C_OK) {
|
if (retval == C_OK) {
|
||||||
sendChildCOWInfo(CHILD_INFO_TYPE_RDB, "RDB");
|
sendChildCOWInfo(CHILD_TYPE_RDB, "RDB");
|
||||||
}
|
}
|
||||||
|
|
||||||
rioFreeFd(&rdb);
|
rioFreeFd(&rdb);
|
||||||
|
@ -112,6 +112,8 @@
|
|||||||
#define REDISMODULE_CTX_FLAGS_ACTIVE_CHILD (1<<18)
|
#define REDISMODULE_CTX_FLAGS_ACTIVE_CHILD (1<<18)
|
||||||
/* The next EXEC will fail due to dirty CAS (touched keys). */
|
/* The next EXEC will fail due to dirty CAS (touched keys). */
|
||||||
#define REDISMODULE_CTX_FLAGS_MULTI_DIRTY (1<<19)
|
#define REDISMODULE_CTX_FLAGS_MULTI_DIRTY (1<<19)
|
||||||
|
/* Redis is currently running inside background child process. */
|
||||||
|
#define REDISMODULE_CTX_FLAGS_IS_CHILD (1<<20)
|
||||||
|
|
||||||
/* Keyspace changes notification classes. Every class is associated with a
|
/* Keyspace changes notification classes. Every class is associated with a
|
||||||
* character for configuration purposes.
|
* character for configuration purposes.
|
||||||
|
@ -1858,7 +1858,7 @@ void ldbSendLogs(void) {
|
|||||||
int ldbStartSession(client *c) {
|
int ldbStartSession(client *c) {
|
||||||
ldb.forked = (c->flags & CLIENT_LUA_DEBUG_SYNC) == 0;
|
ldb.forked = (c->flags & CLIENT_LUA_DEBUG_SYNC) == 0;
|
||||||
if (ldb.forked) {
|
if (ldb.forked) {
|
||||||
pid_t cp = redisFork();
|
pid_t cp = redisFork(CHILD_TYPE_LDB);
|
||||||
if (cp == -1) {
|
if (cp == -1) {
|
||||||
addReplyError(c,"Fork() failed: can't run EVAL in debugging mode.");
|
addReplyError(c,"Fork() failed: can't run EVAL in debugging mode.");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2886,6 +2886,7 @@ void initServer(void) {
|
|||||||
server.aof_state = server.aof_enabled ? AOF_ON : AOF_OFF;
|
server.aof_state = server.aof_enabled ? AOF_ON : AOF_OFF;
|
||||||
server.hz = server.config_hz;
|
server.hz = server.config_hz;
|
||||||
server.pid = getpid();
|
server.pid = getpid();
|
||||||
|
server.in_fork_child = CHILD_TYPE_NONE;
|
||||||
server.main_thread_id = pthread_self();
|
server.main_thread_id = pthread_self();
|
||||||
server.current_client = NULL;
|
server.current_client = NULL;
|
||||||
server.fixed_time_expire = 0;
|
server.fixed_time_expire = 0;
|
||||||
@ -4989,7 +4990,8 @@ void removeSignalHandlers(void) {
|
|||||||
* accepting writes because of a write error condition. */
|
* accepting writes because of a write error condition. */
|
||||||
static void sigKillChildHandler(int sig) {
|
static void sigKillChildHandler(int sig) {
|
||||||
UNUSED(sig);
|
UNUSED(sig);
|
||||||
serverLogFromHandler(LL_WARNING, "Received SIGUSR1 in child, exiting now.");
|
int level = server.in_fork_child == CHILD_TYPE_MODULE? LL_VERBOSE: LL_WARNING;
|
||||||
|
serverLogFromHandler(level, "Received SIGUSR1 in child, exiting now.");
|
||||||
exitFromChild(SERVER_CHILD_NOERROR_RETVAL);
|
exitFromChild(SERVER_CHILD_NOERROR_RETVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5015,11 +5017,13 @@ void closeClildUnusedResourceAfterFork() {
|
|||||||
close(server.cluster_config_file_lock_fd); /* don't care if this fails */
|
close(server.cluster_config_file_lock_fd); /* don't care if this fails */
|
||||||
}
|
}
|
||||||
|
|
||||||
int redisFork() {
|
/* purpose is one of CHILD_TYPE_ types */
|
||||||
|
int redisFork(int purpose) {
|
||||||
int childpid;
|
int childpid;
|
||||||
long long start = ustime();
|
long long start = ustime();
|
||||||
if ((childpid = fork()) == 0) {
|
if ((childpid = fork()) == 0) {
|
||||||
/* Child */
|
/* Child */
|
||||||
|
server.in_fork_child = purpose;
|
||||||
setOOMScoreAdj(CONFIG_OOM_BGCHILD);
|
setOOMScoreAdj(CONFIG_OOM_BGCHILD);
|
||||||
setupChildSignalHandlers();
|
setupChildSignalHandlers();
|
||||||
closeClildUnusedResourceAfterFork();
|
closeClildUnusedResourceAfterFork();
|
||||||
|
11
src/server.h
11
src/server.h
@ -1046,9 +1046,11 @@ struct clusterState;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHILD_INFO_MAGIC 0xC17DDA7A12345678LL
|
#define CHILD_INFO_MAGIC 0xC17DDA7A12345678LL
|
||||||
#define CHILD_INFO_TYPE_RDB 0
|
#define CHILD_TYPE_NONE 0
|
||||||
#define CHILD_INFO_TYPE_AOF 1
|
#define CHILD_TYPE_RDB 1
|
||||||
#define CHILD_INFO_TYPE_MODULE 3
|
#define CHILD_TYPE_AOF 2
|
||||||
|
#define CHILD_TYPE_LDB 3
|
||||||
|
#define CHILD_TYPE_MODULE 4
|
||||||
|
|
||||||
struct redisServer {
|
struct redisServer {
|
||||||
/* General */
|
/* General */
|
||||||
@ -1062,6 +1064,7 @@ struct redisServer {
|
|||||||
the actual 'hz' field value if dynamic-hz
|
the actual 'hz' field value if dynamic-hz
|
||||||
is enabled. */
|
is enabled. */
|
||||||
int hz; /* serverCron() calls frequency in hertz */
|
int hz; /* serverCron() calls frequency in hertz */
|
||||||
|
int in_fork_child; /* indication that this is a fork child */
|
||||||
redisDb *db;
|
redisDb *db;
|
||||||
dict *commands; /* Command table */
|
dict *commands; /* Command table */
|
||||||
dict *orig_commands; /* Command table before command renaming. */
|
dict *orig_commands; /* Command table before command renaming. */
|
||||||
@ -1904,7 +1907,7 @@ void sendChildInfo(int process_type);
|
|||||||
void receiveChildInfo(void);
|
void receiveChildInfo(void);
|
||||||
|
|
||||||
/* Fork helpers */
|
/* Fork helpers */
|
||||||
int redisFork();
|
int redisFork(int type);
|
||||||
int hasActiveChildProcess();
|
int hasActiveChildProcess();
|
||||||
void sendChildCOWInfo(int ptype, char *pname);
|
void sendChildCOWInfo(int ptype, char *pname);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user