]>
Commit | Line | Data |
---|---|---|
d036e418 SR |
1 | package PVE::QemuServer::Helpers; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
babf613a SR |
6 | use File::stat; |
7 | ||
d036e418 | 8 | use PVE::INotify; |
babf613a | 9 | use PVE::ProcFSTools; |
d036e418 SR |
10 | |
11 | my $nodename = PVE::INotify::nodename(); | |
12 | ||
13 | # Paths and directories | |
14 | ||
15 | our $var_run_tmpdir = "/var/run/qemu-server"; | |
16 | mkdir $var_run_tmpdir; | |
17 | ||
18 | sub qmp_socket { | |
19 | my ($vmid, $qga) = @_; | |
20 | my $sockettype = $qga ? 'qga' : 'qmp'; | |
21 | return "${var_run_tmpdir}/$vmid.$sockettype"; | |
22 | } | |
23 | ||
24 | sub pidfile_name { | |
25 | my ($vmid) = @_; | |
26 | return "${var_run_tmpdir}/$vmid.pid"; | |
27 | } | |
28 | ||
29 | sub 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 |
35 | sub 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 | ||
70 | sub 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 | 100 | 1; |