#!/usr/bin/perl # # $Id: loncontrol,v 1.34.2.1 2010/01/13 19:26:54 raeburn Exp $ # # The LearningOnline Network with CAPA # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # # Startup script for the LON-CAPA network processes # # chkconfig: 345 95 5 # description: LON-CAPA is a "network of knowledge". It is used to \ # distribute knowledge resources and instructional management. # processnames: lonc, lond, lonsql, lonmaxima # pidfiles: /home/httpd/perl/logs/lon*.pid # config: /etc/httpd/conf/loncapa.conf # config: /home/httpd/lonTabs/hosts.tab # config: /home/httpd/lonTabs/spare.tab # SuSE chkconfig/insserv info ### BEGIN INIT INFO # Provides: loncapa # Required-Start: mysql apache2 $network $remote_fs # Required-Stop: # Default-Start: 3 4 5 # Default-Stop: # Description: Starts the LON-CAPA services ### END INIT INFO use strict; use lib '/home/httpd/lib/perl/'; use LONCAPA::Configuration; my $command=$ARGV[0]; $command=~s/[^a-z]//g; $ENV{'PATH'}="/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin"; $ENV{'BASH_ENV'}=""; { # Firewall variable scoping # Firewall code is based on the code in FC2 /etc/init.d/ntpd my $fw_chain = 'RH-Firewall-1-INPUT'; my $iptables = '/sbin/iptables'; if (! -e $iptables) { $iptables = '/usr/sbin/iptables'; if (!-e $iptables) { print("Unable to find iptables command\n"); } } my $suse_config = "/etc/sysconfig/SuSEfirewall2"; if (-e $suse_config) { $fw_chain = 'input_ext'; } else { if (!-e '/etc/sysconfig/iptables') { print("Unable to find iptables file containing static definitions\n"); } } if (-e $iptables) { my $count = `$iptables -L -n 2>/dev/null |grep $fw_chain |wc -l`; chomp($count); if (!$count) { $fw_chain ='INPUT'; } } my $lond_port = &get_lond_port(); if (!$lond_port) { print("Unable to determine lond port number from LON-CAPA configuration.\n"); } sub firewall_open_port { return 'inactive firewall' if (! &firewall_is_active); return 'port number unknown' if !$lond_port; my @opened; my $suse_config = "/etc/sysconfig/SuSEfirewall2"; if (-e $suse_config) { if (open(my $fh,"<$suse_config")) { while(<$fh>) { chomp(); if (/^FW_SERVICES_EXT_TCP="([^"]+)"\s*$/) { my $portstr = $1; my @suseports = split(/\s+/,$portstr); foreach my $port ($lond_port) { if (grep/^\Q$port\E$/,@suseports) { push(@opened,$port); } } } } } } else { if (! `$iptables -L -n 2>/dev/null | grep $fw_chain | wc -l`) { return 'chain error'; } # iptables is running with our chain # # We could restrict the servers allowed to attempt to communicate # here, but the logistics of updating the /home/httpd/lonTabs/host.tab # file are likely to be a problem foreach my $port ($lond_port) { print "Opening firewall access on port $port.\n"; my $result; my $firewall_command = "$iptables -I $fw_chain -p tcp -d 0/0 --dport $port -j ACCEPT"; system($firewall_command); my $return_status = $?>>8; if ($return_status == 1) { # Error print "Error opening port.\n"; } elsif ($return_status == 2) { # Bad command print "Bad command error opening port. Command was\n". " ".$firewall_command."\n"; } elsif ($return_status == 0) { push(@opened,$port); } } } foreach my $port ($lond_port) { if (!grep(/^\Q$port\E$/,@opened)) { return 'Required port not open: '.$port."\n"; } } return 'ok'; } sub firewall_is_port_open { my ($port) = @_; # returns 1 if the firewall port is open, 0 if not. # # check if firewall is active or installed return if (! &firewall_is_active); if (`$iptables -L -n 2>/dev/null | grep "tcp dpt:$port"`) { return 1; } else { return 0; } } sub firewall_is_active { if (-e '/proc/net/ip_tables_names') { return 1; } else { return 0; } } sub firewall_close_port { return 'inactive firewall' if (! &firewall_is_active); return 'port number unknown' if !$lond_port; my $suse_config = "/etc/sysconfig/SuSEfirewall2"; return if (-e $suse_config); foreach my $port ($lond_port) { print "Closing firewall access on port $port\n"; my $firewall_command = "$iptables -D $fw_chain -p tcp -d 0/0 --dport $port -j ACCEPT"; system($firewall_command); my $return_status = $?>>8; if ($return_status == 1) { # Error print "Error closing port.\n"; } elsif ($return_status == 2) { # Bad command print "Bad command error closing port. Command was\n". " ".$firewall_command."\n"; } else { print "Port closed.\n"; } } return; } sub get_lond_port { my $perlvarref=&LONCAPA::Configuration::read_conf(); my $lond_port; if (ref($perlvarref) eq 'HASH') { if (defined($perlvarref->{'londPort'})) { $lond_port = $perlvarref->{'londPort'}; } } return $lond_port; } } # End firewall variable scope sub stop_daemon { my ($daemon,$killallname)=@_; my $pidfile="/home/httpd/perl/logs/$daemon.pid"; printf("%-15s ",$daemon); if (-e $pidfile) { open(PIDFILE,$pidfile); my $daemonpid=; chomp($daemonpid); kill TERM => $daemonpid; my $count=0; while ($count++ < 5 && kill(0 => $daemonpid)) { sleep 1; } if (kill 0 => $daemonpid) { kill KILL => $daemonpid; sleep 1; if (kill 0 => $daemonpid) { print("failed to kill"); } else { print("killed"); } } else { print("stopped"); } } else { print("not running"); } system("killall -q -0 $killallname"); if ($? == 0) { system("killall -q $killallname"); print(", killed off extraneous processes"); } unlink($pidfile); print("\n"); } sub clean_sockets { opendir(SOCKETS,"/home/httpd/sockets/"); my $perlvarref=&LONCAPA::Configuration::read_conf(); return if (ref($perlvarref) ne 'HASH'); while (my $fname=readdir(SOCKETS)) { next if (-d $fname || $fname=~/(mysqlsock|maximasock|\Q$perlvarref->{'lonSockDir'}\E)/); unlink("/home/httpd/sockets/$fname"); } } if ($command eq "restart") { print 'Restarting LON-CAPA'."\n"; print 'Ending LON-CAPA client and daemon processes'."\n"; foreach my $daemon ('lonsql','lond','lonc','lonmemcached','lonmaxima') { my $killallname=$daemon; if ($daemon eq 'lonc') { $killallname='loncnew'; } &stop_daemon($daemon,$killallname); } print 'Starting LON-CAPA client and daemon processes (please be patient)'. "\n"; system("su www -c '/home/httpd/perl/loncron --justcheckdaemons'"); } elsif ($command eq "stop") { print 'Stopping LON-CAPA'."\n"; foreach my $daemon ('lonsql','lond','lonc','lonmemcached','lonmaxima') { my $killallname=$daemon; if ($daemon eq 'lonc') { $killallname='loncnew'; } &stop_daemon($daemon,$killallname); } my $firewall_result = &firewall_close_port(); if ($firewall_result) { print "$firewall_result\n"; } &clean_sockets(); } elsif ($command eq "start") { my $firewall_result = &firewall_open_port(); if (($firewall_result eq 'ok') || ($firewall_result eq 'inactive firewall')) { if ($firewall_result eq 'inactive firewall') { print "WARNING: iptables firewall is currently inactive\n"; } print 'Starting LON-CAPA'."\n"; print 'Starting LON-CAPA client and daemon processes (please be patient)'. "\n"; system("su www -c '/home/httpd/perl/loncron --justcheckdaemons'"); } else { print "Not starting LON-CAPA\n"; if ($firewall_result eq 'port number unknown') { print "Could not check for status of LON-CAPA port in running firewall - port number unknown. \n"; } elsif ($firewall_result) { print "$firewall_result\n"; } } } elsif ($command eq "reload") { print 'Reload LON-CAPA config files'."\n"; system("su www -c '/home/httpd/perl/loncron --justreload'"); } elsif ($command eq "status") { my $lond_port = &get_lond_port(); my $response=`/bin/cat /home/httpd/perl/logs/*.pid 2>&1`; if ($response=~/No such file or directory/) { print 'LON-CAPA is not running.'."\n"; } else { print 'LON-CAPA is running.'."\n"; system("su www -c '/home/httpd/perl/loncron --justcheckconnections'"); } if (! &firewall_is_active) { print 'The iptables firewall is not active'."\n"; } my $lond_port = &get_lond_port(); if ($lond_port) { if (&firewall_is_port_open($lond_port)) { print "The LON-CAPA port ($lond_port) is open in firewall.\n"; } elsif (&firewall_is_active) { print "The LON-CAPA port ($lond_port) is NOT open in running firewall!\n"; } } else { if (&firewall_is_active) { print "Could not check for status of LON-CAPA port in running firewall - port number unknown.\n"; } else { print "LON-CAPA port number is unknown, and firewall is not running.\n"; } } } else { print "You need to specify one of restart|stop|start|status on the command line.\n"; }