optional => 1,
type => 'string',
description => <<EODESCR,
-NOTE: this option is for experts only. It allows you to pass arbitrary arguments to kvm, for example:
+Arbitrary arguments passed to kvm, for example:
args: -no-reboot -no-hpet
+
+NOTE: this option is for experts only.
EODESCR
},
tablet => {
$confdesc->{"net$i"} = $netdesc;
}
-PVE::JSONSchema::register_format('pve-volume-id-or-none', \&verify_volume_id_or_none);
-sub verify_volume_id_or_none {
+PVE::JSONSchema::register_format('pve-volume-id-or-qm-path', \&verify_volume_id_or_qm_path);
+sub verify_volume_id_or_qm_path {
my ($volid, $noerr) = @_;
- return $volid if $volid eq 'none';
+ if ($volid eq 'none' || $volid eq 'cdrom' || $volid =~ m|^/|) {
+ return $volid;
+ }
+
+ # if its neither 'none' nor 'cdrom' nor a path, check if its a volume-id
$volid = eval { PVE::JSONSchema::check_format('pve-volume-id', $volid, '') };
if ($@) {
return undef if $noerr;
volume => { alias => 'file' },
file => {
type => 'string',
- format => 'pve-volume-id-or-none',
+ format => 'pve-volume-id-or-qm-path',
default_key => 1,
format_description => 'volume',
description => "The drive's backing volume.",
print "drive mirror is starting (scanning bitmap) : this step can take some minutes/hours, depend of disk size and storage speed\n";
+ my $finish_job = sub {
+ while (1) {
+ my $stats = vm_mon_cmd($vmid, "query-block-jobs");
+ my $stat = @$stats[0];
+ last if !$stat;
+ sleep 1;
+ }
+ };
+
eval {
vm_mon_cmd($vmid, "drive-mirror", %$opts);
while (1) {
# 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") };
- last if !$@;
+ if (!$@) {
+ &$finish_job();
+ last;
+ }
die $@ if $@ !~ m/cannot be completed/;
}
sleep 1;
my $cancel_job = sub {
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;
- }
+ &$finish_job();
};
if ($err) {