]> git.proxmox.com Git - pmg-api.git/commitdiff
backup: pbs: prevent race in concurrent backups
authorStoiko Ivanov <s.ivanov@proxmox.com>
Mon, 1 Mar 2021 14:12:18 +0000 (15:12 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 5 Mar 2021 21:41:38 +0000 (22:41 +0100)
If two pbs backup-creation calls happen simultaneously, it is possible
that the first removes the backup dir before the other is done
creating or sending it to the pbs remote.

This patch takes the same route as non-PBS backups - creating a unique
tempdir indexed by remote, PID and current time.

the tmp-dir now also needs to be removed in case of error while
backing up. (before the next invocation would have wiped it).

Noticed while having 2 schedules to different PBS instances with the
same interval and w/o random delay.

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
src/PMG/API2/PBS/Job.pm

index 23874225b04a615391ed4b4e21b57e7a1cb61fa3..c095d258ed9fe33e835147535488c4997f46e029 100644 (file)
@@ -294,20 +294,28 @@ __PACKAGE__->register_method ({
        $param->{statistic} //= $remote_config->{'include-statistics'} // 1;
 
        my $pbs = PVE::PBSClient->new($remote_config, $remote, $conf->{secret_dir});
-       my $backup_dir = "/var/lib/pmg/backup/current";
+
+       my $time = time;
+       my $backup_dir = "/tmp/pbsbackup_${remote}_$$.$time";
 
        my $worker = sub {
            my $upid = shift;
 
            print "starting update of current backup state\n";
 
-           -d $backup_dir || mkdir $backup_dir;
-           PMG::Backup::pmg_backup($backup_dir, $param->{statistic});
+           eval {
+               -d $backup_dir || mkdir $backup_dir;
+               PMG::Backup::pmg_backup($backup_dir, $param->{statistic});
 
-           $pbs->backup_fs_tree($backup_dir, $node, 'pmgbackup');
+               $pbs->backup_fs_tree($backup_dir, $node, 'pmgbackup');
 
-           rmtree $backup_dir;
+               rmtree $backup_dir;
+           };
+           if (my $err = $@) {
+               rmtree $backup_dir;
+               die "backup failed: $err\n";
 
+           }
            print "backup finished\n";
 
            my $group = "host/$node";