### ### 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 = ; 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 module provides a B 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 class is derived from the B class, but it defines/overrides the following methods: =over 4 =item check() Checks to see if there is any action(s) pending on I. =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 class, the B class supports the following attributes: =over 4 =item I The name of the daemon to restart. =item I The file(s) to watch to check() to restart. =item I A reference to the subroutine that determines whether the command needs to be executed. The subroutine will be passed a reference to the B object and a reference to the B object. It can return anything that the check() method can return. =item I The signal to send to the daemon, defaults to I. =item I The file that stores the pid of I daemon. =item I Use this I with the I and I options to bounce this daemon. =item I The I supports the I argument. =item I Sleep I seconds between running I and I. =back =head1 SEE ALSO L L L L =cut