]>
git.proxmox.com Git - qemu-server.git/blob - PVE/QemuServer/Helpers.pm
1 package PVE
::QemuServer
::Helpers
;
20 my $nodename = PVE
::INotify
::nodename
();
22 # Paths and directories
24 our $var_run_tmpdir = "/var/run/qemu-server";
25 mkdir $var_run_tmpdir;
28 my ($vmid, $qga) = @_;
29 my $sockettype = $qga ?
'qga' : 'qmp';
30 return "${var_run_tmpdir}/$vmid.$sockettype";
35 return "${var_run_tmpdir}/$vmid.pid";
40 return "${var_run_tmpdir}/$vmid.vnc";
43 # Parse the cmdline of a running kvm/qemu process and return arguments as hash
47 my $fh = IO
::File-
>new("/proc/$pid/cmdline", "r");
52 my @param = split(/\0/, $line);
55 return if !$cmd || ($cmd !~ m
|kvm
$| && $cmd !~ m
@(?
:^|/)qemu-system-[^/]+$@);
59 for (my $i = 0; $i < scalar (@param); $i++) {
63 if ($p =~ m/^--?(.*)$/) {
65 $phash->{$pending_cmd} = {};
68 } elsif ($pending_cmd) {
69 $phash->{$pending_cmd} = { value
=> $p };
79 sub vm_running_locally
{
82 my $pidfile = pidfile_name
($vmid);
84 if (my $fd = IO
::File-
>new("<$pidfile")) {
89 my $mtime = $st->mtime;
90 if ($mtime > time()) {
91 warn "file '$pidfile' modified in future\n";
94 if ($line =~ m/^(\d+)$/) {
96 my $cmdline = parse_cmdline
($pid);
97 if ($cmdline && defined($cmdline->{pidfile
}) && $cmdline->{pidfile
}->{value
}
98 && $cmdline->{pidfile
}->{value
} eq $pidfile) {
99 if (my $pinfo = PVE
::ProcFSTools
::check_process_running
($pid)) {
110 my ($verstr, $major, $minor, $pve) = @_;
112 if ($verstr =~ m/^(\d+)\.(\d+)(?:\.(\d+))?(?:\+pve(\d+))?/) {
113 return 1 if version_cmp
($1, $major, $2, $minor, $4, $pve) >= 0;
117 die "internal error: cannot check version of invalid string '$verstr'";
120 # gets in pairs the versions you want to compares, i.e.:
121 # ($a-major, $b-major, $a-minor, $b-minor, $a-extra, $b-extra, ...)
122 # returns 0 if same, -1 if $a is older than $b, +1 if $a is newer than $b
126 my $size = scalar(@versions);
128 return 0 if $size == 0;
131 my (undef, $fn, $line) = caller(0);
132 die "cannot compare odd count of versions, called from $fn:$line\n";
135 for (my $i = 0; $i < $size; $i += 2) {
136 my ($a, $b) = splice(@versions, 0, 2);
141 return -1 if $a < $b;
146 sub config_aware_timeout
{
147 my ($config, $memory, $is_suspended) = @_;
150 # Based on user reported startup time for vm with 512GiB @ 4-5 minutes
151 if (defined($memory) && $memory > 30720) {
152 $timeout = int($memory/1024);
155 # When using PCI passthrough, users reported much higher startup times,
156 # growing with the amount of memory configured. Constant factor chosen
157 # based on user reports.
158 if (grep(/^hostpci[0-9]+$/, keys %$config)) {
162 if ($is_suspended && $timeout < 300) {
166 if ($config->{hugepages
} && $timeout < 150) {
173 sub get_node_pvecfg_version
{
176 my $nodes_version_info = PVE
::Cluster
::get_node_kv
('version-info', $node);
177 return if !$nodes_version_info->{$node};
179 my $version_info = decode_json
($nodes_version_info->{$node});
180 return $version_info->{version
};
183 sub pvecfg_min_version
{
184 my ($verstr, $major, $minor, $release) = @_;
186 return 0 if !$verstr;
188 if ($verstr =~ m/^(\d+)\.(\d+)(?:[.-](\d+))?/) {
189 return 1 if version_cmp
($1, $major, $2, $minor, $3 // 0, $release) >= 0;
193 die "internal error: cannot check version of invalid string '$verstr'";
196 sub parse_number_sets
{
199 foreach my $part (split(/;/, $set)) {
200 if ($part =~ /^\s*(\d+)(?:-(\d+))?\s*$/) {
201 die "invalid range: $part ($2 < $1)\n" if defined($2) && $2 < $1;
202 push @$res, [ $1, $2 ];
204 die "invalid range: $part\n";
210 sub windows_version
{
213 return 0 if !$ostype;
217 if($ostype eq 'wxp' || $ostype eq 'w2k3' || $ostype eq 'w2k') {
219 } elsif($ostype eq 'w2k8' || $ostype eq 'wvista') {
221 } elsif ($ostype =~ m/^win(\d+)$/) {