###
### Copyright 2000-2007 University of Illinois Board of Trustees
### All rights reserved.
###
### PSGConf::Action::RestartDaemon - Send defined signal to a given daemon
###
### Campus Information Technologies and Educational Services
### University of Illinois at Urbana-Champaign
###
package PSGConf::Action::RestartDaemon;
use strict;
use File::stat;
use PSGConf::Action;
use PSGConf::Util;
our @ISA = qw (PSGConf::Action);
###############################################################################
### constructor
###############################################################################
my %defaults = (
signal => 'HUP',
check_func => \&_check_file
);
sub new
{
my ($class, %opts) = @_;
my ($self) = \%opts;
map {
$self->{$_} = $defaults{$_}
if (!exists($self->{$_}));
} keys %defaults;
return PSGConf::Action::new($class, %$self);
}
###############################################################################
### check method
###############################################################################
sub _check_file
{
my ($self, $psgconf) = @_;
my ($action, $file);
foreach $file ( @{$self->{filename}} ) {
$action = $psgconf->get_action($file);
return 1
if (defined($action) && $action->changed());
}
return 0;
}
sub check
{
my ($self, $psgconf) = @_;
my ($ret);
$ret = (exists($self->{check_func})
? $self->{check_func}->($self, $psgconf)
: 1);
return $ret
if ($ret != 1);
$self->{changed} = 1;
return 1;
}
###############################################################################
### diff method
###############################################################################
sub diff
{
my ($self) = @_;
print "###############################################################################\n";
print "### DIFF FOR $self->{name}\n";
print "###############################################################################\n";
print "+ RESTART: $self->{name}\n\n";
}
###############################################################################
### do method
###############################################################################
sub do
{
my ($self, $psgconf) = @_;
my ($proc, $pid, $rcscript);
return 0
if (! $psgconf->{restart_daemons});
print $0 . ": restarting $self->{name}\n";
### do special AIX stuff
if ( -x '/usr/bin/refresh'
&& $self->{signal} eq 'HUP'
&& (grep /^$self->{name}$/, @{$psgconf->data_obj('refresh_daemons')->get()}))
{
return ( PSGConf::Util::RunCommand (
"/usr/bin/refresh -s $self->{name} > /dev/null 2>&1"
) ? -1 : 1 );
}
### use pidfile if specified
if (defined($self->{pidfile}))
{
return 0
if (! -f $self->{pidfile});
if (!open(PIDFILE, "<$self->{pidfile}"))
{
warn "\t!!! open('<$self->{pidfile}'): $!\n";
return -1;
}
$pid = <PIDFILE>;
close(PIDFILE);
chomp($pid);
if (! kill($self->{signal}, $pid))
{
warn "\t!!! can't send signal SIG$self->{signal} to "
. "$self->{name} (pid=$pid): $!\n";
return -1;
}
return 1;
}
### use the rcscript to bounce the daemon
elsif (defined($self->{rcscript}) && -f $self->{rcscript})
{
$rcscript = ( -x $self->{rcscript} )?
$self->{rcscript} : 'sh ' . $self->{rcscript};
if ( defined $self->{use_restart} ) {
return ( PSGConf::Util::RunCommand (
"$rcscript restart > /dev/null 2>&1"
) ? -1 : 1 );
} else {
if ( PSGConf::Util::RunCommand (
"$rcscript stop > /dev/null 2>&1")) {
return -1;
} else {
sleep $self->{delay}
if ( defined $self->{delay} );
return ( PSGConf::Util::RunCommand (
"$rcscript start > /dev/null 2>&1"
) ? -1 : 1 );
}
}
}
### if all else fails, check for running processes
foreach $proc (@{$psgconf->{ps}->table})
{
next
if ($proc->pid == $$
|| $proc->ppid != 1
|| (eval { $proc->cmndline; }
&& $proc->cmndline !~ m/$self->{name}/));
if (!kill($self->{signal}, $proc->pid))
{
warn "\t!!! can't send SIG$self->{signal} to $self->{name} "
. "(pid=" . $proc->pid . "): $!\n";
return -1;
}
}
return 1;
}
###############################################################################
### documentation
###############################################################################
1;
__END__
=head1 NAME
PSGConf::Action::RestartDaemon - Send defined signal to a given daemon
=head1 SYNOPSIS
use PSGConf::Action::RestartDaemon;
$psgconf->register_actions(
PSGConf::Action::RestartDaemon->new(
'name' => daemon,
'filename' => [ '/path/file1', ... ],
'check_func' => \&_subref,
'signal' => HUP,
'pidfile' => '/path/to/file.pid'
'rcscript' => '/etc/init.d/script' # Takes stop/start args
'use_restart' => true # the rcscript has a restart arg
'delay' => 10 # Number of seconds to sleep
# between stop & start of rc script
...
),
...
);
=head1 DESCRIPTION
The B<PSGConf::Action::RestartDaemon> module provides a B<PSGConf>
action class for signaling a daemon to restart. The arguments are
the name of the daemon to restart, the file to watch for a change,
the signal to send to the daemon, and (optionally) the absolute
path of the daemon's pidfile.
The B<PSGConf::Action::RestartDaemon> class is derived from the
B<PSGConf::Action> class, but it defines/overrides the
following methods:
=over 4
=item check()
Checks to see if there is any action(s) pending on I<filename>.
=item diff()
Prints a message indicating that the daemon will be restarted.
=item do()
Actually restarts the daemon.
=back
In addition to the attributes supported by the B<PSGConf::Action>
class, the B<PSGConf::Action::RestartCommand> class supports the following
attributes:
=over 4
=item I<name>
The name of the daemon to restart.
=item I<filename>
The file(s) to watch to check() to restart.
=item I<check_func>
A reference to the subroutine that determines whether the command needs
to be executed. The subroutine will be passed a reference to the
B<PSGConf::Action::RestartDaemon> object and a reference to the B<PSGConf>
object. It can return anything that the check() method can return.
=item I<signal>
The signal to send to the daemon, defaults to I<HUP>.
=item I<pidfile>
The file that stores the pid of I<name> daemon.
=item I<rcscript>
Use this I<rcscript> with the I<stop> and I<start> options to bounce
this daemon.
=item I<use_restart>
The I<rcscript> supports the I<restart> argument.
=item I<delay>
Sleep I<delay> seconds between running I<rcscript stop> and
I<rcscript start>.
=back
=head1 SEE ALSO
L<perl>
L<PSGConf>
L<PSGConf::Action>
L<PSGConf::Util>
=cut
syntax highlighted by Code2HTML, v. 0.9.1