X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=src%2FPVE%2FDaemon.pm;h=64f8126c141b478b07ac11e652cb8b32d2ffdee3;hp=e3e43d9b3f0561998c6318eaf16d2a856ffd360d;hb=HEAD;hpb=d949babe56bde89b2935bfab041574e360a1201e diff --git a/src/PVE/Daemon.pm b/src/PVE/Daemon.pm index e3e43d9..63fd5ee 100644 --- a/src/PVE/Daemon.pm +++ b/src/PVE/Daemon.pm @@ -13,7 +13,7 @@ package PVE::Daemon; # * allow to restart while workers are still runningl # (option 'leave_children_open_on_reload') # * run as different user using setuid/setgid - + use strict; use warnings; use English; @@ -64,7 +64,7 @@ sub after_fork_cleanup { for my $sig (qw(CHLD HUP INT TERM QUIT)) { $SIG{$sig} = 'DEFAULT'; # restore default handler - # AnyEvent signals only works if $SIG{XX} is + # AnyEvent signals only works if $SIG{XX} is # undefined (perl event loop) delete $SIG{$sig}; # so that we can handle events with AnyEvent } @@ -80,7 +80,7 @@ my $lockpidfile = sub { if (my $fd = $self->{env_pve_lock_fd}) { $self->{daemon_lock_fh} = IO::Handle->new_from_fd($fd, "a"); - + } else { $waittime = 5; @@ -114,10 +114,10 @@ my $writepidfile = sub { my $pidfile = $self->{pidfile}; - die "can't open pid file '$pidfile' - $!\n" if !open (PIDFH, ">$pidfile"); + open (my $PID_FH, '>', "$pidfile") or die "can't open pid file '$pidfile' - $!\n"; - print PIDFH "$$\n"; - close (PIDFH); + print $PID_FH "$$\n"; + close ($PID_FH); }; my $server_cleanup = sub { @@ -243,8 +243,7 @@ sub setup { initlog($self->{name}); - my $restart = $ENV{RESTART_PVE_DAEMON}; - delete $ENV{RESTART_PVE_DAEMON}; + my $restart = delete $ENV{RESTART_PVE_DAEMON}; $self->{env_restart_pve_daemon} = $restart; my $lockfd = $ENV{PVE_DAEMON_LOCK_FD}; @@ -311,8 +310,8 @@ my $server_run = sub { $self->init(); if (!$debug) { - open STDIN, '/dev/null' || die "can't write /dev/null"; + open STDIN, '<', '/dev/null' or die "can't read /dev/null - $!"; + open STDOUT, '>', '/dev/null' or die "can't write /dev/null - $!"; } if (!$self->{env_restart_pve_daemon} && !$debug) { @@ -333,7 +332,7 @@ my $server_run = sub { syslog('info' , "starting server"); } - POSIX::setsid(); + POSIX::setsid(); open STDERR, '>&STDOUT' || die "can't close STDERR\n"; @@ -377,7 +376,7 @@ my $server_run = sub { } }; - eval { + eval { if ($self->{max_workers}) { my $old_sig_chld = $SIG{CHLD}; local $SIG{CHLD} = sub { @@ -387,7 +386,7 @@ my $server_run = sub { }; # now loop forever (until we receive terminate signal) - for (;;) { + for (;;) { &$start_workers($self); sleep(5); &$terminate_old_workers($self); @@ -397,7 +396,7 @@ my $server_run = sub { } else { $self->run(); - } + } }; my $err = $@; @@ -430,7 +429,7 @@ sub new { eval { my $class = ref($this) || $this; - $self = bless { + $self = bless { name => $name, pidfile => "/var/run/${name}.pid", workers => {}, @@ -458,7 +457,7 @@ sub new { die "unknown daemon option '$opt'\n"; } } - + # untaint $self->{cmdline} = [map { /^(.*)$/ } @$cmdline]; @@ -565,7 +564,7 @@ my $read_pid = sub { return 0 if !$pid_str; return 0 if $pid_str !~ m/^(\d+)$/; # untaint - + my $pid = int($1); return $pid; @@ -573,13 +572,12 @@ my $read_pid = sub { # checks if the process was started by systemd my $init_ppid = sub { - if (getppid() == 1) { return 1; } else { return 0; } -}; +}; sub running { my ($self) = @_; @@ -664,7 +662,7 @@ sub register_start_command { } return undef; - }}); + }}); } my $reload_daemon = sub { @@ -673,7 +671,7 @@ my $reload_daemon = sub { if ($self->{env_restart_pve_daemon}) { $self->start(); } else { - my ($running, $pid) = $self->running(); + my ($running, $pid) = $self->running(); if (!$running) { $self->start(); } else { @@ -714,7 +712,7 @@ sub register_restart_command { } return undef; - }}); + }}); } sub register_reload_command { @@ -739,7 +737,7 @@ sub register_reload_command { &$reload_daemon($self, 1); return undef; - }}); + }}); } sub register_stop_command { @@ -760,7 +758,7 @@ sub register_stop_command { code => sub { my ($param) = @_; - + if (&$init_ppid()) { $self->stop(); } else { @@ -768,7 +766,7 @@ sub register_stop_command { } return undef; - }}); + }}); } sub register_status_command { @@ -785,7 +783,7 @@ sub register_status_command { additionalProperties => 0, properties => {}, }, - returns => { + returns => { type => 'string', enum => ['stopped', 'running'], }, @@ -799,7 +797,7 @@ sub register_status_command { # some useful helper sub create_reusable_socket { - my ($self, $port, $host, $family) = @_; + my ($self, $port, $host) = @_; die "no port specifed" if !$port; @@ -808,26 +806,34 @@ sub create_reusable_socket { if (defined($sockfd = $ENV{"PVE_DAEMON_SOCKET_$port"}) && $self->{env_restart_pve_daemon}) { - die "unable to parse socket fd '$sockfd'\n" + die "unable to parse socket fd '$sockfd'\n" if $sockfd !~ m/^(\d+)$/; $sockfd = $1; # untaint $socket = IO::Socket::IP->new; - $socket->fdopen($sockfd, 'w') || + $socket->fdopen($sockfd, 'w') || die "cannot fdopen file descriptor '$sockfd' - $!\n"; $socket->fcntl(Fcntl::F_SETFD(), Fcntl::FD_CLOEXEC); } else { - $socket = IO::Socket::IP->new( - LocalAddr => $host, + my %sockargs = ( LocalPort => $port, Listen => SOMAXCONN, - Family => $family, Proto => 'tcp', GetAddrInfoFlags => 0, - ReuseAddr => 1) || - die "unable to create socket - $@\n"; + ReuseAddr => 1, + ); + if (defined($host)) { + $socket = IO::Socket::IP->new( LocalHost => $host, %sockargs) || + die "unable to create socket - $@\n"; + } else { + # disabling AF_INET6 (by adding ipv6.disable=1 to the kernel cmdline) + # causes bind on :: to fail, try 0.0.0.0 in that case + $socket = IO::Socket::IP->new( LocalHost => '::', %sockargs) // + IO::Socket::IP->new( LocalHost => '0.0.0.0', %sockargs); + die "unable to create socket - $@\n" if !$socket; + } # we often observe delays when using Nagle algorithm, # so we disable that to maximize performance