You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by Apache Wiki <wi...@apache.org> on 2009/06/02 19:49:49 UTC

[Spamassassin Wiki] Update of "SpamdOnWindows" by Brain2000

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Spamassassin Wiki" for change notification.

The following page has been changed by Brain2000:
http://wiki.apache.org/spamassassin/SpamdOnWindows

------------------------------------------------------------------------------
  = Running SpamD on Windows - Overview =
  
  This document describes how to get SpamD to run on Windows.
- 
- '''ATTENTION''': This is a '''''extremely rough''''' solution and not intended to be used in a production environment. It works around the in windows unimplemented fork issues by incorporating the children processes' tasks into the main process. Thus no spin-off processes are needed. Various other issues are not tackle but these result only in warning messages.
+ '''ATTENTION''': This is a '''''extremely rough''''' solution and not intended to be used in a production environment. It works around the in windows unimplemented fork issues by incorporating the children processes' tasks into the main process. Thus no spin-off processes are needed. Various other issues are not tackled but these result only in warning messages.
  
  Kudos to Arik for providing this document. In NO WAY do I wish to minimize his achievement!
  
@@ -13, +12 @@

  But under heavier load, you will likely find any performance advantage disappearing and may experience timeouts. Also, this amount of
  patching is not fot the novice and will break all too easily with only minor code updates -- MichaelBell
  
+ 
+ = Update for SpamAssassin 3.2.5 =
+ 
+ Brain2000 has updated this document to also work with SpamAssassin 3.2.5.  However, it has only been tested by running the two sample-spam/nonspam files thousands of times simultaneously.  After enough runs though, there is an issue that ultimately leads to the following error:
+ 
+ [3496] error: backchannel: socketpair failed: Too many open files at ../lib/Mail/SpamAssassin/SubProcBackChannel.pm line
+  73.
+ backchannel: socketpair failed: Too many open files at ../lib/Mail/SpamAssassin/SubProcBackChannel.pm line 73.
+ 
+ Somewhere a file is not closing.  There will hopefully be a a stability update for this in the next week.
+ 
+ 
  = Installation =
  
- The version used with this description was 3.0.0-pre4:
+ The version used with this description is 3.2.5 and also 3.0.0-pre4.  Each step applies to both versions unless a specific version is denoted:
+ 
  
  1. Follow the procedures in InstallingOnWindows or on http://www.openhandhome.com/howtosa.html.
  
+ 
  2. Copy ''spamd.raw'' from the SpamAssassin source directory to ''C:\Perl\bin''.
  
+ 
- 3. From the already existing ''spamassassin.bat'' copy the first few lines that look like: {{{{@rem = '--*-Perl-*--
+ 3. From the already existing ''spamassassin.bat'' copy the first few lines that look like: {{{@rem = '--*-Perl-*--
  @echo off
  SET RES_NAMESERVERS=192.168.2.1
  SET LANG=en_US
@@ -61, +75 @@

  use lib 'C:\Perl\site\lib';                   # substituted at 'make' time
  }}}
  
+ 
  4. and replace following lines in ''spamd.raw'' with it: {{{#!/usr/bin/perl -w -T
  # <@LICENSE>
  # Copyright 2004 Apache Software Foundation
@@ -83, +98 @@

  my $LOCAL_RULES_DIR = '@@LOCAL_RULES_DIR@@';    # substituted at 'make' time
  use lib '@@INSTALLSITELIB@@';}}}
  
+ 
- 5. Further down, comment out the following line by adding a # in front of it: {{{use Sys::Syslog qw(:DEFAULT setlogsock);}}}
+ 5a. (SpamAssassin version 3.0.0 only) Further down, comment out the following line by adding a # in front of it: {{{use Sys::Syslog qw(:DEFAULT setlogsock);}}}
+ 
+ 
+ 5b. (SpamAssassin version 3.2.5 only) Further down, change the following line from 'mail' to 'null': {{{#   of a specific logfile
+ my $log_facility = $opt{'syslog'} || 'mail';}}}
+ Change to: {{{#   of a specific logfile
+ my $log_facility = $opt{'syslog'} || 'null';}}}
+ 
  
  6. Even further down comment out the two occurrences of the line: {{{spawn();}}}
  
+ 
- 7. Find the beginning of following block: {{{while (1) {
+ 7a. (SpamAssassin version 3.0.0 only) Find the beginning of following block: {{{while (1) {
    sleep;    # wait for a signal (ie: child's death)
  
    if ( defined $got_sighup ) {
@@ -114, +138 @@

    }
  } }}}
  
- 8. Add this code segment immediately in front of it: {{{while (1) {
+ Add this code segment immediately in front of it: {{{while (1) {
        # use a large eval scope to catch die()s and ensure they
        # don't kill the server.
        my $evalret = eval { accept_a_conn(); };
@@ -153, +177 @@

        undef $current_user;
  } }}}
  
+ 
+ 7b. (SpamAssassin version 3.2.5 only)  Find the beginning of following block: {{{while (1) {
+   if (!$scaling) {
+     # wait for a signal (ie: child's death)
+     # bug 4190: use a time-limited sleep, and call child_handler() even
+     # if haven't received a SIGCHLD, due to inherent race condition
+     sleep 10;
+     child_handler();
+   } else {
+     $scaling->main_server_poll($opt{'server-scale-period'});
+   }
+ 
+   ( defined $got_sighup ) and do_sighup_restart();
+ 
+   for (my $i = keys %children; $i < $childlimit; $i++) {
+     spawn();
+   }
+ }
+ }}}
+ 
+ Add this code segment immediately in front of it: {{{my $i = 0;
+ while (1) {
+       # use a large eval scope to catch die()s and ensure they
+       # don't kill the server.
+       $backchannel->setup_backchannel_parent_pre_fork();
+       $children{$$} = 1;
+       $backchannel->setup_backchannel_parent_post_fork($$);
+       if ($scaling) {
+         $scaling->add_child($$);
+       }
+       $backchannel->setup_backchannel_parent_pre_fork();
+       $spamtest->call_plugins("spamd_child_init");
+       $0 = 'spamd child';
+       $backchannel->setup_backchannel_child_post_fork();
+       my $evalret = eval { accept_a_conn(); };
+ 
+       if (!defined ($evalret)) {
+         warn("spamd: error: $@ $!, continuing");
+         if ($client) { $client->close(); }  # avoid fd leaks
+       }
+       elsif ($evalret == -1) {
+         # serious error; used for accept() failure
+         die("spamd: respawning server");
+       }
+ 
+       $spamtest->call_plugins("spamd_child_post_connection_close");
+ 
+       if ($copy_config_p) {
+         # use a timeout!  There are bugs in Storable on certain platforms
+         # that can cause spamd to hang -- see bug 3828 comment 154.
+         # we don't use Storable any more, but leave this in -- just
+         # in case.
+ 	# bug 4699: this is the alarm that often ends up with an empty $@
+ 
+ 	my $timer = Mail::SpamAssassin::Timeout->new({ secs => 20 });
+ 	my $err = $timer->run(sub {	
+           while(my($k,$v) = each %msa_backup) {
+             $spamtest->{$k} = $v;
+           }
+ 
+           # if we changed user, we would have also loaded up new configs
+           # (potentially), so let's restore back the saved version we
+           # had before.
+           $spamtest->copy_config(\%conf_backup, undef) ||
+             die "spamd: error returned from copy_config\n";
+         });
+ 
+ 	if ($timer->timed_out()) {
+ 	  warn("spamd: copy_config timeout, respawning child process after ".($i+1)." messages");
+ 	  exit;		# so that the master spamd can respawn
+ 	}
+       }
+       undef $current_user;
+       $i += 1;
+ }
+ }}}
+ 
+ 
- 9. Below find the the line: {{{my ( $uid, $gid ) = ( getpwnam('nobody') )[ 2, 3 ];}}} and replace it with: {{{my ( $uid, $gid ) = 'nobody';}}}
+ 8. (SpamAssassin version 3.0.0 only) Below find the line: {{{my ( $uid, $gid ) = ( getpwnam('nobody') )[ 2, 3 ];}}} and replace it with: {{{my ( $uid, $gid ) = 'nobody';}}}
  
+ 
- 10. Then find the block: {{{  my ( $name, $pwd, $uid, $gid, $quota, $comment, $gcos, $dir, $etc ) =
+ 9. (SpamAssassin version 3.0.0 only) Find the block: {{{  my ( $name, $pwd, $uid, $gid, $quota, $comment, $gcos, $dir, $etc ) =
      getpwnam($userid);
  }}}
  
- 11. Replace it with: {{{  my ( $name, $pwd, $uid, $gid, $quota, $comment, $gcos, $dir, $etc ) =
+ Replace it with: {{{  my ( $name, $pwd, $uid, $gid, $quota, $comment, $gcos, $dir, $etc ) =
      'nobody';
  }}}
  
+ 
+ 10. (SpamAssassin version 3.2.5 only) Find the routine handle_setuid_to_user() and comment out the code in it leaving an empty function: {{{sub handle_setuid_to_user {
+ #  if ($spamtest->{paranoid}) {
+ #    die("spamd: in paranoid mode, still running as root: closing connection");
+ #  }
+ #  warn("spamd: still running as root: user not specified with -u, "
+ #       . "not found, or set to root, falling back to nobody\n");
+ #
+ # my ( $name, $pwd, $uid, $gid, $quota, $comment, $gcos, $dir, $etc ) = 
+ #    'nobody';
+ #  
+ #  $) = "$gid $gid";                   # eGID
+ #  $> = $uid;                          # eUID
+ #  if (!defined($uid) || ($> != $uid and $> != ($uid - 2**32))) {
+ #    die("spamd: setuid to nobody failed");
+ #  }
+ #
+ #  $spamtest->signal_user_changed(
+ #    {
+ #      username => $name,
+ #      user_dir => $dir
+ #    }
+ #  );
+ }
+ }}}
+ 
+ 
+ 11. (SpamAssassin version 3.2.5 only) Find and comment out all the lines that quit if credentials are root: {{{#  if ($> == 0) { die "spamd: still running as root! dying"; }
+ }}}
+ 
+ 
+ 12. (SpamAssassin version 3.2.5 only) Open c:\perl\site\lib\mail\spamassassin\util.pm and change the routine trap_sigalrm_fully() as follows: {{{sub trap_sigalrm_fully {
+   my ($handler) = @_;
+ #  if ($] < 5.008) {
+     # signals are always unsafe, just use %SIG
+     $SIG{ALRM} = $handler;
+ #  } else {
+ #    # may be using "safe" signals with %SIG; use POSIX to avoid it
+ #    POSIX::sigaction POSIX::SIGALRM(), new POSIX::SigAction $handler;
+ #  }
+ }
+ }}}
+ 
+ 
- 12. Go all the way to the end of the document and append these lines: {{{
+ 13. Go all the way to the end of the document and append these lines: {{{
  __END__
  :endofperl
  }}}
  
+ 
- 13. Save the file and rename it to ''spamd.bat''.
+ 14. Save the file and rename it to ''spamd.bat''.
+ 
  
  = Running SpamD =