RM_GetContextFlags provides indication that we're in a fork child (#7783)

This commit is contained in:
Oran Agra 2020-09-20 13:43:28 +03:00 committed by GitHub
parent dfe9714c86
commit 2458e54814
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 28 additions and 18 deletions

View File

@ -1603,7 +1603,7 @@ int rewriteAppendOnlyFileBackground(void) {
if (hasActiveChildProcess()) return C_ERR;
if (aofCreatePipes() != C_OK) return C_ERR;
openChildInfoPipe();
if ((childpid = redisFork()) == 0) {
if ((childpid = redisFork(CHILD_TYPE_AOF)) == 0) {
char tmpfile[256];
/* Child */
@ -1611,7 +1611,7 @@ int rewriteAppendOnlyFileBackground(void) {
redisSetCpuAffinity(server.aof_rewrite_cpulist);
snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid());
if (rewriteAppendOnlyFile(tmpfile) == C_OK) {
sendChildCOWInfo(CHILD_INFO_TYPE_AOF, "AOF rewrite");
sendChildCOWInfo(CHILD_TYPE_AOF, "AOF rewrite");
exitFromChild(0);
} else {
exitFromChild(1);

View File

@ -76,11 +76,11 @@ void receiveChildInfo(void) {
if (read(server.child_info_pipe[0],&server.child_info_data,wlen) == wlen &&
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;
} 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;
} 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;
}
}

View File

@ -1991,6 +1991,7 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
/* Presence of children processes. */
if (hasActiveChildProcess()) flags |= REDISMODULE_CTX_FLAGS_ACTIVE_CHILD;
if (server.in_fork_child) flags |= REDISMODULE_CTX_FLAGS_IS_CHILD;
return flags;
}
@ -6899,7 +6900,7 @@ int RM_Fork(RedisModuleForkDoneHandler cb, void *user_data) {
}
openChildInfoPipe();
if ((childpid = redisFork()) == 0) {
if ((childpid = redisFork(CHILD_TYPE_MODULE)) == 0) {
/* Child */
redisSetProcTitle("redis-module-fork");
} 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.
*/
int RM_ExitFromChild(int retcode) {
sendChildCOWInfo(CHILD_INFO_TYPE_MODULE, "Module fork");
sendChildCOWInfo(CHILD_TYPE_MODULE, "Module fork");
exitFromChild(retcode);
return REDISMODULE_OK;
}

View File

@ -1385,7 +1385,7 @@ int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {
server.lastbgsave_try = time(NULL);
openChildInfoPipe();
if ((childpid = redisFork()) == 0) {
if ((childpid = redisFork(CHILD_TYPE_RDB)) == 0) {
int retval;
/* Child */
@ -1393,7 +1393,7 @@ int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {
redisSetCpuAffinity(server.bgsave_cpulist);
retval = rdbSave(filename,rsi);
if (retval == C_OK) {
sendChildCOWInfo(CHILD_INFO_TYPE_RDB, "RDB");
sendChildCOWInfo(CHILD_TYPE_RDB, "RDB");
}
exitFromChild((retval == C_OK) ? 0 : 1);
} else {
@ -2561,7 +2561,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
/* Create the child process. */
openChildInfoPipe();
if ((childpid = redisFork()) == 0) {
if ((childpid = redisFork(CHILD_TYPE_RDB)) == 0) {
/* Child */
int retval, dummy;
rio rdb;
@ -2576,7 +2576,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
retval = C_ERR;
if (retval == C_OK) {
sendChildCOWInfo(CHILD_INFO_TYPE_RDB, "RDB");
sendChildCOWInfo(CHILD_TYPE_RDB, "RDB");
}
rioFreeFd(&rdb);

View File

@ -112,6 +112,8 @@
#define REDISMODULE_CTX_FLAGS_ACTIVE_CHILD (1<<18)
/* The next EXEC will fail due to dirty CAS (touched keys). */
#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
* character for configuration purposes.

View File

@ -1858,7 +1858,7 @@ void ldbSendLogs(void) {
int ldbStartSession(client *c) {
ldb.forked = (c->flags & CLIENT_LUA_DEBUG_SYNC) == 0;
if (ldb.forked) {
pid_t cp = redisFork();
pid_t cp = redisFork(CHILD_TYPE_LDB);
if (cp == -1) {
addReplyError(c,"Fork() failed: can't run EVAL in debugging mode.");
return 0;

View File

@ -2886,6 +2886,7 @@ void initServer(void) {
server.aof_state = server.aof_enabled ? AOF_ON : AOF_OFF;
server.hz = server.config_hz;
server.pid = getpid();
server.in_fork_child = CHILD_TYPE_NONE;
server.main_thread_id = pthread_self();
server.current_client = NULL;
server.fixed_time_expire = 0;
@ -4989,7 +4990,8 @@ void removeSignalHandlers(void) {
* accepting writes because of a write error condition. */
static void sigKillChildHandler(int 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);
}
@ -5015,11 +5017,13 @@ void closeClildUnusedResourceAfterFork() {
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;
long long start = ustime();
if ((childpid = fork()) == 0) {
/* Child */
server.in_fork_child = purpose;
setOOMScoreAdj(CONFIG_OOM_BGCHILD);
setupChildSignalHandlers();
closeClildUnusedResourceAfterFork();

View File

@ -1046,9 +1046,11 @@ struct clusterState;
#endif
#define CHILD_INFO_MAGIC 0xC17DDA7A12345678LL
#define CHILD_INFO_TYPE_RDB 0
#define CHILD_INFO_TYPE_AOF 1
#define CHILD_INFO_TYPE_MODULE 3
#define CHILD_TYPE_NONE 0
#define CHILD_TYPE_RDB 1
#define CHILD_TYPE_AOF 2
#define CHILD_TYPE_LDB 3
#define CHILD_TYPE_MODULE 4
struct redisServer {
/* General */
@ -1062,6 +1064,7 @@ struct redisServer {
the actual 'hz' field value if dynamic-hz
is enabled. */
int hz; /* serverCron() calls frequency in hertz */
int in_fork_child; /* indication that this is a fork child */
redisDb *db;
dict *commands; /* Command table */
dict *orig_commands; /* Command table before command renaming. */
@ -1904,7 +1907,7 @@ void sendChildInfo(int process_type);
void receiveChildInfo(void);
/* Fork helpers */
int redisFork();
int redisFork(int type);
int hasActiveChildProcess();
void sendChildCOWInfo(int ptype, char *pname);