O
Ole
hi everybody,
i've got a little problem with a program i'm working on. That program
has the purpose to collect log entries generated by iptables through
syslog-ng. I have redirected the logs coming from iptables to a
named pipe (or fifo) ( "/dev/ipt_fifo" ). The program then forks
processes that
must collect the log entries coming through the fifo and prepare them
to
be saved for further analysis.
Now i have the following code:
( the program forks 5 processes that work on the input of the named
pipe.
after having collected a certain amount of information, the
processes save
the data to a file. )
##########################################################################
#!/usr/bin/perl -w
use POSIX;
use strict;
my $pid;
my $childId;
my $child_pids = [ ];
our $zombies = 0;
##########################################################################
for ( my $num = 0; $num < 5; $num++ ) {
if (( $pid = fork ( ) ) > 0 ) { # parent process
push ( @$child_pids, $pid );
}elsif ( $pid == 0 ) {
my $FIFO;
my $i = 1;
my $reports = [];
my $my_pid = getpid ( ) ||die "Cannot getpid ( ) : $!";
while ( 1 ) {
open ( $FIFO, "</dev/ipt_fifo" );
while ( <$FIFO> ) {
# analyze log data... ( left here ) #
push( @$reports, $_ );
print $my_pid . " : " . $i . "--Size of \$reports\t:\t" .
scalar( @$reports ) . "\n";
if (( $i % 1024 ) == 0 ) {
saveReport ( $reports,$my_pid );
undef ( $reports );
print "OK\n";
$i = 0;
}
$i++;
}
close ( $FIFO );
}
}
}
wait_zombies ( $pid );
sub wait_zombies {
my $pid = $_[ 0 ];
if ( $pid > 0 ) {
my $chId;
do {
$chId = waitpid( -1, 0 );
print "Caught child no $chId\n";
}until ( $chId == - 1 );
}
}
sub saveReport {
my $reports = $_[ 0 ];
my $my_pid = $_[ 1 ];
open ( FH, ">>log_fork_childno_$my_pid.log" );
print "saving reports [PID = $my_pid]";
foreach ( @$reports ) {
print ".";
print FH $_;
}
close ( FH );
}
##################################################################
Now i have 2 problems:
1.) How do I trap e.g. a "kill -9" command, directed to the parent
process
in order to collect to child processes before quiting. Now the
child
processes get init for as parent.
2. ) I recognize a strange behaviour: for a while, the processes
collect
data from syslog through the fifo as they should. But then, it
seems
that syslog is generating approx 200 entires per second. But i
think
that it has to do with process synchronization.
Questions:
1. ) Is it possible that, if two processes try to read simultaneously
from
the named pipe or fifo, they lock themselves somehow ?
2. ) How can manage it to have only one child process trying to read
from
the fifo ?
I would be very thankful if someone might help me out here.
I need this filter daemon, because it is the topic of the final
examination
of my training.
Thanks in advance for your interprocesscommunication!
Greetings Ole Viaud-Murat.
i've got a little problem with a program i'm working on. That program
has the purpose to collect log entries generated by iptables through
syslog-ng. I have redirected the logs coming from iptables to a
named pipe (or fifo) ( "/dev/ipt_fifo" ). The program then forks
processes that
must collect the log entries coming through the fifo and prepare them
to
be saved for further analysis.
Now i have the following code:
( the program forks 5 processes that work on the input of the named
pipe.
after having collected a certain amount of information, the
processes save
the data to a file. )
##########################################################################
#!/usr/bin/perl -w
use POSIX;
use strict;
my $pid;
my $childId;
my $child_pids = [ ];
our $zombies = 0;
##########################################################################
for ( my $num = 0; $num < 5; $num++ ) {
if (( $pid = fork ( ) ) > 0 ) { # parent process
push ( @$child_pids, $pid );
}elsif ( $pid == 0 ) {
my $FIFO;
my $i = 1;
my $reports = [];
my $my_pid = getpid ( ) ||die "Cannot getpid ( ) : $!";
while ( 1 ) {
open ( $FIFO, "</dev/ipt_fifo" );
while ( <$FIFO> ) {
# analyze log data... ( left here ) #
push( @$reports, $_ );
print $my_pid . " : " . $i . "--Size of \$reports\t:\t" .
scalar( @$reports ) . "\n";
if (( $i % 1024 ) == 0 ) {
saveReport ( $reports,$my_pid );
undef ( $reports );
print "OK\n";
$i = 0;
}
$i++;
}
close ( $FIFO );
}
}
}
wait_zombies ( $pid );
sub wait_zombies {
my $pid = $_[ 0 ];
if ( $pid > 0 ) {
my $chId;
do {
$chId = waitpid( -1, 0 );
print "Caught child no $chId\n";
}until ( $chId == - 1 );
}
}
sub saveReport {
my $reports = $_[ 0 ];
my $my_pid = $_[ 1 ];
open ( FH, ">>log_fork_childno_$my_pid.log" );
print "saving reports [PID = $my_pid]";
foreach ( @$reports ) {
print ".";
print FH $_;
}
close ( FH );
}
##################################################################
Now i have 2 problems:
1.) How do I trap e.g. a "kill -9" command, directed to the parent
process
in order to collect to child processes before quiting. Now the
child
processes get init for as parent.
2. ) I recognize a strange behaviour: for a while, the processes
collect
data from syslog through the fifo as they should. But then, it
seems
that syslog is generating approx 200 entires per second. But i
think
that it has to do with process synchronization.
Questions:
1. ) Is it possible that, if two processes try to read simultaneously
from
the named pipe or fifo, they lock themselves somehow ?
2. ) How can manage it to have only one child process trying to read
from
the fifo ?
I would be very thankful if someone might help me out here.
I need this filter daemon, because it is the topic of the final
examination
of my training.
Thanks in advance for your interprocesscommunication!
Greetings Ole Viaud-Murat.