[pve-devel] [PATCH pve-zsync] Allow detecting a syncing instance of a job
Fabian Ebner
f.ebner at proxmox.com
Mon Sep 30 12:55:16 CEST 2019
Before, the check whether a syncing instance of the same job is already present
was inside the locked section. This caused cron to continuously spawn new
instances of pve-zsync on syncs (or rather groups of syncs) taking longer
than 15 minutes, see [0] in the forum. This patch introduces a new locked
section for checking the current status and a new 'waiting' status.
The 'waiting' status is needed to mark jobs which are currently waiting
for the lock for syncing. So if job A is syncing and job B is waiting for
the lock then all new instances of job B will see that one instance is
already scheduled to sync.
[0]: https://forum.proxmox.com/threads/pve-zsync-bug-spawns-endless-cron-processes.58087/
Signed-off-by: Fabian Ebner <f.ebner at proxmox.com>
---
pve-zsync | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/pve-zsync b/pve-zsync
index 425ffa2..90c1bb3 100755
--- a/pve-zsync
+++ b/pve-zsync
@@ -19,6 +19,7 @@ my $PVE_DIR = "/etc/pve/local";
my $QEMU_CONF = "${PVE_DIR}/qemu-server";
my $LXC_CONF = "${PVE_DIR}/lxc";
my $LOCKFILE = "$CONFIG_PATH/${PROGNAME}.lock";
+my $LOCKFILE_STATUS_CHECK = "$CONFIG_PATH/${PROGNAME}_status_check.lock";
my $PROG_PATH = "$PATH/${PROGNAME}";
my $INTERVAL = 15;
my $DEBUG;
@@ -578,20 +579,34 @@ sub destroy_job {
sub sync {
my ($param) = @_;
+ my $lock_status_check_fh = IO::File->new("> $LOCKFILE_STATUS_CHECK");
+ die "Can't open Lock File: $LOCKFILE_STATUS_CHECK $!\n" if !$lock_status_check_fh;
+ lock($lock_status_check_fh);
+
+ my $job;
+ eval {
+ $job = get_job($param);
+ };
+
+ if ($job && defined($job->{state}) && ($job->{state} eq "syncing" || $job->{state} eq "waiting")) {
+ unlock($lock_status_check_fh);
+ die "Job --source $param->{source} --name $param->{name} is already scheduled to sync\n";
+ }
+
+ $job->{state} = "waiting";
+ update_state($job);
+ unlock($lock_status_check_fh);
+
my $lock_fh = IO::File->new("> $LOCKFILE");
die "Can't open Lock File: $LOCKFILE $!\n" if !$lock_fh;
lock($lock_fh);
+ #job might've changed while we waited for the lock, but we can be sure it's not syncing
my $date = get_date();
- my $job;
eval {
$job = get_job($param);
};
- if ($job && defined($job->{state}) && $job->{state} eq "syncing") {
- die "Job --source $param->{source} --name $param->{name} is syncing at the moment";
- }
-
my $dest = parse_target($param->{dest});
my $source = parse_target($param->{source});
--
2.20.1
More information about the pve-devel
mailing list