]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer/Helpers.pm
refactor: extract QEMU machine related helpers to package
[qemu-server.git] / PVE / QemuServer / Helpers.pm
CommitLineData
d036e418
SR
1package PVE::QemuServer::Helpers;
2
3use strict;
4use warnings;
5
babf613a
SR
6use File::stat;
7
d036e418 8use PVE::INotify;
babf613a 9use PVE::ProcFSTools;
d036e418
SR
10
11my $nodename = PVE::INotify::nodename();
12
13# Paths and directories
14
15our $var_run_tmpdir = "/var/run/qemu-server";
16mkdir $var_run_tmpdir;
17
18sub qmp_socket {
19 my ($vmid, $qga) = @_;
20 my $sockettype = $qga ? 'qga' : 'qmp';
21 return "${var_run_tmpdir}/$vmid.$sockettype";
22}
23
24sub pidfile_name {
25 my ($vmid) = @_;
26 return "${var_run_tmpdir}/$vmid.pid";
27}
28
29sub vnc_socket {
30 my ($vmid) = @_;
31 return "${var_run_tmpdir}/$vmid.vnc";
32}
33
babf613a
SR
34# Parse the cmdline of a running kvm/qemu process and return arguments as hash
35sub parse_cmdline {
36 my ($pid) = @_;
37
38 my $fh = IO::File->new("/proc/$pid/cmdline", "r");
39 if (defined($fh)) {
40 my $line = <$fh>;
41 $fh->close;
42 return undef if !$line;
43 my @param = split(/\0/, $line);
44
45 my $cmd = $param[0];
46 return if !$cmd || ($cmd !~ m|kvm$| && $cmd !~ m@(?:^|/)qemu-system-[^/]+$@);
47
48 my $phash = {};
49 my $pending_cmd;
50 for (my $i = 0; $i < scalar (@param); $i++) {
51 my $p = $param[$i];
52 next if !$p;
53
54 if ($p =~ m/^--?(.*)$/) {
55 if ($pending_cmd) {
56 $phash->{$pending_cmd} = {};
57 }
58 $pending_cmd = $1;
59 } elsif ($pending_cmd) {
60 $phash->{$pending_cmd} = { value => $p };
61 $pending_cmd = undef;
62 }
63 }
64
65 return $phash;
66 }
67 return undef;
68}
69
70sub vm_running_locally {
71 my ($vmid) = @_;
72
73 my $pidfile = pidfile_name($vmid);
74
75 if (my $fd = IO::File->new("<$pidfile")) {
76 my $st = stat($fd);
77 my $line = <$fd>;
78 close($fd);
79
80 my $mtime = $st->mtime;
81 if ($mtime > time()) {
82 warn "file '$pidfile' modified in future\n";
83 }
84
85 if ($line =~ m/^(\d+)$/) {
86 my $pid = $1;
87 my $cmdline = parse_cmdline($pid);
88 if ($cmdline && defined($cmdline->{pidfile}) && $cmdline->{pidfile}->{value}
89 && $cmdline->{pidfile}->{value} eq $pidfile) {
90 if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
91 return $pid;
92 }
93 }
94 }
95 }
96
97 return undef;
98}
99
d036e418 1001;