+ my $status;
+ my $starttime = time ();
+ my $last_per = -1;
+ my $last_total = 0;
+ my $last_zero = 0;
+ my $last_transferred = 0;
+ my $last_time = time();
+ my $transferred;
+
+ while(1) {
+ $status = PVE::QemuServer::vm_mon_cmd($vmid, 'query-backup');
+ my $total = $status->{total} || 0;
+ $transferred = $status->{transferred} || 0;
+ my $per = $total ? int(($transferred * 100)/$total) : 0;
+ my $zero = $status->{'zero-bytes'} || 0;
+ my $zero_per = $total ? int(($zero * 100)/$total) : 0;
+
+ die "got unexpected uuid\n" if !$status->{uuid} || ($status->{uuid} ne $uuid);
+
+ my $ctime = time();
+ my $duration = $ctime - $starttime;
+
+ my $rbytes = $transferred - $last_transferred;
+ my $wbytes = $rbytes - ($zero - $last_zero);
+
+ my $timediff = ($ctime - $last_time) || 1; # fixme
+ my $mbps_read = ($rbytes > 0) ?
+ int(($rbytes/$timediff)/(1000*1000)) : 0;
+ my $mbps_write = ($wbytes > 0) ?
+ int(($wbytes/$timediff)/(1000*1000)) : 0;
+
+ my $statusline = "status: $per% ($transferred/$total), " .
+ "sparse ${zero_per}% ($zero), duration $duration, " .
+ "read/write $mbps_read/$mbps_write MB/s";
+ my $res = $status->{status} || 'unknown';
+ if ($res ne 'active') {
+ $self->loginfo($statusline);
+ die(($status->{errmsg} || "unknown error") . "\n")
+ if $res eq 'error';
+ die "got unexpected status '$res'\n"
+ if $res ne 'done';
+ die "got wrong number of transfered bytes ($total != $transferred)\n"
+ if ($res eq 'done') && ($total != $transferred);
+
+ last;
+ }
+ if ($per != $last_per && ($timediff > 2)) {
+ $self->loginfo($statusline);
+ $last_per = $per;
+ $last_total = $total if $total;
+ $last_zero = $zero if $zero;
+ $last_transferred = $transferred if $transferred;
+ $last_time = $ctime;
+ }
+ sleep(1);
+ }
+
+ my $duration = time() - $starttime;
+ if ($transferred && $duration) {
+ my $mb = int($transferred/(1000*1000));
+ my $mbps = int(($transferred/$duration)/(1000*1000));
+ $self->loginfo("transferred $mb MB in $duration seconds ($mbps MB/s)");
+ }
+ };
+ my $err = $@;
+
+ if ($err) {
+ $self->logerr($err);
+ $self->loginfo("aborting backup job");
+ eval { PVE::QemuServer::vm_mon_cmd($vmid, 'backup-cancel'); };
+ if (my $err1 = $@) {
+ $self->logerr($err1);