]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/QemuServer.pm
migrate: log which local resource causes error
[qemu-server.git] / PVE / QemuServer.pm
index e60aa286ffe9dc2ce15a8742f76031e8dd87adc1..9d560ec3a91031d95fe6fd056e3f2c8298514a7c 100644 (file)
@@ -1281,7 +1281,7 @@ my $hostpci_fmt = {
        pattern => qr/$PCIRE(;$PCIRE)*/,
        format_description => 'HOSTPCIID[;HOSTPCIID2...]',
        description => <<EODESCR,
-Host PCI device pass through. The PCI ID of a host's PCI device or a list 
+Host PCI device pass through. The PCI ID of a host's PCI device or a list
 of PCI virtual functions of the host. HOSTPCIID syntax is:
 
 'bus:dev.func' (hexadecimal numbers)
@@ -1335,7 +1335,7 @@ my $hostpcidesc = {
        verbose_description =>  <<EODESCR,
 Map host PCI devices into guest.
 
-NOTE: This option allows direct access to host hardware. So it is no longer 
+NOTE: This option allows direct access to host hardware. So it is no longer
 possible to migrate such machines - use with special care.
 
 CAUTION: Experimental! User reported problems with this option.
@@ -1905,7 +1905,7 @@ sub print_drive_full {
     my $path;
     my $volid = $drive->{file};
     my $format;
-    
+
     if (drive_is_cdrom($drive)) {
        $path = get_iso_path($storecfg, $vmid, $volid);
     } else {
@@ -2846,23 +2846,23 @@ sub config_list {
 sub check_local_resources {
     my ($conf, $noerr) = @_;
 
-    my $loc_res = 0;
+    my @loc_res = ();
 
-    $loc_res = 1 if $conf->{hostusb}; # old syntax
-    $loc_res = 1 if $conf->{hostpci}; # old syntax
+    push @loc_res, "hostusb" if $conf->{hostusb}; # old syntax
+    push @loc_res, "hostpci" if $conf->{hostpci}; # old syntax
 
-    $loc_res = 1 if $conf->{ivshmem};
+    push @loc_res, "ivshmem" if $conf->{ivshmem};
 
     foreach my $k (keys %$conf) {
        next if $k =~ m/^usb/ && ($conf->{$k} eq 'spice');
        # sockets are safe: they will recreated be on the target side post-migrate
        next if $k =~ m/^serial/ && ($conf->{$k} eq 'socket');
-       $loc_res = 1 if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
+       push @loc_res, $k if $k =~ m/^(usb|hostpci|serial|parallel)\d+$/;
     }
 
-    die "VM uses local resources\n" if $loc_res && !$noerr;
+    die "VM uses local resources\n" if scalar @loc_res && !$noerr;
 
-    return $loc_res;
+    return \@loc_res;
 }
 
 # check if used storages are available on all nodes (use by migrate)
@@ -3798,7 +3798,7 @@ sub config_to_command {
     push @$cmd, get_cpu_options($conf, $arch, $kvm, $machine_type, $kvm_off, $kvmver, $winversion, $gpu_passthrough);
 
     PVE::QemuServer::Memory::config($conf, $vmid, $sockets, $cores, $defaults, $hotplug_features, $cmd);
-    
+
     push @$cmd, '-S' if $conf->{freeze};
 
     push @$cmd, '-k', $conf->{keyboard} if defined($conf->{keyboard});
@@ -3922,7 +3922,7 @@ sub config_to_command {
            my $queues = '';
            if($conf->{scsihw} && $conf->{scsihw} eq "virtio-scsi-single" && $drive->{queues}){
                $queues = ",num_queues=$drive->{queues}";
-           } 
+           }
 
            push @$devices, '-device', "$scsihw_type,id=$controller_prefix$controller$pciaddr$iothread$queues" if !$scsicontroller->{$controller};
            $scsicontroller->{$controller}=1;
@@ -5904,7 +5904,6 @@ sub restore_update_config_line {
     return if $line =~ m/^lock:/;
     return if $line =~ m/^unused\d+:/;
     return if $line =~ m/^parent:/;
-    return if $line =~ m/^template:/; # restored VM is never a template
 
     my $dc = PVE::Cluster::cfs_read_file('datacenter.cfg');
     if (($line =~ m/^(vlan(\d+)):\s*(\S+)\s*$/)) {
@@ -6587,7 +6586,7 @@ sub do_snapshots_with_qemu {
 
     my $storage_name = PVE::Storage::parse_volume_id($volid);
 
-    if ($qemu_snap_storage->{$storecfg->{ids}->{$storage_name}->{type}} 
+    if ($qemu_snap_storage->{$storecfg->{ids}->{$storage_name}->{type}}
        && !$storecfg->{ids}->{$storage_name}->{krbd}){
        return 1;
     }
@@ -6728,7 +6727,7 @@ sub qemu_img_format {
 }
 
 sub qemu_drive_mirror {
-    my ($vmid, $drive, $dst_volid, $vmiddst, $is_zero_initialized, $jobs, $skipcomplete, $qga) = @_;
+    my ($vmid, $drive, $dst_volid, $vmiddst, $is_zero_initialized, $jobs, $skipcomplete, $qga, $bwlimit) = @_;
 
     $jobs = {} if !$jobs;
 
@@ -6755,13 +6754,19 @@ sub qemu_drive_mirror {
     my $opts = { timeout => 10, device => "drive-$drive", mode => "existing", sync => "full", target => $qemu_target };
     $opts->{format} = $format if $format;
 
-    print "drive mirror is starting for drive-$drive\n";
-
-    eval { vm_mon_cmd($vmid, "drive-mirror", %$opts); }; #if a job already run for this device,it's throw an error
+    if (defined($bwlimit)) {
+       $opts->{speed} = $bwlimit * 1024;
+       print "drive mirror is starting for drive-$drive with bandwidth limit: ${bwlimit} KB/s\n";
+    } else {
+       print "drive mirror is starting for drive-$drive\n";
+    }
 
+    # if a job already runs for this device we get an error, catch it for cleanup
+    eval { vm_mon_cmd($vmid, "drive-mirror", %$opts); };
     if (my $err = $@) {
        eval { PVE::QemuServer::qemu_blockjobs_cancel($vmid, $jobs) };
-       die "mirroring error: $err";
+       warn "$@\n" if $@;
+       die "mirroring error: $err\n";
     }
 
     qemu_drive_mirror_monitor ($vmid, $vmiddst, $jobs, $skipcomplete, $qga);
@@ -6899,7 +6904,7 @@ sub qemu_blockjobs_cancel {
 
 sub clone_disk {
     my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
-       $newvmid, $storage, $format, $full, $newvollist, $jobs, $skipcomplete, $qga) = @_;
+       $newvmid, $storage, $format, $full, $newvollist, $jobs, $skipcomplete, $qga, $bwlimit) = @_;
 
     my $newvolid;
 
@@ -6934,6 +6939,7 @@ sub clone_disk {
 
        my $sparseinit = PVE::Storage::volume_has_feature($storecfg, 'sparseinit', $newvolid);
        if (!$running || $snapname) {
+           # TODO: handle bwlimits
            qemu_img_convert($drive->{file}, $newvolid, $size, $snapname, $sparseinit);
        } else {
 
@@ -6943,7 +6949,7 @@ sub clone_disk {
                    if $drive->{iothread};
            }
 
-           qemu_drive_mirror($vmid, $drivename, $newvolid, $newvmid, $sparseinit, $jobs, $skipcomplete, $qga);
+           qemu_drive_mirror($vmid, $drivename, $newvolid, $newvmid, $sparseinit, $jobs, $skipcomplete, $qga, $bwlimit);
        }
     }