| 4285 | } |
| 4286 | |
| 4287 | int prepareForShutdown(int flags) { |
| 4288 | /* When SHUTDOWN is called while the server is loading a dataset in |
| 4289 | * memory we need to make sure no attempt is performed to save |
| 4290 | * the dataset on shutdown (otherwise it could overwrite the current DB |
| 4291 | * with half-read data). |
| 4292 | * |
| 4293 | * Also when in Sentinel mode clear the SAVE flag and force NOSAVE. */ |
| 4294 | if (server.loading || server.sentinel_mode) |
| 4295 | flags = (flags & ~SHUTDOWN_SAVE) | SHUTDOWN_NOSAVE; |
| 4296 | |
| 4297 | int save = flags & SHUTDOWN_SAVE; |
| 4298 | int nosave = flags & SHUTDOWN_NOSAVE; |
| 4299 | |
| 4300 | serverLog(LL_WARNING,"User requested shutdown..."); |
| 4301 | if (server.supervised_mode == SUPERVISED_SYSTEMD) |
| 4302 | redisCommunicateSystemd("STOPPING=1\n"); |
| 4303 | |
| 4304 | /* Kill all the Lua debugger forked sessions. */ |
| 4305 | ldbKillForkedSessions(); |
| 4306 | |
| 4307 | /* Kill the saving child if there is a background saving in progress. |
| 4308 | We want to avoid race conditions, for instance our saving child may |
| 4309 | overwrite the synchronous saving did by SHUTDOWN. */ |
| 4310 | if (server.child_type == CHILD_TYPE_RDB) { |
| 4311 | serverLog(LL_WARNING,"There is a child saving an .rdb. Killing it!"); |
| 4312 | killRDBChild(); |
| 4313 | /* Note that, in killRDBChild normally has backgroundSaveDoneHandler |
| 4314 | * doing it's cleanup, but in this case this code will not be reached, |
| 4315 | * so we need to call rdbRemoveTempFile which will close fd(in order |
| 4316 | * to unlink file actully) in background thread. |
| 4317 | * The temp rdb file fd may won't be closed when redis exits quickly, |
| 4318 | * but OS will close this fd when process exits. */ |
| 4319 | rdbRemoveTempFile(server.child_pid, 0); |
| 4320 | } |
| 4321 | |
| 4322 | /* Kill module child if there is one. */ |
| 4323 | if (server.child_type == CHILD_TYPE_MODULE) { |
| 4324 | serverLog(LL_WARNING,"There is a module fork child. Killing it!"); |
| 4325 | TerminateModuleForkChild(server.child_pid,0); |
| 4326 | } |
| 4327 | |
| 4328 | if (server.aof_state != AOF_OFF) { |
| 4329 | /* Kill the AOF saving child as the AOF we already have may be longer |
| 4330 | * but contains the full dataset anyway. */ |
| 4331 | if (server.child_type == CHILD_TYPE_AOF) { |
| 4332 | /* If we have AOF enabled but haven't written the AOF yet, don't |
| 4333 | * shutdown or else the dataset will be lost. */ |
| 4334 | if (server.aof_state == AOF_WAIT_REWRITE) { |
| 4335 | serverLog(LL_WARNING, "Writing initial AOF, can't exit."); |
| 4336 | return C_ERR; |
| 4337 | } |
| 4338 | serverLog(LL_WARNING, |
| 4339 | "There is a child rewriting the AOF. Killing it!"); |
| 4340 | killAppendOnlyChild(); |
| 4341 | } |
| 4342 | /* Append only file: flush buffers and fsync() the AOF at exit */ |
| 4343 | serverLog(LL_NOTICE,"Calling fsync() on the AOF file."); |
| 4344 | flushAppendOnlyFile(1); |
no test coverage detected