X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=PVE%2FQemuServer.pm;h=9d560ec3a91031d95fe6fd056e3f2c8298514a7c;hb=ca6abacf6b12bb20f23576bcb829f1d934768075;hp=c21876beae4b6345c7f5078263061e2d5bc2bd89;hpb=11efdfa5a96bf016985e6847b7249dce5effd21c;p=qemu-server.git diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index c21876b..9d560ec 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -2,6 +2,7 @@ package PVE::QemuServer; use strict; use warnings; + use POSIX; use IO::Handle; use IO::Select; @@ -77,12 +78,6 @@ PVE::JSONSchema::register_standard_option('pve-qm-stateuri', { optional => 1, }); -PVE::JSONSchema::register_standard_option('pve-snapshot-name', { - description => "The name of the snapshot.", - type => 'string', format => 'pve-configid', - maxLength => 40, -}); - PVE::JSONSchema::register_standard_option('pve-qm-image-format', { type => 'string', enum => [qw(raw cow qcow qed qcow2 vmdk cloop)], @@ -1286,7 +1281,7 @@ my $hostpci_fmt = { pattern => qr/$PCIRE(;$PCIRE)*/, format_description => 'HOSTPCIID[;HOSTPCIID2...]', description => < <{file}; my $format; - + if (drive_is_cdrom($drive)) { $path = get_iso_path($storecfg, $vmid, $volid); } else { @@ -2851,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) @@ -3803,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}); @@ -3927,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; @@ -5909,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*$/)) { @@ -6592,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; } @@ -6733,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; @@ -6760,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); @@ -6904,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; @@ -6939,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 { @@ -6948,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); } }