purpose is one of CHILD_TYPE_ types */
| 6956 | |
| 6957 | /* purpose is one of CHILD_TYPE_ types */ |
| 6958 | int redisFork(int purpose) { |
| 6959 | int childpid; |
| 6960 | long long start = ustime(); |
| 6961 | |
| 6962 | if (isMutuallyExclusiveChildType(purpose)) { |
| 6963 | if (hasActiveChildProcess()) |
| 6964 | return -1; |
| 6965 | |
| 6966 | openChildInfoPipe(); |
| 6967 | } |
| 6968 | long long startWriteLock = ustime(); |
| 6969 | aeAcquireForkLock(); |
| 6970 | latencyAddSampleIfNeeded("fork-lock",(ustime()-startWriteLock)/1000); |
| 6971 | if ((childpid = fork()) == 0) { |
| 6972 | /* Child */ |
| 6973 | aeForkLockInChild(); |
| 6974 | aeReleaseForkLock(); |
| 6975 | g_pserver->in_fork_child = purpose; |
| 6976 | setOOMScoreAdj(CONFIG_OOM_BGCHILD); |
| 6977 | setupChildSignalHandlers(); |
| 6978 | closeChildUnusedResourceAfterFork(); |
| 6979 | } else { |
| 6980 | /* Parent */ |
| 6981 | aeReleaseForkLock(); |
| 6982 | g_pserver->stat_total_forks++; |
| 6983 | g_pserver->stat_fork_time = ustime()-start; |
| 6984 | g_pserver->stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / g_pserver->stat_fork_time / (1024*1024*1024); /* GB per second. */ |
| 6985 | latencyAddSampleIfNeeded("fork",g_pserver->stat_fork_time/1000); |
| 6986 | if (childpid == -1) { |
| 6987 | if (isMutuallyExclusiveChildType(purpose)) closeChildInfoPipe(); |
| 6988 | return -1; |
| 6989 | } |
| 6990 | |
| 6991 | /* The child_pid and child_type are only for mutual exclusive children. |
| 6992 | * other child types should handle and store their pid's in dedicated variables. |
| 6993 | * |
| 6994 | * Today, we allows CHILD_TYPE_LDB to run in parallel with the other fork types: |
| 6995 | * - it isn't used for production, so it will not make the server be less efficient |
| 6996 | * - used for debugging, and we don't want to block it from running while other |
| 6997 | * forks are running (like RDB and AOF) */ |
| 6998 | if (isMutuallyExclusiveChildType(purpose)) { |
| 6999 | g_pserver->child_pid = childpid; |
| 7000 | g_pserver->child_type = purpose; |
| 7001 | g_pserver->stat_current_cow_bytes = 0; |
| 7002 | g_pserver->stat_current_cow_updated = 0; |
| 7003 | g_pserver->stat_current_save_keys_processed = 0; |
| 7004 | g_pserver->stat_module_progress = 0; |
| 7005 | g_pserver->stat_current_save_keys_total = dbTotalServerKeyCount(); |
| 7006 | } |
| 7007 | |
| 7008 | updateDictResizePolicy(); |
| 7009 | moduleFireServerEvent(REDISMODULE_EVENT_FORK_CHILD, |
| 7010 | REDISMODULE_SUBEVENT_FORK_CHILD_BORN, |
| 7011 | NULL); |
| 7012 | } |
| 7013 | return childpid; |
| 7014 | } |
| 7015 |
no test coverage detected