| 5215 | } |
| 5216 | |
| 5217 | int prepareForShutdown(int flags) { |
| 5218 | /* When SHUTDOWN is called while the server is loading a dataset in |
| 5219 | * memory we need to make sure no attempt is performed to save |
| 5220 | * the dataset on shutdown (otherwise it could overwrite the current DB |
| 5221 | * with half-read data). |
| 5222 | * |
| 5223 | * Also when in Sentinel mode clear the SAVE flag and force NOSAVE. */ |
| 5224 | if (g_pserver->loading || g_pserver->sentinel_mode) |
| 5225 | flags = (flags & ~SHUTDOWN_SAVE) | SHUTDOWN_NOSAVE; |
| 5226 | |
| 5227 | int save = flags & SHUTDOWN_SAVE; |
| 5228 | int nosave = flags & SHUTDOWN_NOSAVE; |
| 5229 | |
| 5230 | serverLog(LL_WARNING,"User requested shutdown..."); |
| 5231 | if (cserver.supervised_mode == SUPERVISED_SYSTEMD) |
| 5232 | redisCommunicateSystemd("STOPPING=1\n"); |
| 5233 | |
| 5234 | /* Kill all the Lua debugger forked sessions. */ |
| 5235 | ldbKillForkedSessions(); |
| 5236 | |
| 5237 | /* Kill the saving child if there is a background saving in progress. |
| 5238 | We want to avoid race conditions, for instance our saving child may |
| 5239 | overwrite the synchronous saving did by SHUTDOWN. */ |
| 5240 | if (g_pserver->FRdbSaveInProgress()) { |
| 5241 | serverLog(LL_WARNING,"There is a child saving an .rdb. Killing it!"); |
| 5242 | killRDBChild(); |
| 5243 | /* Note that, in killRDBChild normally has backgroundSaveDoneHandler |
| 5244 | * doing it's cleanup, but in this case this code will not be reached, |
| 5245 | * so we need to call rdbRemoveTempFile which will close fd(in order |
| 5246 | * to unlink file actully) in background thread. |
| 5247 | * The temp rdb file fd may won't be closed when redis exits quickly, |
| 5248 | * but OS will close this fd when process exits. */ |
| 5249 | rdbRemoveTempFile(g_pserver->rdbThreadVars.tmpfileNum, 0); |
| 5250 | } |
| 5251 | |
| 5252 | /* Kill module child if there is one. */ |
| 5253 | if (g_pserver->child_type == CHILD_TYPE_MODULE) { |
| 5254 | serverLog(LL_WARNING,"There is a module fork child. Killing it!"); |
| 5255 | TerminateModuleForkChild(g_pserver->child_pid,0); |
| 5256 | } |
| 5257 | |
| 5258 | if (g_pserver->aof_state != AOF_OFF) { |
| 5259 | /* Kill the AOF saving child as the AOF we already have may be longer |
| 5260 | * but contains the full dataset anyway. */ |
| 5261 | if (g_pserver->child_type == CHILD_TYPE_AOF) { |
| 5262 | /* If we have AOF enabled but haven't written the AOF yet, don't |
| 5263 | * shutdown or else the dataset will be lost. */ |
| 5264 | if (g_pserver->aof_state == AOF_WAIT_REWRITE) { |
| 5265 | serverLog(LL_WARNING, "Writing initial AOF, can't exit."); |
| 5266 | return C_ERR; |
| 5267 | } |
| 5268 | serverLog(LL_WARNING, |
| 5269 | "There is a child rewriting the AOF. Killing it!"); |
| 5270 | killAppendOnlyChild(); |
| 5271 | } |
| 5272 | /* Append only file: flush buffers and fsync() the AOF at exit */ |
| 5273 | serverLog(LL_NOTICE,"Calling fsync() on the AOF file."); |
| 5274 | flushAppendOnlyFile(1); |
no test coverage detected