]>
git.proxmox.com Git - pve-manager.git/blob - PVE/Service/pvescheduler.pm
1 package PVE
::Service
::pvescheduler
;
11 use PVE
::API2
::Replication
;
14 use base
qw(PVE::Daemon);
16 my $cmdline = [$0, @ARGV];
17 my %daemon_options = (stop_wait_time
=> 180, max_workers
=> 0);
18 my $daemon = __PACKAGE__-
>new('pvescheduler', $cmdline, %daemon_options);
20 my @types = qw(replication jobs);
22 my $finish_jobs = sub {
24 for my $type (@types) {
25 if (my $cpid = $self->{jobs
}->{$type}) {
26 my $waitpid = waitpid($cpid, WNOHANG
);
27 if (defined($waitpid) && ($waitpid == $cpid)) {
28 $self->{jobs
}->{$type} = undef;
38 $self->{jobs
} = $jobs;
40 my $old_sig_chld = $SIG{CHLD
};
41 local $SIG{CHLD
} = sub {
42 local ($@, $!, $?); # do not overwrite error vars
43 $finish_jobs->($self);
44 $old_sig_chld->(@_) if $old_sig_chld;
48 my ($type, $sub) = @_;
50 # don't fork again if the previous iteration still runs
51 return if defined($self->{jobs
}->{$type});
54 if (!defined($child)) {
55 die "fork failed: $!\n";
56 } elsif ($child == 0) {
57 $self->after_fork_cleanup();
62 syslog
('err', "ERROR: $err");
67 $jobs->{$type} = $child;
72 $fork->('replication', sub {
73 PVE
::API2
::Replication
::run_jobs
(undef, sub {}, 0, 1);
77 PVE
::Jobs
::run_jobs
();
81 PVE
::Jobs
::setup_dirs
();
83 for (my $count = 1000;;$count++) {
84 last if $self->{shutdown_request
};
90 # Job schedule has minute precision, so try running near the minute boundary.
91 my ($current_seconds) = localtime;
92 $sleep_time = (60 - $current_seconds) if (60 - $current_seconds >= 5);
96 my $slept = 0; # SIGCHLD interrupts sleep, so we need to keep track
97 while ($slept < $sleep_time) {
98 last if $self->{shutdown_request
};
99 $slept += sleep($sleep_time - $slept);
103 # replication jobs have a lock timeout of 60s, wait a bit more for graceful termination
105 for my $type (@types) {
106 while (defined($jobs->{$type}) && $timeout < 75) {
107 kill 'TERM', $jobs->{$type};
108 $timeout += sleep(5);
110 # ensure the rest gets stopped
111 kill 'KILL', $jobs->{$type} if defined($jobs->{$type});
118 syslog
('info', 'got shutdown request, signal running jobs to stop');
120 for my $type (@types) {
121 kill 'TERM', $self->{jobs
}->{$type} if $self->{jobs
}->{$type};
123 $self->{shutdown_request
} = 1;
126 $daemon->register_start_command();
127 $daemon->register_stop_command();
128 $daemon->register_status_command();
131 start
=> [ __PACKAGE__
, 'start', []],
132 stop
=> [ __PACKAGE__
, 'stop', []],
133 status
=> [ __PACKAGE__
, 'status', [], undef, sub { print shift . "\n";} ],