Bug 169561 - app-antivirus/clamav - clamav-milter with "--external" doesn't start up correctly from clamd init script
Bug#: 169561 Product:  Gentoo Linux Version: unspecified Platform: All
OS/Version: Linux Status: RESOLVED Severity: normal Priority: P2
Resolution: FIXED Assigned To: antivirus@gentoo.org Reported By: dean@bullock.net
Component: Applications
URL: 
Summary: app-antivirus/clamav - clamav-milter with "--external" doesn't start up correctly from clamd init script
Keywords:  
Status Whiteboard: 
Opened: 2007-03-06 02:08 0000
Description:   Opened: 2007-03-06 02:08 0000
The /etc/init.d/clamd script tries to start clamav-milter before the clamd
socket (/var/run/clamav/clamd.sock) is available and hence fails to start.

Reproducible: Always

Steps to Reproduce:
1.  Add --external to MILTER_OPTS in /etc/conf.d/clamd
2.  /etc/init/clamd start
3.




A patch for /etc/init.d/clamd that waits for the socket when --external is in
MILTER_OPTS.


--- clamd.orig  2007-03-05 17:03:48.000000000 -0800
+++ clamd       2007-03-05 17:02:45.000000000 -0800
@@ -45,6 +45,25 @@
                chown ${clamav_user} ${logfile}
                fi

+               if [[ ${MILTER_OPTS} == *--external* ]]; then
+                       local clamd_socket_wait_count=0
+                       local clamd_socket_wait_max=10
+                       local clamd_socket_wait_result=-1
+                       ebegin "Waiting for clamd to create ${clamd_socket}"
+                       while [[ clamd_socket_wait < clamd_socket_wait_max ]];
do
+                               if [ -S "${clamd_socket:-/tmp/clamd}" ]; then
+                                       clamd_socket_wait_result=0
+                                       break
+                               else
+                                       echo -n " ."
+                                       let clamd_socket_wait++
+                                       sleep 1
+                               fi
+                       done
+                       echo
+                       eend $clamd_socket_wait_result "Timeout waiting for
${clamd_socket}"
+               fi
+

------- Comment #1 From Dean C Bullock 2007-03-06 02:10:09 0000 -------
Created an attachment (id=112237) [details]
patch for /etc/init.d/clamd

------- Comment #2 From Andrej Kacian (RETIRED) 2007-03-08 17:00:38 0000 -------
Initscript changed as you suggested. Thanks!

------- Comment #3 From steveb 2007-03-09 13:55:45 0000 -------
Sorry for writing into this closed bug report. But I have a problem with the
way the new init.d script is implemented.

According to the documentation the --external does not check LocalSocket or
TCPSocket but in the new Gentoo init.d script the startup is delayed because it
waits for the socket to be created (wich never happens in my case since I don't
use LocalSocket but use the TCPSocket option.

From the man output of clamav-milter:
       -e, --external
              Usually clamav-milter scans the emails itself without the use of
              an  external program.  The --external option informs
clamav-milter
              ter to use an external program such as clamd(8)  running  either
              on  the local server or other server(s) to perform the scanning.
              The setting  in  clamd.conf  for  LocalSocket  or  TCPSocket  is
              ignored.


So can any one explain me what the point is in waiting for a non existent
socket?

I would much more like the init.d script to chmod the ${MILTER_SOCKET} with
0777 then this waiting thing (should I send a patch for that?).

------- Comment #4 From Andrej Kacian (RETIRED) 2007-03-09 15:32:21 0000 -------
Ok, initscript change reverted. This is something we haven't thought about, and
I certainly misunderstood nature of --external option. Sorry about that.

Any suggestions on how to solve the original problem?

------- Comment #5 From Dean C Bullock 2007-03-12 20:53:53 0000 -------
I didn't read about the TCPSocket feature when using --external.  I apologize
for leaving TCPSocket users out of my original patch.  However....

The man page for clamav-milter states that clamav-milter will terminate at
start up if it cannot communicate with the external clamd.  It also specifies
(under the --server argument) that all servers must be up when clamav-milter
starts.

I think that it is valid to delay the clamav-milter startup when we know that
the server is unavailable, which is the case where we are using LocalSocket
with the --external flag and we are starting clamd in the same startup script.

I think that my mistake was to leave out the TCPSocket possibility.  I have
never used TCPSocket with clamav-milter.  Am I correct in thinking that one
must list a set of one or more servers on the command line with the --servers
argument?  It appears that if --external is used without --servers then
clamav-milter will try the LocalSocket and if --external is used with --servers
then clamav-milter will try to contact all of the servers listed via the TCP
socket specified by TCPSocket (in /etc/clamd.conf).

I think there are a few options.

1)  Add the logic to my patch that allows for the (--external && --servers)
logic such that no wait will occur when both --external and --servers are
present in MILTER_OPTS.  Only delay when --external is present without
--servers.

2)  Add a line to /etc/conf.d/clamd that would force an explicit wait without
any automatic logic.  It could be MILTER_START_DELAY which would default to
zero.  This option forces the someone like myself to understand that a delay is
needed when using --external and LocalSocket.

3)  Add a line to /etc/conf.d/clamd that the user can set to "turn on"
--external over LocalSocket which would add the needed delay and --external to
the clamav-milter invocation.


I think that option two is the least advisable in that it forces the end user
to learn why clamav-milter failed to start after the user adds --external to
the MILTER_OPTS.  Option three is better, but I think that it is just option
one (1) poorly implemented.  I like the automation of option one.

By the way, on my system the delay is always four seconds.  If the decision is
to go ahead with a solution to this issue and my option one is picked, I will
provide the code.

------- Comment #6 From Dean C Bullock 2007-03-12 23:30:10 0000 -------
Created an attachment (id=113117) [details]
new patch that takes into account --server

This new patch will delay only if --external is in MILTER_OPTS and --server is
not.  Getopt is used so that MILTER_OPTS can be searched for -e, -s, --external
and/or --server using the getopt logic.

Also fixes a bug in the count down where the [[ operator was used instead of
the (( operator.

------- Comment #7 From Andrej Kacian (RETIRED) 2007-04-10 20:14:26 0000 -------
Looks good, patch applied. Thanks, and sorry for the delay!