description => "Enable/disable NUMA.",
default => 0,
},
+ hugepages => {
+ optional => 1,
+ type => 'string',
+ description => "Enable/disable hugepages memory.",
+ enum => [qw(any 2 1024)],
+ },
vcpus => {
optional => 1,
type => 'integer',
if ($feature =~ m/^(network|disk|cpu|memory|usb)$/) {
$res->{$1} = 1;
} else {
- warn "ignoring unknown hotplug feature '$feature'\n";
+ die "invalid hotplug feature '$feature'\n";
}
}
return $res;
}
sub foreach_drive {
- my ($conf, $func) = @_;
+ my ($conf, $func, @param) = @_;
foreach my $ds (valid_drive_names()) {
next if !defined($conf->{$ds});
my $drive = parse_drive($ds, $conf->{$ds});
next if !$drive;
- &$func($ds, $drive);
+ &$func($ds, $drive, @param);
}
}
sub foreach_volid {
- my ($conf, $func) = @_;
+ my ($conf, $func, @param) = @_;
my $volhash = {};
}
foreach my $volid (keys %$volhash) {
- &$func($volid, $volhash->{$volid});
+ &$func($volid, $volhash->{$volid}, @param);
}
}
my $cpuunits = defined($conf->{cpuunits}) ?
$conf->{cpuunits} : $defaults->{cpuunits};
- push @$cmd, '/usr/bin/systemd-run';
- push @$cmd, '--scope';
- push @$cmd, '--slice', "qemu";
- push @$cmd, '--unit', $vmid;
- push @$cmd, '--description', "'Proxmox VE VM $vmid'";
- # set KillMode=none, so that systemd don't kill those scopes
- # at shutdown (pve-manager service should stop the VMs instead)
- push @$cmd, '-p', "KillMode=none";
- push @$cmd, '-p', "CPUShares=$cpuunits";
- if ($conf->{cpulimit}) {
- my $cpulimit = int($conf->{cpulimit} * 100);
- push @$cmd, '-p', "CPUQuota=$cpulimit\%";
- }
-
push @$cmd, '/usr/bin/kvm';
push @$cmd, '-id', $vmid;
push @$cpuFlags , 'hv_vapic' if !$nokvm;
push @$cpuFlags , 'hv_time' if !$nokvm;
+ if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 6)) {
+ push @$cpuFlags , 'hv_reset' if !$nokvm;
+ push @$cpuFlags , 'hv_vpindex' if !$nokvm;
+ push @$cpuFlags , 'hv_runtime' if !$nokvm;
+ }
+
} else {
push @$cpuFlags , 'hv_spinlocks=0xffff' if !$nokvm;
}
$migrate_uri = "tcp:${localip}:${migrate_port}";
push @$cmd, '-incoming', $migrate_uri;
push @$cmd, '-S';
+
+ } elsif ($statefile eq 'unix') {
+ # should be default for secure migrations as a ssh TCP forward
+ # tunnel is not deterministic reliable ready and fails regurarly
+ # to set up in time, so use UNIX socket forwards
+ my $socket_addr = "/run/qemu-server/$vmid.migrate";
+ unlink $socket_addr;
+
+ $migrate_uri = "unix:$socket_addr";
+
+ push @$cmd, '-incoming', $migrate_uri;
+ push @$cmd, '-S';
+
} else {
push @$cmd, '-loadstate', $statefile;
}
eval { run_command($cmd); };
}
- eval { run_command($cmd, timeout => $statefile ? undef : 30,
- umask => 0077); };
+ my $cpuunits = defined($conf->{cpuunits}) ? $conf->{cpuunits}
+ : $defaults->{cpuunits};
+
+ my %run_params = (timeout => $statefile ? undef : 30, umask => 0077);
+
+ my %properties = (
+ Slice => 'qemu.slice',
+ KillMode => 'none',
+ CPUShares => $cpuunits
+ );
+
+ if (my $cpulimit = $conf->{cpulimit}) {
+ $properties{CPUQuota} = int($cpulimit * 100);
+ }
+ $properties{timeout} = 10 if $statefile; # setting up the scope shoul be quick
+
+ if ($conf->{hugepages}) {
+
+ my $code = sub {
+ my $hugepages_topology = PVE::QemuServer::Memory::hugepages_topology($conf);
+ my $hugepages_host_topology = PVE::QemuServer::Memory::hugepages_host_topology();
+
+ PVE::QemuServer::Memory::hugepages_mount();
+ PVE::QemuServer::Memory::hugepages_allocate($hugepages_topology, $hugepages_host_topology);
+
+ eval {
+ PVE::Tools::enter_systemd_scope($vmid, "Proxmox VE VM $vmid", %properties);
+ run_command($cmd, %run_params);
+ };
+
+ if (my $err = $@) {
+ PVE::QemuServer::Memory::hugepages_reset($hugepages_host_topology);
+ die $err;
+ }
+
+ PVE::QemuServer::Memory::hugepages_pre_deallocate($hugepages_topology);
+ };
+ eval { PVE::QemuServer::Memory::hugepages_update_locked($code); };
+
+ } else {
+ eval {
+ PVE::Tools::enter_systemd_scope($vmid, "Proxmox VE VM $vmid", %properties);
+ run_command($cmd, %run_params);
+ };
+ }
if (my $err = $@) {
# deactivate volumes if start fails
die "ERROR: file '$archive' does not exist\n" if ! -f $archive;
# try to detect archive type first
- my $pid = open (TMP, "tar tf '$archive'|") ||
+ my $pid = open (my $fh, '-|', 'tar', 'tf', $archive) ||
die "unable to open file '$archive'\n";
- my $firstfile = <TMP>;
+ my $firstfile = <$fh>;
kill 15, $pid;
- close TMP;
+ close $fh;
die "ERROR: archive contaions no data\n" if !$firstfile;
chomp $firstfile;