From 97d9ba2380e0c894a1b611bdb4f35d0fe98a837a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 11 Dec 2017 10:57:00 -0500 Subject: Add a mostly disabled feature to debug restarting in-process For 23847, we want Tor to be able to shut down and then restart in the same process. Here's a patch to make the Tor binary do that. To test it, you need to build with --enable-restart-debugging, and then you need to set the environment variable TOR_DEBUG_RESTART. With this option, Tor will then run for 5 seconds, then restart itself in-process without exiting. This only happens once. You can change the 5-second interval using TOR_DEBUG_RESTART_AFTER_SECONDS. Implements ticket 24583. --- src/or/main.c | 39 +++++++++++++++++++++++++++++++++++++++ src/or/tor_main.c | 16 +++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/or/main.c b/src/or/main.c index aae98dd8ab..dc954bc15d 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -682,6 +682,20 @@ shutdown_did_not_work_callback(evutil_socket_t fd, short event, void *arg) // LCOV_EXCL_STOP } +#ifdef ENABLE_RESTART_DEBUGGING +static struct event *tor_shutdown_event_loop_for_restart_event = NULL; +static void +tor_shutdown_event_loop_for_restart_cb( + evutil_socket_t fd, short event, void *arg) +{ + (void)fd; + (void)event; + (void)arg; + tor_event_free(tor_shutdown_event_loop_for_restart_event); + tor_shutdown_event_loop_and_exit(0); +} +#endif + /** * After finishing the current callback (if any), shut down the main loop, * clean up the process, and exit with exitcode. @@ -2675,6 +2689,31 @@ do_main_loop(void) main_loop_should_exit = 0; main_loop_exit_value = 0; +#ifdef ENABLE_RESTART_DEBUGGING + { + static int first_time = 1; + + if (first_time && getenv("TOR_DEBUG_RESTART")) { + first_time = 0; + const char *sec_str = getenv("TOR_DEBUG_RESTART_AFTER_SECONDS"); + long sec; + int sec_ok=0; + if (sec_str && + (sec = tor_parse_long(sec_str, 10, 0, INT_MAX, &sec_ok, NULL)) && + sec_ok) { + /* Okay, we parsed the seconds. */ + } else { + sec = 5; + } + struct timeval restart_after = { (time_t) sec, 0 }; + tor_shutdown_event_loop_for_restart_event = + tor_evtimer_new(tor_libevent_get_base(), + tor_shutdown_event_loop_for_restart_cb, NULL); + event_add(tor_shutdown_event_loop_for_restart_event, &restart_after); + } + } +#endif + return run_main_loop_until_done(); } diff --git a/src/or/tor_main.c b/src/or/tor_main.c index c203d8248f..703669ac99 100644 --- a/src/or/tor_main.c +++ b/src/or/tor_main.c @@ -3,6 +3,11 @@ * Copyright (c) 2007-2017, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +#include "orconfig.h" +#ifdef ENABLE_RESTART_DEBUGGING +#include +#endif + /** * \file tor_main.c * \brief Stub module containing a main() function. @@ -19,9 +24,18 @@ int tor_main(int argc, char *argv[]); int main(int argc, char *argv[]) { - int r = tor_main(argc, argv); + int r; +#ifdef ENABLE_RESTART_DEBUGGING + int restart_count = getenv("TOR_DEBUG_RESTART") ? 1 : 0; + again: +#endif + r = tor_main(argc, argv); if (r < 0 || r > 255) return 1; +#ifdef ENABLE_RESTART_DEBUGGING + else if (r == 0 && restart_count--) + goto again; +#endif else return r; } -- cgit v1.2.3-54-g00ecf