Hi everybody,
Short introduction:
We are a small company using Squid in our Unified Threat Management
(UTM) series of products. I am working as a Backend developer and have
tackled some problems with cross-compiling Squid in the past (see the
unfortunately unanswered bug report at
http://bugs.squid-cache.org/show_bug.cgi?id=4650).
The Problem:
We're using runit (http://smarden.org/runit/) to supervise squid 3.5.21
in "no_daemon"-mode (-N option).
Being interested in the SMP feature of squid we face the problem that it
only works in daemon mode, which is inherently incompatible with runit
supervising the service (would notice the process exiting and start it
over and over again).
What are the reasons to tie the SMP feature so tightly to the daemon
mode of squid? I played with the code and was able to alter the behavior
and allow staying in foreground AND forking children that take the role
of workers and coordinators etc.. I also managed to make the "master"
process (the one staying in foreground) to react on a SIGTERM by
signalling its children to shutdown. See the attached patch against the
3.5 branch of squid, which is not meant as a real contribution but just
to show what I did.
I do acknowledge that I do not understand all implications of the
changes I made, but in general, the program behaves as expected, with
the slight exception that it runs into an exception if the configuration
directive "workers 0" is given.
I noticed that in the squid 4 branch, the behavior again has slightly
changed. What I get from the code in main.cc:watch_child is, that the
"daemon" process stays alive until all its children terminate if the
rather strangely named "opt_foreground" option is set. Additionally, the
"master" process (the one created by the daemon's fork) processes
signals and broadcasts those to its children.
Isn't it a rather small step from here to just prevent daemonizing and
let the master process run in "real foreground"? That way, it seems to
me that runit would not have any problems managing squid with standard
signals and without changing the behavior of squid?
Am I missing something completely here? Is there some hidden problem
that would break everything if instead of the "daemon-forking"-process,
the master process itself would stay in the foreground? Or would it be
possible?
Kind Regards,
Adnreas Weigel
--
Mit freundlichem Gruß / Best regards,
Andreas Weigel
UTM Backend Developer
Securepoint GmbH
Salzstrasse 1
D-21335 Lüneburg
https://www.securepoint.de
Tel.: +49(0)413124010
Fax: +49(0)4131240118
Geschäftsführer: Lutz Hausmann, Claudia Hausmann
Amtsgericht Lüneburg HRB 1776
USt.-ID-Nr.: DE 188 528 597
=== modified file 'src/main.cc'
--- src/main.cc 2016-09-23 15:28:42 +0000
+++ src/main.cc 2017-06-08 11:16:18 +0000
@@ -1457,7 +1457,7 @@
RunRegisteredHere(RegisteredRunner::useConfig);
enter_suid();
- if (!opt_no_daemon && Config.workers > 0)
+ if (!opt_no_daemon || Config.workers > 0)
watch_child(argv);
if (opt_create_swap_dirs) {
@@ -1689,14 +1689,14 @@
return;
openlog(APP_SHORTNAME, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4);
-
- if ((pid = fork()) < 0)
- syslog(LOG_ALERT, "fork failed: %s", xstrerror());
- else if (pid > 0)
- exit(0);
-
- if (setsid() < 0)
- syslog(LOG_ALERT, "setsid failed: %s", xstrerror());
+ if (!opt_no_daemon) {
+ if ((pid = fork()) < 0)
+ syslog(LOG_ALERT, "fork failed: %s", xstrerror());
+ else if (pid > 0)
+ exit(0);
+ if (setsid() < 0)
+ syslog(LOG_ALERT, "setsid failed: %s", xstrerror());
+ }
closelog();
@@ -1727,9 +1727,6 @@
dup2(nullfd, 2);
}
- // handle shutdown notifications from kids
- squid_signal(SIGUSR1, sig_shutdown, SA_RESTART);
-
if (Config.workers > 128) {
syslog(LOG_ALERT, "Suspiciously high workers value: %d",
Config.workers);
@@ -1766,7 +1763,10 @@
/* parent */
openlog(APP_SHORTNAME, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4);
- squid_signal(SIGINT, SIG_IGN, SA_RESTART);
+ // handle shutdown notifications from kids
+ squid_signal(SIGUSR1, sig_shutdown, SA_RESTART);
+ squid_signal(SIGINT, sig_shutdown, SA_RESTART);
+ squid_signal(SIGTERM, sig_shutdown, SA_RESTART);
#if _SQUID_NEXT_
=== modified file 'src/tools.cc'
--- src/tools.cc 2016-12-16 12:18:27 +0000
+++ src/tools.cc 2017-06-08 10:02:21 +0000
@@ -438,6 +438,12 @@
sig_shutdown(int sig)
{
shutting_down = 1;
+ if (IamMasterProcess()) {
+ for (int i = TheKids.count() - 1; i >= 0; --i) {
+ Kid &cur = TheKids.get(i);
+ kill(cur.getPid(), SIGINT);
+ }
+ }
}
const char *
@@ -661,7 +667,7 @@
IamWorkerProcess()
{
// when there is only one process, it has to be the worker
- if (opt_no_daemon || Config.workers == 0)
+ if (Config.workers == 0)
return true;
return TheProcessKind == pkWorker;
@@ -676,12 +682,14 @@
bool
InDaemonMode()
{
- return !opt_no_daemon && Config.workers > 0;
+ debugs(50, DBG_IMPORTANT, "opt_no_daemon=" << opt_no_daemon << " Config.workers=" << Config.workers);
+ return !opt_no_daemon || Config.workers > 0;
}
bool
UsingSmp()
{
+ debugs(50, DBG_IMPORTANT, "InDaemonMode=" << InDaemonMode() << " NumberOfKids=" << NumberOfKids());
return InDaemonMode() && NumberOfKids() > 1;
}
@@ -695,7 +703,7 @@
IamPrimaryProcess()
{
// when there is only one process, it has to be primary
- if (opt_no_daemon || Config.workers == 0)
+ if (Config.workers == 0)
return true;
// when there is a master and worker process, the master delegates
_______________________________________________
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev