X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=src%2FPVE%2FDaemon.pm;h=1243fc7512bddabeed908a6f5a24945c72376471;hp=264f8be5e2a840aa7969a47ef95fbda017d7cbc8;hb=1068aeb3988b7ef080bd812bb1fa330c27e1b9f7;hpb=b51b16e6f58de4cb385bd461d97866b3d94c93ec diff --git a/src/PVE/Daemon.pm b/src/PVE/Daemon.pm index 264f8be..1243fc7 100644 --- a/src/PVE/Daemon.pm +++ b/src/PVE/Daemon.pm @@ -24,7 +24,7 @@ use PVE::INotify; use POSIX ":sys_wait_h"; use Fcntl ':flock'; use Socket qw(IPPROTO_TCP TCP_NODELAY SOMAXCONN); -use IO::Socket::INET; +use IO::Socket::IP; use Getopt::Long; use Time::HiRes qw (gettimeofday); @@ -247,6 +247,59 @@ my $terminate_server = sub { } }; +sub setup { + my ($self) = @_; + + initlog($self->{name}); + + my $restart = $ENV{RESTART_PVE_DAEMON}; + delete $ENV{RESTART_PVE_DAEMON}; + $self->{env_restart_pve_daemon} = $restart; + + my $lockfd = $ENV{PVE_DAEMON_LOCK_FD}; + delete $ENV{PVE_DAEMON_LOCK_FD}; + if (defined($lockfd)) { + die "unable to parse lock fd '$lockfd'\n" + if $lockfd !~ m/^(\d+)$/; + $lockfd = $1; # untaint + } + $self->{env_pve_lock_fd} = $lockfd; + + 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(); + + if (my $gidstr = $self->{setgid}) { + my $gid = getgrnam($gidstr) || die "getgrnam failed - $!\n"; + POSIX::setgid($gid) || die "setgid $gid failed - $!\n"; + $EGID = "$gid $gid"; # this calls setgroups + # just to be sure + die "detected strange gid\n" if !($GID eq "$gid $gid" && $EGID eq "$gid $gid"); + } + + if (my $uidstr = $self->{setuid}) { + my $uid = getpwnam($uidstr) || die "getpwnam failed - $!\n"; + POSIX::setuid($uid) || die "setuid $uid failed - $!\n"; + # just to be sure + die "detected strange uid\n" if !($UID == $uid && $EUID == $uid); + } + + if ($restart && $self->{max_workers}) { + if (my $wpids = $ENV{PVE_DAEMON_WORKER_PIDS}) { + foreach my $pid (split(':', $wpids)) { + if ($pid =~ m/^(\d+)$/) { + $self->{old_workers}->{$1} = 1; + } + } + } + } + + $self->{nodename} = PVE::INotify::nodename(); +} + my $server_run = sub { my ($self, $debug) = @_; @@ -382,38 +435,14 @@ sub new { $name = 'daemon' if !$name; # should not happen - initlog($name); - my $self; eval { - - my $restart = $ENV{RESTART_PVE_DAEMON}; - delete $ENV{RESTART_PVE_DAEMON}; - - my $lockfd = $ENV{PVE_DAEMON_LOCK_FD}; - delete $ENV{PVE_DAEMON_LOCK_FD}; - - if (defined($lockfd)) { - die "unable to parse lock fd '$lockfd'\n" - if $lockfd !~ m/^(\d+)$/; - $lockfd = $1; # untaint - } - - 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(); - my $class = ref($this) || $this; $self = bless { name => $name, pidfile => "/var/run/${name}.pid", - env_restart_pve_daemon => $restart, - env_pve_lock_fd => $lockfd, workers => {}, old_workers => {}, }, $class; @@ -440,39 +469,9 @@ sub new { } } - if (my $gidstr = $self->{setgid}) { - my $gid = getgrnam($gidstr) || die "getgrnam failed - $!\n"; - POSIX::setgid($gid) || die "setgid $gid failed - $!\n"; - $EGID = "$gid $gid"; # this calls setgroups - # just to be sure - die "detected strange gid\n" if !($GID eq "$gid $gid" && $EGID eq "$gid $gid"); - } - - if (my $uidstr = $self->{setuid}) { - my $uid = getpwnam($uidstr) || die "getpwnam failed - $!\n"; - POSIX::setuid($uid) || die "setuid $uid failed - $!\n"; - # just to be sure - die "detected strange uid\n" if !($UID == $uid && $EUID == $uid); - } - - if ($restart && $self->{max_workers}) { - if (my $wpids = $ENV{PVE_DAEMON_WORKER_PIDS}) { - foreach my $pid (split(':', $wpids)) { - if ($pid =~ m/^(\d+)$/) { - $self->{old_workers}->{$1} = 1; - } - } - } - } - - $self->{nodename} = PVE::INotify::nodename(); - $self->{cmdline} = []; - - foreach my $el (@$cmdline) { - $el =~ m/^(.*)$/; # untaint - push @{$self->{cmdline}}, $1; - } + # untaint + $self->{cmdline} = [map { /^(.*)$/ } @$cmdline]; $0 = $name; }; @@ -555,7 +554,10 @@ sub run { sub start { my ($self, $debug) = @_; - eval { &$server_run($self, $debug); }; + eval { + $self->setup(); + &$server_run($self, $debug); + }; if (my $err = $@) { &$log_err("start failed - $err"); exit(-1); @@ -576,6 +578,16 @@ my $read_pid = sub { return $pid; }; +# checks if the process was started by systemd +my $init_ppid = sub { + + if (getppid() == 1) { + return 1; + } else { + return 0; + } +}; + sub running { my ($self) = @_; @@ -652,7 +664,11 @@ sub register_start_command { code => sub { my ($param) = @_; - $self->start($param->{debug}); + if (&$init_ppid()) { + $self->start($param->{debug}); + } else { + PVE::Tools::run_command(['systemctl', 'start', $self->{name}]); + } return undef; }}); @@ -698,7 +714,11 @@ sub register_restart_command { code => sub { my ($param) = @_; - &$reload_daemon($self, $use_hup); + if (&$init_ppid()) { + &$reload_daemon($self, $use_hup); + } else { + PVE::Tools::run_command(['systemctl', $use_hup ? 'reload-or-restart' : 'restart', $self->{name}]); + } return undef; }}); @@ -748,7 +768,11 @@ sub register_stop_command { code => sub { my ($param) = @_; - $self->stop(); + if (&$init_ppid()) { + $self->stop(); + } else { + PVE::Tools::run_command(['systemctl', 'stop', $self->{name}]); + } return undef; }}); @@ -782,7 +806,7 @@ sub register_status_command { # some useful helper sub create_reusable_socket { - my ($self, $port, $host) = @_; + my ($self, $port, $host, $family) = @_; die "no port specifed" if !$port; @@ -795,17 +819,19 @@ sub create_reusable_socket { if $sockfd !~ m/^(\d+)$/; $sockfd = $1; # untaint - $socket = IO::Socket::INET->new; + $socket = IO::Socket::IP->new; $socket->fdopen($sockfd, 'w') || die "cannot fdopen file descriptor '$sockfd' - $!\n"; } else { - $socket = IO::Socket::INET->new( + $socket = IO::Socket::IP->new( LocalAddr => $host, LocalPort => $port, Listen => SOMAXCONN, + Family => $family, Proto => 'tcp', + GetAddrInfoFlags => 0, ReuseAddr => 1) || die "unable to create socket - $@\n";