------------------------------------------------------------ revno: 13935 revision-id: squid3@treenet.co.nz-20151014052929-7yesi94pu0i2gpwq parent: squid3@treenet.co.nz-20151011053619-x5o37tyg0ymkpe3z fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=3574 committer: Amos Jeffries branch nick: 3.5 timestamp: Tue 2015-10-13 22:29:29 -0700 message: Bug 3574: crashes on reconfigure and startup When Squid receives a reconfigure signal before its signal handler has been registered on startup it will crash with unhandled signal exceptions. This can be triggered on system boot when a resolv.conf alteration signal wins a race with the daemon service initialization. Fix: Register the reconfigure signal handler early and ignoring signals until initial squid.conf load has completed. When Squid receives a reconfigure signal while it is already in the process of reconfiguring, the two async sequences can interfere and result in confusing fatal error or crashes. Fix: Only allow one reconfigure sequence to be initiated at a time. Also, if shutdown signal has been received while waiting for a reconfigure to finish, let shutdown take precedence over any pending reconfigure repeats. Based on work by Clint Byrum and D J Gardner, Ubuntu ------------------------------------------------------------ # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: squid3@treenet.co.nz-20151014052929-7yesi94pu0i2gpwq # target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 # testament_sha1: 6d385c74e2d6f1943f237dac44c2c061576c19a7 # timestamp: 2015-10-14 05:50:59 +0000 # source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 # base_revision_id: squid3@treenet.co.nz-20151011053619-\ # x5o37tyg0ymkpe3z # # Begin patch === modified file 'src/main.cc' --- src/main.cc 2015-07-29 08:56:44 +0000 +++ src/main.cc 2015-10-14 05:29:29 +0000 @@ -224,8 +224,10 @@ PROF_start(SignalEngine_checkEvents); if (do_reconfigure) { - mainReconfigureStart(); - do_reconfigure = 0; + if (!reconfiguring && configured_once) { + mainReconfigureStart(); + do_reconfigure = 0; + } // else wait until previous reconfigure is done } else if (do_rotate) { mainRotate(); do_rotate = 0; @@ -889,6 +891,10 @@ writePidFile(); /* write PID file */ reconfiguring = 0; + + // ignore any pending re-reconfigure signals if shutdown received + if (do_shutdown) + do_reconfigure = 0; } static void @@ -991,6 +997,7 @@ squid_signal(SIGPIPE, SIG_IGN, SA_RESTART); squid_signal(SIGCHLD, sig_child, SA_NODEFER | SA_RESTART); + squid_signal(SIGHUP, reconfigure, SA_RESTART); setEffectiveUser(); @@ -1156,8 +1163,6 @@ #endif - squid_signal(SIGHUP, reconfigure, SA_RESTART); - squid_signal(SIGTERM, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART); squid_signal(SIGINT, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART); @@ -1402,6 +1407,7 @@ Format::Token::Init(); // XXX: temporary. Use a runners registry of pre-parse runners instead. try { + do_reconfigure = 0; // ignore any early (boot/startup) reconfigure signals parse_err = parseConfigFile(ConfigFile); } catch (...) { // for now any errors are a fatal condition...