Restart the server, executing the same executable that started this * instance, with the same arguments and configuration file. * * The function is designed to directly call execve() so that the new * server instance will retain the PID of the previous one. * * The list of flags, that may be bitwise ORed together, alter the * behavior of this function: * * RESTART_SERVER_NONE
| 3426 | * On success the function does not return, because the process turns into |
| 3427 | * a different process. On error C_ERR is returned. */ |
| 3428 | int restartServer(int flags, mstime_t delay) { |
| 3429 | int j; |
| 3430 | |
| 3431 | /* Check if we still have accesses to the executable that started this |
| 3432 | * server instance. */ |
| 3433 | if (access(cserver.executable,X_OK) == -1) { |
| 3434 | serverLog(LL_WARNING,"Can't restart: this process has no " |
| 3435 | "permissions to execute %s", cserver.executable); |
| 3436 | return C_ERR; |
| 3437 | } |
| 3438 | |
| 3439 | /* Config rewriting. */ |
| 3440 | if (flags & RESTART_SERVER_CONFIG_REWRITE && |
| 3441 | cserver.configfile && |
| 3442 | rewriteConfig(cserver.configfile, 0) == -1) |
| 3443 | { |
| 3444 | serverLog(LL_WARNING,"Can't restart: configuration rewrite process " |
| 3445 | "failed"); |
| 3446 | return C_ERR; |
| 3447 | } |
| 3448 | |
| 3449 | /* Perform a proper shutdown. */ |
| 3450 | if (flags & RESTART_SERVER_GRACEFULLY && |
| 3451 | prepareForShutdown(SHUTDOWN_NOFLAGS) != C_OK) |
| 3452 | { |
| 3453 | serverLog(LL_WARNING,"Can't restart: error preparing for shutdown"); |
| 3454 | return C_ERR; |
| 3455 | } |
| 3456 | |
| 3457 | /* Close all file descriptors, with the exception of stdin, stdout, strerr |
| 3458 | * which are useful if we restart a Redis server which is not daemonized. */ |
| 3459 | for (j = 3; j < (int)g_pserver->maxclients + 1024; j++) { |
| 3460 | /* Test the descriptor validity before closing it, otherwise |
| 3461 | * Valgrind issues a warning on close(). */ |
| 3462 | if (fcntl(j,F_GETFD) != -1) |
| 3463 | { |
| 3464 | /* This user to just close() here, but sanitizers detected that as an FD race. |
| 3465 | The race doesn't matter since we're about to call exec() however we want |
| 3466 | to cut down on noise, so instead we ask the kernel to close when we call |
| 3467 | exec(), and only do it ourselves if that fails. */ |
| 3468 | if (fcntl(j, F_SETFD, FD_CLOEXEC) == -1) |
| 3469 | { |
| 3470 | close(j); // failed to set close on exec, close here |
| 3471 | } |
| 3472 | } |
| 3473 | } |
| 3474 | |
| 3475 | if (flags & RESTART_SERVER_GRACEFULLY) { |
| 3476 | if (g_pserver->m_pstorageFactory) { |
| 3477 | for (int idb = 0; idb < cserver.dbnum; ++idb) { |
| 3478 | g_pserver->db[idb]->storageProviderDelete(); |
| 3479 | } |
| 3480 | delete g_pserver->metadataDb; |
| 3481 | } |
| 3482 | } |
| 3483 | |
| 3484 | /* Execute the server with the original command line. */ |
| 3485 | if (delay) usleep(delay*1000); |
no test coverage detected