[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