[Mimedefang] Setting clamd timeouts.
David F. Skoll
dfs at roaringpenguin.com
Wed Sep 26 16:29:21 EDT 2007
Matthew Schumacher wrote:
> I think the best solution to this is to set a timeout on clamd so that
> message_contains_virus() can return tempfail if clamd is taking more
> than 20 seconds. This would allow the system to correctly report what
> the problem is in the logs while not waiting the full slave timeout.
Actually, I don't think this is a good solution. Instead, we run a script
from cron once a minute that asks clamd to scan /etc/hosts. If that
times out, we kill and restart clamd, thereby un-wedging it.
The script follows below. Note that it's shipped with CanIt so
there may be some CanIt-specific assumtions about file locations, but
they should be easy to work around.
Regards,
David.
================ Cut Here =================
#!perl
use strict;
use warnings;
use IO::Socket;
use IO::Select;
sub clamd_ok
{
my($clamd_sock, $timeout) = @_;
my $sock = IO::Socket::UNIX->new(Peer => $clamd_sock);
if (!defined($sock)) {
return 0;
}
my $s = IO::Select->new();
$s->add($sock);
if (!$s->can_write($timeout)) {
$sock->close();
return 0;
}
$sock->print("SCAN /etc/hosts\n");
$sock->flush();
if (!$s->can_read($timeout)) {
$sock->close();
return 0;
}
my $output;
$sock->sysread($output, 256);
$sock->close;
chomp($output);
if (!defined($output) || $output !~ m{/etc/hosts: OK}) {
return 0;
}
return 1;
}
my $init_script;
# Find the init script...
if (-x '/etc/init.d/clamav-daemon') {
# Debian appliances
$init_script = '/etc/init.d/clamav-daemon';
} elsif (-x '/etc/init.d/clamd') {
# RPM packages
$init_script = '/etc/init.d/clamd';
} elsif (-x '/opt/RPSI/canit/bin/clamav-ctrl') {
# Solaris 9 packages
$init_script = '/opt/RPSI/canit/bin/clamav-ctrl';
} else {
# Pretty much everyone else
$init_script = '/etc/mail/canit/clamav-ctrl';
}
my $pidfile = '/var/spool/MIMEDefang/clamd.pid';
# If there's no pid file, assume admin has stopped clamd
if (! -r $pidfile) {
exit(0);
}
my $socket_path = '/var/spool/MIMEDefang/clamd.sock';
if (clamd_ok($socket_path, 30)) {
exit(0);
}
print STDERR "ClamAV daemon not responding... restarting.\n";
my $clamd_pid = -1;
if (open(IN, "<$pidfile")) {
$clamd_pid = <IN>;
chomp($clamd_pid);
close(IN);
}
system("$init_script stop");
if ($clamd_pid > 1) {
sleep(1);
kill(9, $clamd_pid);
}
system("$init_script start");
exit(1);
More information about the MIMEDefang
mailing list