]> git.proxmox.com Git - pve-firewall.git/commitdiff
use Daemon class from pve-common
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 16 Dec 2014 11:15:43 +0000 (12:15 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 18 Dec 2014 08:41:48 +0000 (09:41 +0100)
debian/pve-firewall.init
src/pve-firewall

index dcd1dfffaf0534796aa0f54c52b7f837915d3804..062dfa4b57d011a9be60c44541de5e2c51188769 100755 (executable)
@@ -55,12 +55,8 @@ case "$1" in
        ;;
     reload|restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
-       if ( [ -e $PIDFILE ] && kill -0 `cat $PIDFILE`) then
-           start-stop-daemon --stop --quiet --pidfile $PIDFILE --signal HUP
-       else
-           $DAEMON start
-       fi
-       log_end_msg $?
+       $DAEMON restart
+       log_end_msg $?
        ;;
     *)
        N=/etc/init.d/$NAME
index e7a2337c4c9da59c19c4eda999b369303ef62a8c..038afc409e0e2ce2ae9c4e31ea321c786cd572db 100755 (executable)
@@ -3,11 +3,11 @@
 use strict;
 use warnings;
 use PVE::SafeSyslog;
-use POSIX ":sys_wait_h";
-use Fcntl ':flock';
-use Getopt::Long;
+use PVE::Daemon;
+
 use Time::HiRes qw (gettimeofday);
 use PVE::Tools qw(dir_glob_foreach file_read_firstline);
+use PVE::ProcFSTools;
 use PVE::INotify;
 use PVE::Cluster qw(cfs_read_file);
 use PVE::RPCEnvironment;
@@ -16,26 +16,13 @@ use PVE::Firewall;
 use PVE::FirewallSimulator;
 use Data::Dumper;
 
-use base qw(PVE::CLIHandler);
-
-my $pve_firewall_pidfile = "/var/run/pve-firewall.pid";
-
-$SIG{'__WARN__'} = sub {
-    my $err = $@;
-    my $t = $_[0];
-    chomp $t;
-    print "$t\n";
-    syslog('warning', "WARNING: %s", $t);
-    $@ = $err;
-};
+use base qw(PVE::Daemon);
 
-initlog('pve-firewall');
+my $cmdline = [$0, @ARGV];
 
-$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
+my %daemon_options = (restart_on_error => 5, stop_wait_time => 5);
 
-die "please run as root\n" if $> != 0;
-
-PVE::INotify::inotify_init();
+my $daemon = __PACKAGE__->new('pve-firewall', $cmdline, %daemon_options);
 
 my $rpcenv = PVE::RPCEnvironment->init('cli');
 
@@ -45,58 +32,11 @@ $rpcenv->set_user('root@pam');
 
 my $nodename = PVE::INotify::nodename();
 
-my $commandline = [$0, @ARGV];
-
-$0 = "pve-firewall";
-
-sub restart_server {
-    my ($waittime) = @_;
-
-    syslog('info', "server shutdown (restart)");
-
-    $ENV{RESTART_PVE_FIREWALL} = 1;
-
-    sleep($waittime) if $waittime; # avoid high server load due to restarts
-
-    PVE::INotify::inotify_close();
-
-    exec (@$commandline);
-    exit (-1); # never reached?
-}
-
-sub cleanup {
-    unlink "$pve_firewall_pidfile.lock";
-    unlink $pve_firewall_pidfile;
-}
-
-sub lockpidfile {
-    my $pidfile = shift;
-    my $lkfn = "$pidfile.lock";
-
-    if (!open (FLCK, ">>$lkfn")) {
-       my $msg = "can't aquire lock on file '$lkfn' - $!";
-       syslog ('err', $msg);
-       die "ERROR: $msg\n";
-    }
-
-    if (!flock (FLCK, LOCK_EX|LOCK_NB)) {
-       close (FLCK);
-        my $msg = "can't aquire lock '$lkfn' - $!";
-       syslog ('err', $msg);
-       die "ERROR: $msg\n";
-    }
-}
-
-sub writepidfile {
-    my $pidfile = shift;
+sub init {
 
-    if (!open (PIDFH, ">$pidfile")) {
-       my $msg = "can't open pid file '$pidfile' - $!";
-       syslog ('err', $msg);
-       die "ERROR: $msg\n";
-    } 
-    print PIDFH "$$\n";
-    close (PIDFH);
+    PVE::Cluster::cfs_update();
+    
+    PVE::Firewall::init();
 }
 
 my $restart_request = 0;
@@ -107,194 +47,88 @@ my $updatetime = 10;
 
 my $initial_memory_usage;
 
-sub run_server {
-    my ($param) = @_;
+sub shutdown {
+    my ($self) = @_;
 
-    # try to get the lock
-    lockpidfile($pve_firewall_pidfile);
+    syslog('info' , "server closing");
 
-    # run in background
-    my $spid;
-
-    my $restart = $ENV{RESTART_PVE_FIREWALL};
-
-    delete $ENV{RESTART_PVE_FIREWALL};
-
-    PVE::Cluster::cfs_update();
-    
-    PVE::Firewall::init();
-
-    if (!$param->{debug}) {
-       open STDIN,  '</dev/null' || die "can't read /dev/null";
-       open STDOUT, '>/dev/null' || die "can't write /dev/null";
-    }
-
-    if (!$restart && !$param->{debug}) {
-       $spid = fork();
-       if (!defined ($spid)) {
-           my $msg =  "can't put server into background - fork failed";
-           syslog('err', $msg);
-           die "ERROR: $msg\n";
-       } elsif ($spid) { # parent
-           exit (0);
-       }
-    } 
-
-    writepidfile($pve_firewall_pidfile);
-
-    open STDERR, '>&STDOUT' || die "can't close STDERR\n";
-    $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = sub { 
-       syslog('info' , "server closing");
-
-       $SIG{INT} = 'DEFAULT';
-
-       # wait for children
-       1 while (waitpid(-1, POSIX::WNOHANG()) > 0);
+    # wait for children
+    1 while (waitpid(-1, POSIX::WNOHANG()) > 0);
        
-       syslog('info' , "clear firewall rules");
-       eval { PVE::Firewall::remove_pvefw_chains(); die "STOP";};
-       warn $@ if $@;
-
-       cleanup();
-
-       exit (0);
-    };
-
-    $SIG{HUP} = sub {
-       # wake up process, so this forces an immediate firewall rules update
-       syslog('info' , "received signal HUP (restart)");
-       $restart_request = 1;
-    };
-
-    if ($restart) {
-       syslog('info' , "restarting server");
-    } else {
-       syslog('info' , "starting server");
-    }
-
-    for (;;) { # forever
-
-       eval {
-
-           local $SIG{'__WARN__'} = 'IGNORE'; # do not fill up logs
+    syslog('info' , "clear firewall rules");
 
-           $next_update = time() + $updatetime;
+    eval { PVE::Firewall::remove_pvefw_chains(); };
+    warn $@ if $@;
 
-           my ($ccsec, $cusec) = gettimeofday ();
-           eval {
-               PVE::Cluster::cfs_update();
-               PVE::Firewall::update();
-           };
-           my $err = $@;
+    $self->exit_daemon(0);
+}
 
-           if ($err) {
-               syslog('err', "status update error: $err");
-           }
+sub hup {
+    my ($self) = @_;
 
-           my ($ccsec_end, $cusec_end) = gettimeofday ();
-           my $cptime = ($ccsec_end-$ccsec) + ($cusec_end - $cusec)/1000000;
+    syslog('info' , "received signal HUP");
 
-           syslog('info', sprintf("firewall update time (%.3f seconds)", $cptime))
-               if ($cptime > 5);
+    $restart_request = 1;
+}
 
-           $cycle++;
+sub run {
+    my ($self) = @_;
 
-           my $mem = PVE::ProcFSTools::read_memory_usage();
+    local $SIG{'__WARN__'} = 'IGNORE'; # do not fill up logs
 
-           if (!defined($initial_memory_usage) || ($cycle < 10)) {
-               $initial_memory_usage = $mem->{resident};
-           } else {
-               my $diff = $mem->{resident} - $initial_memory_usage;
-               if ($diff > 5*1024*1024) {
-                   syslog ('info', "restarting server after $cycle cycles to " .
-                           "reduce memory usage (free $mem->{resident} ($diff) bytes)");
-                   restart_server();
-               }
-           }
+    for (;;) { # forever
 
-           my $wcount = 0;
-           while ((time() < $next_update) && 
-                  ($wcount < $updatetime) && # protect against time wrap
-                  !$restart_request) { $wcount++; sleep (1); };
+       $next_update = time() + $updatetime;
 
-           restart_server() if $restart_request;
+       my ($ccsec, $cusec) = gettimeofday ();
+       eval {
+           PVE::Cluster::cfs_update();
+           PVE::Firewall::update();
        };
-
        my $err = $@;
-    
+       
        if ($err) {
-           syslog ('err', "ERROR: $err");
-           restart_server(5);
-           exit (0);
+           syslog('err', "status update error: $err");
        }
-    }
-}
 
-__PACKAGE__->register_method ({
-    name => 'start',
-    path => 'start',
-    method => 'POST',
-    description => "Start the Proxmox VE firewall service.",
-    parameters => {
-       additionalProperties => 0,
-       properties => {
-           debug => {
-               description => "Debug mode - stay in foreground",
-               type => "boolean",
-               optional => 1,
-               default => 0,
-           },
-       },
-    },
-    returns => { type => 'null' },
+       my ($ccsec_end, $cusec_end) = gettimeofday ();
+       my $cptime = ($ccsec_end-$ccsec) + ($cusec_end - $cusec)/1000000;
 
-    code => sub {
-       my ($param) = @_;
+       syslog('info', sprintf("firewall update time (%.3f seconds)", $cptime))
+           if ($cptime > 5);
 
-       run_server($param);
+       $cycle++;
 
-       return undef;
-    }});
-
-__PACKAGE__->register_method ({
-    name => 'stop',
-    path => 'stop',
-    method => 'POST',
-    description => "Stop firewall. This removes all Proxmox VE related iptable rules. The host is unprotected afterwards.",
-    parameters => {
-       additionalProperties => 0,
-       properties => {},
-    },
-    returns => { type => 'null' },
-
-    code => sub {
-       my ($param) = @_;
-
-       my $pid = int(PVE::Tools::file_read_firstline($pve_firewall_pidfile) || 0);
-
-       if ($pid) {
-           if (PVE::ProcFSTools::check_process_running($pid)) {
-               kill(15, $pid); # send TERM signal
-               # give max 5 seconds to shut down
-               for (my $i = 0; $i < 5; $i++) {
-                   last if !PVE::ProcFSTools::check_process_running($pid);
-                   sleep (1);
-               }
-       
-               # to be sure
-               kill(9, $pid); 
-               waitpid($pid, 0);
-           }
-           if (-f $pve_firewall_pidfile) {
-               # try to get the lock
-               lockpidfile($pve_firewall_pidfile);
-               cleanup();
+       my $mem = PVE::ProcFSTools::read_memory_usage();
+       
+       if (!defined($initial_memory_usage) || ($cycle < 10)) {
+           $initial_memory_usage = $mem->{resident};
+       } else {
+           my $diff = $mem->{resident} - $initial_memory_usage;
+           if ($diff > 5*1024*1024) {
+               syslog ('info', "restarting server after $cycle cycles to " .
+                       "reduce memory usage (free $mem->{resident} ($diff) bytes)");
+               $self->restart_daemon();
            }
        }
 
-       return undef;
-    }});
+       my $wcount = 0;
+       while ((time() < $next_update) && 
+              ($wcount < $updatetime) && # protect against time wrap
+              !$restart_request) { $wcount++; sleep (1); };
+       
+       $self->restart_daemon() if $restart_request;
+    }
+}
+
+$daemon->register_start_command(__PACKAGE__,
+                               "Start the Proxmox VE firewall service.");
+$daemon->register_restart_command(__PACKAGE__,
+                                 "Restart the Proxmox VE firewall service.");
+$daemon->register_stop_command(__PACKAGE__,
+                              "Stop firewall. This removes all Proxmox VE " .
+                              "related iptable rules. " .
+                              "The host is unprotected afterwards.");
 
 __PACKAGE__->register_method ({
     name => 'status',
@@ -331,10 +165,7 @@ __PACKAGE__->register_method ({
 
        my $code = sub {
 
-           my $pid = int(PVE::Tools::file_read_firstline($pve_firewall_pidfile) || 0);
-           my $running = PVE::ProcFSTools::check_process_running($pid);
-
-           my $status = $running ? 'running' : 'stopped';
+           my $status = $daemon->running() ? 'running' : 'stopped';
 
            my $res = { status => $status };
 
@@ -557,6 +388,7 @@ __PACKAGE__->register_method ({
 
 my $cmddef = {
     start => [ __PACKAGE__, 'start', []],
+    restart => [ __PACKAGE__, 'restart', []],
     stop => [ __PACKAGE__, 'stop', []],
     compile => [ __PACKAGE__, 'compile', []],
     simulate => [ __PACKAGE__, 'simulate', []],