mirror of
https://github.com/pandorafms/pandorafms.git
synced 2025-07-30 01:05:39 +02:00
2014-05-13 Ramon Novoa <rnovoa@artica.es>
* bin/pandora_server: Added support to run as a native win32 service. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@9924 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
parent
72a4336b50
commit
828a23432b
@ -1,3 +1,7 @@
|
|||||||
|
2014-05-13 Ramon Novoa <rnovoa@artica.es>
|
||||||
|
|
||||||
|
* bin/pandora_server: Added support to run as a native win32 service.
|
||||||
|
|
||||||
2014-05-10 Junichi Satoh <junichi@rworks.jp>
|
2014-05-10 Junichi Satoh <junichi@rworks.jp>
|
||||||
|
|
||||||
* util/recon_script/ipmi-recon.pl, util/recon_script/snmpdevices.pl,
|
* util/recon_script/ipmi-recon.pl, util/recon_script/snmpdevices.pl,
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use Getopt::Std;
|
||||||
use POSIX qw(strftime);
|
use POSIX qw(strftime);
|
||||||
|
use threads;
|
||||||
|
|
||||||
# Default lib dir for RPM and DEB packages
|
# Default lib dir for RPM and DEB packages
|
||||||
use lib '/usr/lib/perl5';
|
use lib '/usr/lib/perl5';
|
||||||
@ -37,10 +39,15 @@ use PandoraFMS::WMIServer;
|
|||||||
use PandoraFMS::PluginServer;
|
use PandoraFMS::PluginServer;
|
||||||
use PandoraFMS::PredictionServer;
|
use PandoraFMS::PredictionServer;
|
||||||
|
|
||||||
|
# Constants for Win32 services.
|
||||||
|
use constant WIN32_SERVICE_STOPPED => 0x01;
|
||||||
|
use constant WIN32_SERVICE_RUNNING => 0x04;
|
||||||
|
|
||||||
# Global vars
|
# Global vars
|
||||||
my %Config;
|
my %Config :shared;
|
||||||
my @Servers;
|
my @Servers;
|
||||||
my $DBH;
|
my $DBH;
|
||||||
|
my $RUN :shared = 1;
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
# Server shutdown. Handler to do a controlled shutdown.
|
# Server shutdown. Handler to do a controlled shutdown.
|
||||||
@ -243,7 +250,7 @@ sub pandora_server_tasks ($) {
|
|||||||
$pa_config->{'dbuser'}, $pa_config->{'dbpass'});
|
$pa_config->{'dbuser'}, $pa_config->{'dbpass'});
|
||||||
|
|
||||||
my $counter = 0;
|
my $counter = 0;
|
||||||
while (1) {
|
while ($RUN == 1) {
|
||||||
eval{
|
eval{
|
||||||
# TASKS EXECUTED EVERY 5 SECONDS (Low latency tasks)
|
# TASKS EXECUTED EVERY 5 SECONDS (Low latency tasks)
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
@ -331,134 +338,292 @@ sub pandora_server_tasks ($) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$SIG{'TERM'} = 'pandora_shutdown';
|
################################################################################
|
||||||
$SIG{'INT'} = 'pandora_shutdown';
|
## Install the Windows service.
|
||||||
|
################################################################################
|
||||||
|
sub win32_install_service() {
|
||||||
|
|
||||||
# Error handler needs to be reviewed, Enterprise not found errors are too nasty :(
|
# Load Win32::Daemon.
|
||||||
$SIG{__DIE__} = 'pandora_crash';
|
eval "use Win32::Daemon";
|
||||||
|
die($@) if ($@);
|
||||||
|
|
||||||
# Prevent alarm from bombing the main thread when called within a thread
|
# Configure and install the service.
|
||||||
$SIG{'ALRM'} = 'IGNORE';
|
my $service_path = $0;
|
||||||
|
my $service_params = "-S run \"$ARGV[0]\"";
|
||||||
# Initialize
|
my %service_hash = (
|
||||||
pandora_init(\%Config, 'Pandora FMS Server');
|
machine => '',
|
||||||
pandora_load_config (\%Config);
|
name => 'PANDORAFMSSRV',
|
||||||
|
display => 'Pandora FMS Server',
|
||||||
# Daemonize and put in background
|
path => $service_path,
|
||||||
if ($Config{'daemon'} == 1) {
|
user => '',
|
||||||
print_message (\%Config, " [*] Backgrounding Pandora FMS Server process.\n", 1);
|
pwd => '',
|
||||||
pandora_daemonize (\%Config);
|
description => 'Pandora FMS Server http://pandorafms.com/',
|
||||||
}
|
parameters => $service_params
|
||||||
|
);
|
||||||
# Load enterprise module
|
|
||||||
if (enterprise_load (\%Config) == 0) {
|
|
||||||
print_message (\%Config, " [*] Pandora FMS Enterprise module not available.", 1);
|
|
||||||
logger (\%Config, " [*] Pandora FMS Enterprise module not available.", 1);
|
|
||||||
} else {
|
|
||||||
print_message (\%Config, " [*] Pandora FMS Enterprise module loaded.", 1);
|
|
||||||
logger (\%Config, " [*] Pandora FMS Enterprise module loaded.", 1);
|
|
||||||
|
|
||||||
if($Config{'policy_manager'} == 1) {
|
|
||||||
# Start thread to patrol policy queue
|
|
||||||
threads->create('pandora_process_policy_queue', (\%Config))->detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
if($Config{'event_replication'} == 1) {
|
if (Win32::Daemon::CreateService(\%service_hash)) {
|
||||||
# Start thread to process event replication
|
print "Successfully added.\n";
|
||||||
threads->create('pandora_process_event_replication', (\%Config))->detach();
|
exit 0;
|
||||||
|
} else {
|
||||||
|
print "Failed to add service: " . Win32::FormatMessage(Win32::Daemon::GetLastError()) . "\n";
|
||||||
|
exit 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start the servers
|
################################################################################
|
||||||
pandora_startup ();
|
## Install the Windows service.
|
||||||
|
################################################################################
|
||||||
|
sub win32_uninstall_service() {
|
||||||
|
|
||||||
# Start thread to execute server tasks
|
# Load Win32::Daemon.
|
||||||
threads->create('pandora_server_tasks', (\%Config))->detach();
|
eval "use Win32::Daemon";
|
||||||
|
die($@) if ($@);
|
||||||
|
|
||||||
# Generate 'going up' events
|
# Uninstall the service.
|
||||||
foreach my $server (@Servers) {
|
if (Win32::Daemon::DeleteService('', 'PANDORAFMSSRV')) {
|
||||||
$server->upEvent ();
|
print "Successfully deleted.\n";
|
||||||
|
exit 0;
|
||||||
|
} else {
|
||||||
|
print "Failed to delete service: " . Win32::FormatMessage(Win32::Daemon::GetLastError()) . "\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if the Data Server has too many threads
|
################################################################################
|
||||||
if ($Config{'dataserver_threads'} > 5) {
|
## Windows service callback function for the running event.
|
||||||
logger (\%Config, "[W] Server " . $Config{'servername'} . " have configured " . $Config{'dataserver_threads'}
|
################################################################################
|
||||||
. " threads for the data server. You should not use more than 5 threads for this server", 1);
|
sub callback_running {
|
||||||
print_message (\%Config, " [W] Server " . $Config{'servername'} . " have configured " . $Config{'dataserver_threads'}
|
if (Win32::Daemon::State() == WIN32_SERVICE_RUNNING) {
|
||||||
. " threads for the data server. You should not use more than 5 threads for this server", 1);
|
}
|
||||||
pandora_event (\%Config, "Server " . $Config{'servername'} . " have configured "
|
|
||||||
. $Config{'dataserver_threads'} . " threads for the data server", 0, 0, 3, 0, 0, 'system', 0, $DBH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if the Pandora Server has too many threads
|
################################################################################
|
||||||
my $totalThreads = 0;
|
## Windows service callback function for the start event.
|
||||||
foreach my $server (@Servers) {
|
################################################################################
|
||||||
$totalThreads += $server->getNumThreads ();
|
sub callback_start {
|
||||||
}
|
no strict;
|
||||||
if ($totalThreads > 40) {
|
|
||||||
logger (\%Config, '[W] Server ' . $Config{'servername'} . ' have configured a total of ' . $totalThreads
|
# Accept_connections ();
|
||||||
. ' threads. This setup is not recommended, you should reduce the number of total threads below 40', 1);
|
my $thr = threads->create(\&main);
|
||||||
print_message (\%Config, ' [W] Server ' . $Config{'servername'} . ' have configured a total of ' . $totalThreads
|
if (!defined($thr)) {
|
||||||
. ' threads. This setup is not recommended, you should reduce the number of total threads below 40', 1);
|
Win32::Daemon::State(WIN32_SERVICE_STOPPED);
|
||||||
pandora_event (\%Config, 'Server ' . $Config{'servername'} . ' have configured a total of ' . $totalThreads
|
Win32::Daemon::StopService();
|
||||||
. ' threads', 0, 0, 3, 0, 0, 'system', 0, $DBH);
|
return;
|
||||||
|
}
|
||||||
|
$thr->detach();
|
||||||
|
|
||||||
|
Win32::Daemon::State(WIN32_SERVICE_RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if the log verbosity is set to 10
|
################################################################################
|
||||||
if ($Config{'verbosity'} == 10) {
|
## Windows service callback function for the stop event.
|
||||||
logger (\%Config, '[W] Log verbosity is set to 10. This will degrade the server performance. Please set to a lower value ASAP', 1);
|
################################################################################
|
||||||
print_message (\%Config, ' [W] Log verbosity is set to 10. This will degrade the server performance. Please set to a lower value ASAP', 1);
|
sub callback_stop {
|
||||||
pandora_event (\%Config, 'Log verbosity is set to 10. This will degrade the server performance', 0, 0, 1, 0, 0, 'system', 0, $DBH);
|
|
||||||
|
$RUN = 0;
|
||||||
|
Win32::Daemon::State(WIN32_SERVICE_STOPPED);
|
||||||
|
Win32::Daemon::StopService();
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main loop
|
################################################################################
|
||||||
my $time_ref = time ();
|
# Run as a Windows service.
|
||||||
while (1) {
|
################################################################################
|
||||||
|
sub win32_service_run() {
|
||||||
eval {
|
|
||||||
|
# Load Win32::Daemon.
|
||||||
# Update server status
|
eval "use Win32::Daemon";
|
||||||
foreach my $server (@Servers) {
|
die($@) if ($@);
|
||||||
die ($server->getErrStr ()) unless ($server->checkThreads () == 1);
|
|
||||||
$server->update();
|
# Run the Pandora FMS Server as a Windows service.
|
||||||
|
Win32::Daemon::RegisterCallbacks({
|
||||||
|
start => \&callback_start,
|
||||||
|
running => \&callback_running,
|
||||||
|
stop => \&callback_stop,
|
||||||
|
});
|
||||||
|
Win32::Daemon::StartService();
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
## Parse command line options.
|
||||||
|
################################################################################
|
||||||
|
sub parse_options {
|
||||||
|
my %opts;
|
||||||
|
my $tmp;
|
||||||
|
my @t_addresses_tmp;
|
||||||
|
|
||||||
|
# Get options
|
||||||
|
if (getopts('S:', \%opts) == 0 || defined ($opts{'h'})) {
|
||||||
|
print_help ();
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Win32 service management
|
||||||
|
if (defined ($opts{'S'})) {
|
||||||
|
my $service_action = $opts{'S'};
|
||||||
|
if ($^O ne 'MSWin32') {
|
||||||
|
error ("Windows services are only available on Win32.");
|
||||||
|
} else {
|
||||||
|
eval "use Win32::Daemon";
|
||||||
|
die($@) if ($@);
|
||||||
|
|
||||||
|
if ($service_action eq 'install') {
|
||||||
|
win32_install_service();
|
||||||
|
} elsif ($service_action eq 'uninstall') {
|
||||||
|
win32_uninstall_service();
|
||||||
|
} elsif ($service_action eq 'run') {
|
||||||
|
win32_service_run;
|
||||||
|
} else {
|
||||||
|
error("Unknown action: $service_action");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Not needed. The console assumes a server is down if it has not updated its status in the last 15 minutes.
|
################################################################
|
||||||
## Update fallen servers
|
################################################################
|
||||||
#db_do ($DBH, "UPDATE tserver SET status = 0 WHERE keepalive < ?", strftime ("%Y-%m-%d %H:%M:%S", localtime(time() - $Config{'keepalive'})));
|
## Main.
|
||||||
};
|
################################################################
|
||||||
|
################################################################
|
||||||
|
sub main() {
|
||||||
|
|
||||||
|
$SIG{'TERM'} = 'pandora_shutdown';
|
||||||
|
$SIG{'INT'} = 'pandora_shutdown';
|
||||||
|
|
||||||
# Restart on error or auto restart
|
# Error handler needs to be reviewed, Enterprise not found errors are too nasty :(
|
||||||
if ($@) {
|
$SIG{__DIE__} = 'pandora_crash';
|
||||||
|
|
||||||
if ($Config{'restart'} eq '0') {
|
# Prevent alarm from bombing the main thread when called within a thread
|
||||||
print_message (\%Config, $@, 1);
|
$SIG{'ALRM'} = 'IGNORE';
|
||||||
pandora_shutdown ();
|
|
||||||
|
# Initialize
|
||||||
|
pandora_init(\%Config, 'Pandora FMS Server');
|
||||||
|
pandora_load_config (\%Config);
|
||||||
|
|
||||||
|
# Daemonize and put in background
|
||||||
|
if ($Config{'daemon'} == 1) {
|
||||||
|
print_message (\%Config, " [*] Backgrounding Pandora FMS Server process.\n", 1);
|
||||||
|
pandora_daemonize (\%Config);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load enterprise module
|
||||||
|
if (enterprise_load (\%Config) == 0) {
|
||||||
|
print_message (\%Config, " [*] Pandora FMS Enterprise module not available.", 1);
|
||||||
|
logger (\%Config, " [*] Pandora FMS Enterprise module not available.", 1);
|
||||||
|
} else {
|
||||||
|
print_message (\%Config, " [*] Pandora FMS Enterprise module loaded.", 1);
|
||||||
|
logger (\%Config, " [*] Pandora FMS Enterprise module loaded.", 1);
|
||||||
|
|
||||||
|
if($Config{'policy_manager'} == 1) {
|
||||||
|
# Start thread to patrol policy queue
|
||||||
|
threads->create('pandora_process_policy_queue', (\%Config))->detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate 'restarting' events
|
if($Config{'event_replication'} == 1) {
|
||||||
foreach my $server (@Servers) {
|
# Start thread to process event replication
|
||||||
$server->restartEvent ($@);
|
threads->create('pandora_process_event_replication', (\%Config))->detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
logger (\%Config, 'Pandora FMS Server restarting (' . $@ . ') in ' . $Config{'restart_delay'} . ' seconds.', 1);
|
|
||||||
pandora_restart ();
|
|
||||||
}
|
|
||||||
elsif (($Config{'auto_restart'} > 0) && (time () - $time_ref > $Config{'auto_restart'})) {
|
|
||||||
$time_ref = time ();
|
|
||||||
|
|
||||||
# Mute
|
|
||||||
open(OLDOUT, ">&STDOUT");
|
|
||||||
open (STDOUT, '>/dev/null');
|
|
||||||
|
|
||||||
# Restart
|
|
||||||
pandora_restart ();
|
|
||||||
|
|
||||||
# Unmute
|
|
||||||
open(STDOUT, ">&OLDOUT");
|
|
||||||
close (OLDOUT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
threads->yield;
|
# Start the servers
|
||||||
sleep ($Config{'server_threshold'});
|
pandora_startup ();
|
||||||
|
|
||||||
|
# Start thread to execute server tasks
|
||||||
|
threads->create('pandora_server_tasks', (\%Config))->detach();
|
||||||
|
|
||||||
|
# Generate 'going up' events
|
||||||
|
foreach my $server (@Servers) {
|
||||||
|
$server->upEvent ();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the Data Server has too many threads
|
||||||
|
if ($Config{'dataserver_threads'} > 5) {
|
||||||
|
logger (\%Config, "[W] Server " . $Config{'servername'} . " have configured " . $Config{'dataserver_threads'}
|
||||||
|
. " threads for the data server. You should not use more than 5 threads for this server", 1);
|
||||||
|
print_message (\%Config, " [W] Server " . $Config{'servername'} . " have configured " . $Config{'dataserver_threads'}
|
||||||
|
. " threads for the data server. You should not use more than 5 threads for this server", 1);
|
||||||
|
pandora_event (\%Config, "Server " . $Config{'servername'} . " have configured "
|
||||||
|
. $Config{'dataserver_threads'} . " threads for the data server", 0, 0, 3, 0, 0, 'system', 0, $DBH);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the Pandora Server has too many threads
|
||||||
|
my $totalThreads = 0;
|
||||||
|
foreach my $server (@Servers) {
|
||||||
|
$totalThreads += $server->getNumThreads ();
|
||||||
|
}
|
||||||
|
if ($totalThreads > 40) {
|
||||||
|
logger (\%Config, '[W] Server ' . $Config{'servername'} . ' have configured a total of ' . $totalThreads
|
||||||
|
. ' threads. This setup is not recommended, you should reduce the number of total threads below 40', 1);
|
||||||
|
print_message (\%Config, ' [W] Server ' . $Config{'servername'} . ' have configured a total of ' . $totalThreads
|
||||||
|
. ' threads. This setup is not recommended, you should reduce the number of total threads below 40', 1);
|
||||||
|
pandora_event (\%Config, 'Server ' . $Config{'servername'} . ' have configured a total of ' . $totalThreads
|
||||||
|
. ' threads', 0, 0, 3, 0, 0, 'system', 0, $DBH);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the log verbosity is set to 10
|
||||||
|
if ($Config{'verbosity'} == 10) {
|
||||||
|
logger (\%Config, '[W] Log verbosity is set to 10. This will degrade the server performance. Please set to a lower value ASAP', 1);
|
||||||
|
print_message (\%Config, ' [W] Log verbosity is set to 10. This will degrade the server performance. Please set to a lower value ASAP', 1);
|
||||||
|
pandora_event (\%Config, 'Log verbosity is set to 10. This will degrade the server performance', 0, 0, 1, 0, 0, 'system', 0, $DBH);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main loop
|
||||||
|
my $time_ref = time ();
|
||||||
|
while ($RUN == 1) {
|
||||||
|
|
||||||
|
eval {
|
||||||
|
|
||||||
|
# Update server status
|
||||||
|
foreach my $server (@Servers) {
|
||||||
|
die ($server->getErrStr ()) unless ($server->checkThreads () == 1);
|
||||||
|
$server->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Not needed. The console assumes a server is down if it has not updated its status in the last 15 minutes.
|
||||||
|
## Update fallen servers
|
||||||
|
#db_do ($DBH, "UPDATE tserver SET status = 0 WHERE keepalive < ?", strftime ("%Y-%m-%d %H:%M:%S", localtime(time() - $Config{'keepalive'})));
|
||||||
|
};
|
||||||
|
|
||||||
|
# Restart on error or auto restart
|
||||||
|
if ($@) {
|
||||||
|
|
||||||
|
if ($Config{'restart'} eq '0') {
|
||||||
|
print_message (\%Config, $@, 1);
|
||||||
|
pandora_shutdown ();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate 'restarting' events
|
||||||
|
foreach my $server (@Servers) {
|
||||||
|
$server->restartEvent ($@);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger (\%Config, 'Pandora FMS Server restarting (' . $@ . ') in ' . $Config{'restart_delay'} . ' seconds.', 1);
|
||||||
|
pandora_restart ();
|
||||||
|
}
|
||||||
|
elsif (($Config{'auto_restart'} > 0) && (time () - $time_ref > $Config{'auto_restart'})) {
|
||||||
|
$time_ref = time ();
|
||||||
|
|
||||||
|
# Mute
|
||||||
|
open(OLDOUT, ">&STDOUT");
|
||||||
|
open (STDOUT, '>/dev/null');
|
||||||
|
|
||||||
|
# Restart
|
||||||
|
pandora_restart ();
|
||||||
|
|
||||||
|
# Unmute
|
||||||
|
open(STDOUT, ">&OLDOUT");
|
||||||
|
close (OLDOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
threads->yield;
|
||||||
|
sleep ($Config{'server_threshold'});
|
||||||
|
}
|
||||||
|
|
||||||
|
pandora_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Parse command line options.
|
||||||
|
parse_options;
|
||||||
|
|
||||||
|
# Run as a regular process.
|
||||||
|
main();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user