[pve-devel] [PATCH storage v2] Fix #582: Make removing backups a background task

Dominic Jäger d.jaeger at proxmox.com
Fri May 10 12:42:06 CEST 2019


Previously, the web gui timed out when removing a
backup took long. Doing the main part of the API
DELETE call in a fork_worker solves this.

This relies on the patch that makes returning undef possible for API calls.

Signed-off-by: Dominic Jäger <d.jaeger at proxmox.com>
---
 PVE/API2/Storage/Content.pm | 44 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 34 insertions(+), 10 deletions(-)

diff --git a/PVE/API2/Storage/Content.pm b/PVE/API2/Storage/Content.pm
index cd4746b..3b62c60 100644
--- a/PVE/API2/Storage/Content.pm
+++ b/PVE/API2/Storage/Content.pm
@@ -285,9 +285,16 @@ __PACKAGE__->register_method ({
 		type => 'string',
 		completion => \&PVE::Storage::complete_volume,
 	    },
+		background_delay => {
+		    type => 'integer',
+		    description => "Time to wait for the task to finish. We return 'null' if the task finish within that time.",
+		    minimum => 1,
+		    maximum => 30,
+		    optional => 1,
+		},
 	},
     },
-    returns => { type => 'null' },
+    returns => { type => 'string', optional => 1, },
     code => sub {
 	my ($param) = @_;
 
@@ -297,6 +304,7 @@ __PACKAGE__->register_method ({
 	my $cfg = PVE::Storage::config();
 
 	my ($volid, $storeid) = &$real_volume_id($param->{storage}, $param->{volume});
+	my $background_delay = $param->{background_delay};
 
 	my ($path, $ownervm, $vtype) = PVE::Storage::path($cfg, $volid);
 	if ($vtype eq 'backup' && $ownervm) {
@@ -306,16 +314,32 @@ __PACKAGE__->register_method ({
 	    $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.Allocate']);
 	}
 
-	PVE::Storage::vdisk_free ($cfg, $volid);
-
-	if ($vtype eq 'backup'
-	    && $path =~ /(.*\/vzdump-\w+-\d+-\d{4}_\d{2}_\d{2}-\d{2}_\d{2}_\d{2})[^\/]+$/) {
-	    my $logpath = "$1.log";
-	    # try to cleanup our backup log file too, if still exisiting, #318
-	    unlink($logpath) if -e $logpath;
+	my $worker = sub {
+	    PVE::Storage::vdisk_free ($cfg, $volid);
+	    if ($vtype eq 'backup'
+		&& $path =~ /(.*\/vzdump-\w+-\d+-\d{4}_\d{2}_\d{2}-\d{2}_\d{2}_\d{2})[^\/]+$/) {
+		my $logpath = "$1.log";
+		# try to cleanup our backup log file too, if still exisiting, #318
+		unlink($logpath) if -e $logpath;
+	    }
+	};
+	my $upid = $rpcenv->fork_worker('imgdel', $ownervm, $authuser, $worker);
+	if ($background_delay) {
+	    my $end_time = time() + $background_delay;
+	    my $task = PVE::Tools::upid_decode($upid);
+	    my $currently_deleting; # not necessarily true, e.g. sequential api call from cli
+	    do {
+		$currently_deleting = PVE::ProcFSTools::check_process_running($task->{pid}, $task->{pstart});
+		sleep 1 if $currently_deleting;
+	    } while (time() < $end_time && $currently_deleting);
+
+	    if (!$currently_deleting) {
+		my $status = PVE::Tools::upid_read_status($upid);
+		return undef if $status eq 'OK';
+		die $status;
+	    }
 	}
-
-	return undef;
+	return $upid;
     }});
 
 __PACKAGE__->register_method ({
-- 
2.11.0




More information about the pve-devel mailing list