[pve-devel] [Patch V5 guest-common 7/7] Add lock to pervent lost update.
Wolfgang Link
w.link at proxmox.com
Wed May 9 14:48:27 CEST 2018
---
PVE/ReplicationState.pm | 102 +++++++++++++++++++++++++-----------------------
1 file changed, 53 insertions(+), 49 deletions(-)
diff --git a/PVE/ReplicationState.pm b/PVE/ReplicationState.pm
index 2851b62..1613e8f 100644
--- a/PVE/ReplicationState.pm
+++ b/PVE/ReplicationState.pm
@@ -240,67 +240,71 @@ sub job_status {
my $vms = PVE::Cluster::get_vmlist();
- foreach my $jobid (sort keys %{$cfg->{ids}}) {
- my $jobcfg = $cfg->{ids}->{$jobid};
- my $vmid = $jobcfg->{guest};
-
- die "internal error - not implemented" if $jobcfg->{type} ne 'local';
+ my $func = sub {
+ foreach my $jobid (sort keys %{$cfg->{ids}}) {
+ my $jobcfg = $cfg->{ids}->{$jobid};
+ my $vmid = $jobcfg->{guest};
- # skip non existing vms
- next if !$vms->{ids}->{$vmid};
+ die "internal error - not implemented" if $jobcfg->{type} ne 'local';
+
+ # skip non existing vms
+ next if !$vms->{ids}->{$vmid};
+
+ # only consider guest on local node
+ next if $vms->{ids}->{$vmid}->{node} ne $local_node;
+
+ my $target = $jobcfg->{target};
+ if (!$jobcfg->{remove_job}) {
+ # check if vm was stolen (swapped source target)
+ if ($target eq $local_node) {
+ my $source = $jobcfg->{source};
+ if (defined($source) && $source ne $target) {
+ $jobcfg = PVE::ReplicationConfig::swap_source_target_nolock($jobid);
+ $cfg->{ids}->{$jobid} = $jobcfg;
+ } else {
+ # never sync to local node
+ next;
+ }
+ }
- # only consider guest on local node
- next if $vms->{ids}->{$vmid}->{node} ne $local_node;
+ next if !$get_disabled && $jobcfg->{disable};
+ }
- my $target = $jobcfg->{target};
- if (!$jobcfg->{remove_job}) {
- # check if vm was stolen (swapped source target)
- if ($target eq $local_node) {
- my $source = $jobcfg->{source};
- if (defined($source) && $source ne $target) {
- $jobcfg = PVE::ReplicationConfig::swap_source_target_nolock($jobid);
- $cfg->{ids}->{$jobid} = $jobcfg;
+ my $state = extract_job_state($stateobj, $jobcfg);
+ $jobcfg->{state} = $state;
+ $jobcfg->{id} = $jobid;
+ $jobcfg->{vmtype} = $vms->{ids}->{$vmid}->{type};
+
+ my $next_sync = 0;
+
+ if ($jobcfg->{remove_job}) {
+ $next_sync = 1; # lowest possible value
+ # todo: consider fail_count? How many retries?
+ } else {
+ if (my $fail_count = $state->{fail_count}) {
+ my $members = PVE::Cluster::get_members();
+ if (!$fail_count || ($members->{$target} && $members->{$target}->{online})) {
+ $next_sync = $state->{last_try} + 60*($fail_count < 3 ? 5*$fail_count : 30);
+ }
} else {
- # never sync to local node
- next;
+ my $schedule = $jobcfg->{schedule} || '*/15';
+ my $calspec = PVE::CalendarEvent::parse_calendar_event($schedule);
+ $next_sync = PVE::CalendarEvent::compute_next_event($calspec, $state->{last_try}) // 0;
}
}
- next if !$get_disabled && $jobcfg->{disable};
- }
-
- my $state = extract_job_state($stateobj, $jobcfg);
- $jobcfg->{state} = $state;
- $jobcfg->{id} = $jobid;
- $jobcfg->{vmtype} = $vms->{ids}->{$vmid}->{type};
-
- my $next_sync = 0;
+ $jobcfg->{next_sync} = $next_sync;
- if ($jobcfg->{remove_job}) {
- $next_sync = 1; # lowest possible value
- # todo: consider fail_count? How many retries?
- } else {
- if (my $fail_count = $state->{fail_count}) {
- my $members = PVE::Cluster::get_members();
- if (!$fail_count || ($members->{$target} && $members->{$target}->{online})) {
- $next_sync = $state->{last_try} + 60*($fail_count < 3 ? 5*$fail_count : 30);
- }
- } else {
- my $schedule = $jobcfg->{schedule} || '*/15';
- my $calspec = PVE::CalendarEvent::parse_calendar_event($schedule);
- $next_sync = PVE::CalendarEvent::compute_next_event($calspec, $state->{last_try}) // 0;
+ if (!defined($jobcfg->{source}) || $jobcfg->{source} ne $local_node) {
+ $jobcfg->{source} = $cfg->{ids}->{$jobid}->{source} = $local_node;
+ PVE::ReplicationConfig::write($cfg);
}
- }
-
- $jobcfg->{next_sync} = $next_sync;
- if (!defined($jobcfg->{source}) || $jobcfg->{source} ne $local_node) {
- $jobcfg->{source} = $cfg->{ids}->{$jobid}->{source} = $local_node;
- PVE::ReplicationConfig::write($cfg);
+ $jobs->{$jobid} = $jobcfg;
}
+ };
- $jobs->{$jobid} = $jobcfg;
- }
+ PVE::ReplicationConfig::lock($func);
return $jobs;
}
--
2.11.0
More information about the pve-devel
mailing list