]> git.proxmox.com Git - pmg-api.git/blob - PMG/Service/pmgmirror.pm
c8b7d1b81bebce5cef91f35dfa61399b0ed2a9a1
[pmg-api.git] / PMG / Service / pmgmirror.pm
1 package PMG::Service::pmgmirror;
2
3 use strict;
4 use warnings;
5 use Data::Dumper;
6 use Time::HiRes qw (gettimeofday);
7
8 use PVE::SafeSyslog;
9 use PVE::Tools qw(extract_param);
10 use PVE::INotify;
11 use PVE::Daemon;
12 use PVE::ProcFSTools;
13
14 use PMG::RESTEnvironment;
15 use PMG::DBTools;
16 use PMG::RuleDB;
17 use PMG::Cluster;
18 use PMG::ClusterConfig;
19 use PMG::Statistic;
20
21 use base qw(PVE::Daemon);
22
23 my $cmdline = [$0, @ARGV];
24
25 my %daemon_options = (restart_on_error => 5, stop_wait_time => 5);
26
27 my $daemon = __PACKAGE__->new('pmgmirror', $cmdline, %daemon_options);
28
29 my $restart_request = 0;
30 my $next_update = 0;
31
32 my $cycle = 0;
33 my $updatetime = 60*2;
34
35 my $initial_memory_usage;
36
37 sub init {
38 # syslog('INIT');
39 }
40
41 sub hup {
42 my ($self) = @_;
43
44 $restart_request = 1;
45 }
46
47 sub cluster_sync {
48 my ($cinfo) = @_;
49
50 my $rsynctime = 0;
51 my $csynctime = 0;
52
53 my $cinfo = PMG::ClusterConfig->new(); # reload
54 my $role = $cinfo->{local}->{type} // '-';
55
56 return if $role eq '-';
57 return if !$cinfo->{master}; # just to be sure
58
59 my ($ccsec_start, $cusec_start) = gettimeofday ();
60
61 syslog ('info', "starting cluster syncronization");
62
63 my $master_ip = $cinfo->{master}->{ip};
64 my $master_name = $cinfo->{master}->{name};
65
66 PMG::Cluster::sync_config_from_master($cinfo, $master_name, $master_ip);
67
68 my ($ccsec, $cusec) = gettimeofday ();
69 $csynctime += int (($ccsec-$ccsec_start)*1000 + ($cusec - $cusec_start)/1000);
70
71 $cinfo = PMG::ClusterConfig->new(); # reload
72 $role = $cinfo->{local}->{type} // '-';
73
74 return if $role eq '-';
75 return if !$cinfo->{master}; # just to be sure
76
77 ($ccsec, $cusec) = gettimeofday ();
78 my $cptime = int (($ccsec-$ccsec_start) + ($cusec - $cusec_start)/1000000);
79
80 my $rstime = $rsynctime/1000.0;
81 my $cstime = $csynctime/1000.0;
82 my $dbtime = $cptime - $rstime - $cstime;
83
84 syslog('info', sprintf("cluster syncronization finished (%.2f seconds " .
85 "(files %.2f, database %.2f, config %.2f))",
86 $cptime, $rstime, $dbtime, $cstime));
87
88 }
89
90 sub run {
91 my ($self) = @_;
92
93 for (;;) { # forever
94
95 $next_update = time() + $updatetime;
96
97 eval { cluster_sync(); };
98 if (my $err = $@) {
99 syslog('err', PMG::Utils::msgquote ("sync error: $err"));
100 }
101
102 $cycle++;
103
104 last if $self->{terminate};
105
106 my $mem = PVE::ProcFSTools::read_memory_usage();
107
108 if (!defined($initial_memory_usage) || ($cycle < 10)) {
109 $initial_memory_usage = $mem->{resident};
110 } else {
111 my $diff = $mem->{resident} - $initial_memory_usage;
112 if ($diff > 5*1024*1024) {
113 syslog ('info', "restarting server after $cycle cycles to " .
114 "reduce memory usage (free $mem->{resident} ($diff) bytes)");
115 $self->restart_daemon();
116 }
117 }
118
119 my $wcount = 0;
120 while ((time() < $next_update) &&
121 ($wcount < $updatetime) && # protect against time wrap
122 !$restart_request && !$self->{terminate}) {
123
124 $wcount++; sleep (1);
125 };
126
127 last if $self->{terminate};
128
129 $self->restart_daemon() if $restart_request;
130 }
131 }
132
133 $daemon->register_start_command("Start the Database Mirror Daemon");
134 $daemon->register_stop_command("Stop the Database Mirror Daemon");
135 $daemon->register_restart_command(1, "Restart the Database Mirror Daemon");
136
137 our $cmddef = {
138 start => [ __PACKAGE__, 'start', []],
139 restart => [ __PACKAGE__, 'restart', []],
140 stop => [ __PACKAGE__, 'stop', []],
141 };
142
143 1;