From 1a6bc2f371ed41d82ce5dcbcbd92d05b25ac1010 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 31 Dec 2014 11:54:27 +0100 Subject: [PATCH] Daemon: keep lock file open during restart So that nobody else can grab the lock --- data/PVE/Daemon.pm | 57 +++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/data/PVE/Daemon.pm b/data/PVE/Daemon.pm index 7525229..d1cec0e 100644 --- a/data/PVE/Daemon.pm +++ b/data/PVE/Daemon.pm @@ -67,11 +67,17 @@ my $lockpidfile = sub { my $lkfn = $self->{pidfile} . ".lock"; - $self->{daemon_lock_fh} = IO::File->new(">>$lkfn"); + if (my $fd = $self->{env_pve_lock_fd}) { + + $self->{daemon_lock_fh} = IO::Handle->new_from_fd($fd, "a"); + + } else { + + $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"; + die "can't open lock '$lkfn' - $!\n"; } for (my $i = 0; $i < 5; $i ++) { @@ -81,9 +87,7 @@ my $lockpidfile = sub { 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"; + die "can't aquire lock '$lkfn' - $!\n"; } }; @@ -217,8 +221,18 @@ my $terminate_server = sub { my $server_run = sub { my ($self, $debug) = @_; + # fixme: handle restart lockfd &$lockpidfile($self); + # remove FD_CLOEXEC bit to reuse on exec + $self->{daemon_lock_fh}->fcntl(Fcntl::F_SETFD(), 0); + + $ENV{PVE_DAEMON_LOCK_FD} = $self->{daemon_lock_fh}->fileno; + +# my $fd = POSIX::dup($self->{daemon_lock_fh}) || +# die "unable to duplicate daemon_lock_fh\n"; + + # run in background my $spid; @@ -340,27 +354,30 @@ my $server_run = sub { sub new { my ($this, $name, $cmdline, %params) = @_; - my $restart = $ENV{RESTART_PVE_DAEMON}; + die "missing name" if !$name; + + initlog($name); + my $restart = $ENV{RESTART_PVE_DAEMON}; delete $ENV{RESTART_PVE_DAEMON}; - die "please run as root\n" if !$restart && ($> != 0); + my $lockfd = $ENV{PVE_DAEMON_LOCK_FD}; + delete $ENV{PVE_DAEMON_LOCK_FD}; - die "missing name" if !$name; + die "please run as root\n" if !$restart && ($> != 0); die "can't create more that one PVE::Daemon" if $daemon_initialized; $daemon_initialized = 1; PVE::INotify::inotify_init(); - initlog($name); - my $class = ref($this) || $this; my $self = bless { name => $name, run_dir => '/var/run', env_restart_pve_daemon => $restart, + env_pve_lock_fd => $lockfd, workers => {}, }, $class; @@ -460,7 +477,10 @@ sub run { sub start { my ($self, $debug) = @_; - &$server_run($self, $debug); + eval { &$server_run($self, $debug); }; + if (my $err = $@) { + syslog('err', "start failed - $err"); + } } my $read_pid = sub { @@ -516,9 +536,14 @@ sub stop { } if (-f $self->{pidfile}) { - # try to get the lock - &$lockpidfile($self); - &$server_cleanup($self); + eval { + # try to get the lock + &$lockpidfile($self); + &$server_cleanup($self); + }; + if (my $err = $@) { + syslog('err', "cleanup failed - $err"); + } } } -- 2.39.2