]> git.proxmox.com Git - pve-common.git/blobdiff - data/PVE/Daemon.pm
Daemon: move ENV manipulation into new()
[pve-common.git] / data / PVE / Daemon.pm
index 757c2d17b0b6bfd06632d49198070b3594f6bfab..752522940aa6170cf1bcf45e5380d6a93b5da3d7 100644 (file)
@@ -35,19 +35,52 @@ $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
 
 my $daemon_initialized = 0; # we only allow one instance
 
+my $close_daemon_lock = sub {
+    my ($self) = @_;
+
+    return if !$self->{daemon_lock_fh};
+
+    close $self->{daemon_lock_fh};
+    delete $self->{daemon_lock_fh};
+};
+
+# call this if you fork() from child
+# Note: we already call this for workers, so it is only required
+# if you fork inside a simple daemon (max_workers == 0).
+sub after_fork_cleanup {
+    my ($self) = @_;
+
+    &$close_daemon_lock($self);
+
+    PVE::INotify::inotify_close();
+
+    for my $sig (qw(CHLD HUP INT TERM QUIT)) {
+       $SIG{$sig} = 'DEFAULT'; # restore default handler
+       # AnyEvent signals only works if $SIG{XX} is 
+       # undefined (perl event loop)
+       delete $SIG{$sig}; # so that we can handle events with AnyEvent
+    }
+}
+
 my $lockpidfile = sub {
     my ($self) = @_;
 
     my $lkfn = $self->{pidfile} . ".lock";
 
-    if (!open (FLCK, ">>$lkfn")) {
+    $self->{daemon_lock_fh} = IO::File->new(">>$lkfn");
+    if (!$self->{daemon_lock_fh}) {
        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);
+    for (my $i = 0; $i < 5; $i ++) {
+       return if flock ($self->{daemon_lock_fh}, LOCK_EX|LOCK_NB);
+       sleep(1);
+    }
+
+    if (!flock ($self->{daemon_lock_fh}, LOCK_EX|LOCK_NB)) {
+       &$close_daemon_lock($self);
         my $msg = "can't aquire lock '$lkfn' - $!";
        syslog ('err', $msg);
        die "ERROR: $msg\n";
@@ -116,16 +149,7 @@ my $start_workers = sub {
        } else {
            $0 = "$self->{name} worker";
 
-           close(FLCK);
-
-           PVE::INotify::inotify_close();
-
-           for my $sig (qw(CHLD HUP INT TERM QUIT)) {
-               $SIG{$sig} = 'DEFAULT'; # restore default handler
-               # AnyEvent signals only works if $SIG{XX} is 
-               # undefined (perl event loop)
-               delete $SIG{$sig}; # so that we can handle events with AnyEvent
-           }
+           $self->after_fork_cleanup();
 
            eval { $self->run(); };
            if (my $err = $@) {
@@ -198,10 +222,6 @@ my $server_run = sub {
     # run in background
     my $spid;
 
-    my $restart = $ENV{RESTART_PVE_DAEMON};
-
-    delete $ENV{RESTART_PVE_DAEMON};
-
     $self->{debug} = 1 if $debug;
 
     $self->init();
@@ -211,7 +231,7 @@ my $server_run = sub {
        open STDOUT, '>/dev/null' || die "can't write /dev/null";
     }
 
-    if (!$restart && !$debug) {
+    if (!$self->{env_restart_pve_daemon} && !$debug) {
        PVE::INotify::inotify_close();
        $spid = fork();
        if (!defined ($spid)) {
@@ -228,7 +248,7 @@ my $server_run = sub {
 
     POSIX::setsid(); 
 
-    if ($restart) {
+    if ($self->{env_restart_pve_daemon}) {
        syslog('info' , "restarting server");
     } else {
        syslog('info' , "starting server");
@@ -320,7 +340,11 @@ my $server_run = sub {
 sub new {
     my ($this, $name, $cmdline, %params) = @_;
 
-    die "please run as root\n" if !$ENV{RESTART_PVE_DAEMON} && ($> != 0);
+    my $restart = $ENV{RESTART_PVE_DAEMON};
+
+    delete $ENV{RESTART_PVE_DAEMON};
+
+    die "please run as root\n" if !$restart && ($> != 0);
 
     die "missing name" if !$name;
 
@@ -336,6 +360,7 @@ sub new {
     my $self = bless { 
        name => $name,
        run_dir => '/var/run',
+       env_restart_pve_daemon => $restart,
        workers => {},
     }, $class;
 
@@ -530,7 +555,7 @@ sub register_start_command {
 my $reload_daemon = sub {
     my ($self, $use_hup) = @_;
 
-    if (my $restart = $ENV{RESTART_PVE_DAEMON}) {
+    if ($self->{env_restart_pve_daemon}) {
        $self->start();
     } else {
        my ($running, $pid) = $self->running();