]>
Commit | Line | Data |
---|---|---|
8667164d FE |
1 | # LXC monitor socket |
2 | ||
3 | package PVE::LXC::Monitor; | |
4 | ||
5 | use strict; | |
6 | use warnings; | |
7 | ||
8 | use IO::Socket::UNIX; | |
9 | use Socket qw(SOCK_STREAM); | |
10 | use POSIX qw(NAME_MAX); | |
11 | ||
12 | use constant { | |
13 | STATE_STOPPED => 0, | |
14 | STATE_STARTING => 1, | |
15 | STATE_RUNNING => 2, | |
16 | STATE_STOPPING => 3, | |
17 | STATE_ABORTING => 4, | |
18 | STATE_FREEZING => 5, | |
19 | STATE_FROZEN => 6, | |
20 | STATE_THAWED => 7, | |
21 | MAX_STATE => 8, | |
22 | }; | |
23 | ||
24 | my $LXC_MSG_SIZE = length(pack('I! Z'.(NAME_MAX+1).' x![I] I', 0, "", 0)); | |
25 | # Unpack an lxc_msg struct. | |
26 | my sub _unpack_lxc_msg($) { | |
27 | my ($packet) = @_; | |
28 | ||
29 | # struct lxc_msg { | |
30 | # lxc_msg_type_t type; | |
31 | # char name[NAME_MAX+1]; | |
32 | # int value; | |
33 | # }; | |
34 | ||
35 | my ($type, $name, $value) = unpack('I!Z'.(NAME_MAX+1).'I!', $packet); | |
36 | ||
37 | if ($type == 0) { | |
38 | $type = 'STATE'; | |
39 | } elsif ($type == 1) { | |
40 | $type = 'PRIORITY'; | |
41 | } elsif ($type == 2) { | |
42 | $type = 'EXITCODE'; | |
43 | } else { | |
44 | warn "unsupported lxc message type $type received\n"; | |
45 | $type = undef; | |
46 | } | |
47 | ||
48 | return ($type, $name, $value); | |
49 | } | |
50 | ||
51 | # Opens the monitor socket | |
52 | # | |
53 | # Dies on errors | |
54 | sub get_monitor_socket { | |
55 | my $socket = IO::Socket::UNIX->new( | |
56 | Type => SOCK_STREAM(), | |
57 | # assumes that lxcpath is '/var/lib/lxc', the hex part is a hash of the lxcpath | |
58 | Peer => "\0lxc/ad055575fe28ddd5//var/lib/lxc", | |
59 | ); | |
60 | if (!defined($socket)) { | |
61 | die "failed to connect to monitor socket: $!\n"; | |
62 | } | |
63 | ||
64 | return $socket; | |
65 | } | |
66 | ||
67 | # Read an lxc message from a socket. | |
68 | # | |
69 | # Returns undef on EOF | |
70 | # Otherwise returns a (type, vmid, value) tuple. | |
71 | # | |
72 | # The returned 'type' currently can be 'STATE', 'PRIORITY' or 'EXITSTATUS'. | |
73 | sub read_lxc_message($) { | |
74 | my ($socket) = @_; | |
75 | ||
76 | my $msg; | |
77 | my $got = recv($socket, $msg, $LXC_MSG_SIZE, 0) | |
78 | // die "failed to read from state socket: $!\n"; | |
79 | ||
80 | if (length($msg) == 0) { | |
81 | return undef; | |
82 | } | |
83 | ||
84 | die "short read on state socket ($LXC_MSG_SIZE != ".length($msg).")\n" | |
85 | if length($msg) != $LXC_MSG_SIZE; | |
86 | ||
87 | my ($type, $name, $value) = _unpack_lxc_msg($msg); | |
88 | ||
89 | return ($type, $name, $value); | |
90 | } | |
91 | ||
92 | 1; |