]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/QemuServer.pm
bwlimit: add parameter to QemuServer::clone_disk
[qemu-server.git] / PVE / QemuServer.pm
index a30533bd4dd36429dfa2267946b3aebf69a86af3..7d2066e482977ae2aeca094033a2d8f6aac9e268 100644 (file)
@@ -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)],
@@ -3065,6 +3060,11 @@ our $vmstatus_return_properties = {
        type => 'number',
        optional => 1,
     },
+    lock => {
+       description => "The current config lock, if any.",
+       type => 'string',
+       optional => 1,
+    }
 };
 
 my $last_proc_pid_stat;
@@ -3135,6 +3135,7 @@ sub vmstatus {
         $d->{template} = PVE::QemuConfig->is_template($conf);
 
        $d->{serial} = 1 if conf_has_serial($conf);
+       $d->{lock} = $conf->{lock} if $conf->{lock};
 
        $res->{$vmid} = $d;
     }
@@ -5226,6 +5227,7 @@ sub vm_start {
        if ($is_suspended) {
            # enforce machine type on suspended vm to ensure HW compatibility
            $forcemachine = $conf->{runningmachine};
+           print "Resuming suspended VM\n";
        }
 
        my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
@@ -5318,7 +5320,7 @@ sub vm_start {
        my $cpuunits = defined($conf->{cpuunits}) ? $conf->{cpuunits}
                                                  : $defaults->{cpuunits};
 
-       my $start_timeout = $conf->{hugepages} ? 300 : 30;
+       my $start_timeout = ($conf->{hugepages} || $is_suspended) ? 300 : 30;
        my %run_params = (timeout => $statefile ? undef : $start_timeout, umask => 0077);
 
        my %properties = (
@@ -5426,6 +5428,7 @@ sub vm_start {
                    value => 2) if (!defined($conf->{balloon}) || $conf->{balloon});
 
        if ($is_suspended && (my $vmstate = $conf->{vmstate})) {
+           print "Resumed VM, removing state\n";
            delete $conf->@{qw(lock vmstate runningmachine)};
            PVE::Storage::deactivate_volumes($storecfg, [$vmstate]);
            PVE::Storage::vdisk_free($storecfg, $vmstate);
@@ -5679,7 +5682,7 @@ sub vm_stop {
 }
 
 sub vm_suspend {
-    my ($vmid, $skiplock, $includestate) = @_;
+    my ($vmid, $skiplock, $includestate, $statestorage) = @_;
 
     my $conf;
     my $path;
@@ -5701,7 +5704,7 @@ sub vm_suspend {
            $conf->{lock} = 'suspending';
            my $date = strftime("%Y-%m-%d", localtime(time()));
            $storecfg = PVE::Storage::config();
-           $vmstate = PVE::QemuConfig->__snapshot_save_vmstate($vmid, $conf, "suspend-$date", $storecfg, 1);
+           $vmstate = PVE::QemuConfig->__snapshot_save_vmstate($vmid, $conf, "suspend-$date", $storecfg, $statestorage, 1);
            $path = PVE::Storage::path($storecfg, $vmstate);
            PVE::QemuConfig->write_config($vmid, $conf);
        } else {
@@ -5723,6 +5726,7 @@ sub vm_suspend {
                    sleep(1);
                    next;
                } elsif ($state->{status} eq 'completed') {
+                   print "State saved, quitting\n";
                    last;
                } elsif ($state->{status} eq 'failed' && $state->{error}) {
                    die "query-savevm failed with error '$state->{error}'\n"
@@ -6724,7 +6728,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;
 
@@ -6751,13 +6755,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)) {
+       my $bwlimit_bps = $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);
@@ -6895,7 +6905,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;
 
@@ -6930,6 +6940,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 {
 
@@ -6939,7 +6950,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);
        }
     }