qemu_drive_mirror: raise exception if we cannot parse $dst_volid

This commit is contained in:
Dietmar Maurer 2014-11-10 07:55:09 +01:00
parent ad2cb4111f
commit 08ac653fcf

View File

@ -5154,84 +5154,70 @@ sub qemu_drive_mirror {
my $maxwait = 120; my $maxwait = 120;
my $storecfg = PVE::Storage::config(); my $storecfg = PVE::Storage::config();
my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid, 1); my ($dst_storeid, $dst_volname) = PVE::Storage::parse_volume_id($dst_volid);
if ($dst_storeid) { my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
my $format; my $format;
if ($dst_volname =~ m/\.(raw|qcow2)$/){ if ($dst_volname =~ m/\.(raw|qcow2)$/){
$format = $1; $format = $1;
} }
my $dst_path = PVE::Storage::path($storecfg, $dst_volid); my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
if ($format) { if ($format) {
#fixme : sometime drive-mirror timeout, but works fine after. #fixme : sometime drive-mirror timeout, but works fine after.
# (I have see the problem with big volume > 200GB), so we need to eval # (I have see the problem with big volume > 200GB), so we need to eval
eval { vm_mon_cmd($vmid, "drive-mirror", timeout => 10, device => "drive-$drive", mode => "existing", eval { vm_mon_cmd($vmid, "drive-mirror", timeout => 10, device => "drive-$drive", mode => "existing",
sync => "full", target => $dst_path, format => $format); }; sync => "full", target => $dst_path, format => $format); };
} else { } else {
eval { vm_mon_cmd($vmid, "drive-mirror", timeout => 10, device => "drive-$drive", mode => "existing", eval { vm_mon_cmd($vmid, "drive-mirror", timeout => 10, device => "drive-$drive", mode => "existing",
sync => "full", target => $dst_path); }; sync => "full", target => $dst_path); };
} }
eval { eval {
while (1) { while (1) {
my $stats = vm_mon_cmd($vmid, "query-block-jobs"); my $stats = vm_mon_cmd($vmid, "query-block-jobs");
my $stat = @$stats[0]; my $stat = @$stats[0];
die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat; die "mirroring job seem to have die. Maybe do you have bad sectors?" if !$stat;
die "error job is not mirroring" if $stat->{type} ne "mirror"; die "error job is not mirroring" if $stat->{type} ne "mirror";
my $transferred = $stat->{offset}; my $transferred = $stat->{offset};
my $total = $stat->{len}; my $total = $stat->{len};
my $remaining = $total - $transferred; my $remaining = $total - $transferred;
my $percent = sprintf "%.2f", ($transferred * 100 / $total); my $percent = sprintf "%.2f", ($transferred * 100 / $total);
my $busy = $stat->{busy}; my $busy = $stat->{busy};
print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent % busy: $busy\n"; print "transferred: $transferred bytes remaining: $remaining bytes total: $total bytes progression: $percent % busy: $busy\n";
if ($stat->{len} == $stat->{offset}) { if ($stat->{len} == $stat->{offset}) {
if ($busy eq 'false') { if ($busy eq 'false') {
last if $vmiddst != $vmid; last if $vmiddst != $vmid;
# try to switch the disk if source and destination are on the same guest # try to switch the disk if source and destination are on the same guest
eval { vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive") }; eval { vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive") };
last if !$@; last if !$@;
die $@ if $@ !~ m/cannot be completed/; die $@ if $@ !~ m/cannot be completed/;
}
if ($count > $maxwait) {
# if too much writes to disk occurs at the end of migration
#the disk needs to be freezed to be able to complete the migration
vm_suspend($vmid,1);
$frozen = 1;
}
$count ++
} }
$old_len = $stat->{offset};
sleep 1; if ($count > $maxwait) {
# if too much writes to disk occurs at the end of migration
#the disk needs to be freezed to be able to complete the migration
vm_suspend($vmid,1);
$frozen = 1;
}
$count ++
} }
$old_len = $stat->{offset};
vm_resume($vmid, 1) if $frozen; sleep 1;
};
if (my $err = $@) {
eval {
vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
while (1) {
my $stats = vm_mon_cmd($vmid, "query-block-jobs");
my $stat = @$stats[0];
last if !$stat;
sleep 1;
}
};
die "mirroring error: $err";
} }
if ($vmiddst != $vmid) { vm_resume($vmid, 1) if $frozen;
# if we clone a disk for a new target vm, we don't switch the disk
};
if (my $err = $@) {
eval {
vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive"); vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
while (1) { while (1) {
my $stats = vm_mon_cmd($vmid, "query-block-jobs"); my $stats = vm_mon_cmd($vmid, "query-block-jobs");
@ -5239,6 +5225,18 @@ sub qemu_drive_mirror {
last if !$stat; last if !$stat;
sleep 1; sleep 1;
} }
};
die "mirroring error: $err";
}
if ($vmiddst != $vmid) {
# if we clone a disk for a new target vm, we don't switch the disk
vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive");
while (1) {
my $stats = vm_mon_cmd($vmid, "query-block-jobs");
my $stat = @$stats[0];
last if !$stat;
sleep 1;
} }
} }
} }