[pve-devel] [PATCH v2 container 1/2] Add module for reading state changes from monitor socket

Fabian Ebner f.ebner at proxmox.com
Tue Sep 8 13:58:42 CEST 2020


Will be used to monitor state changes on container startup.

Co-developed-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
Signed-off-by: Fabian Ebner <f.ebner at proxmox.com>
---

New in v2.

I hard-coded the name of the abstract UNIX socket instead of
trying to re-implement lxc/monitor.c's lxc_monitor_sock_name
function. For us, is it true that the lxcpath is always '/varl/lib/lxc'?
Otherwise this won't always work.

 src/PVE/LXC/Makefile   |  1 +
 src/PVE/LXC/Monitor.pm | 92 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+)
 create mode 100644 src/PVE/LXC/Monitor.pm

diff --git a/src/PVE/LXC/Makefile b/src/PVE/LXC/Makefile
index f4f4dc1..a190260 100644
--- a/src/PVE/LXC/Makefile
+++ b/src/PVE/LXC/Makefile
@@ -4,6 +4,7 @@ SOURCES= \
 	Config.pm \
 	Create.pm \
 	Migrate.pm \
+	Monitor.pm \
 	Setup.pm \
 	Tools.pm
 
diff --git a/src/PVE/LXC/Monitor.pm b/src/PVE/LXC/Monitor.pm
new file mode 100644
index 0000000..3a592b5
--- /dev/null
+++ b/src/PVE/LXC/Monitor.pm
@@ -0,0 +1,92 @@
+# LXC monitor socket
+
+package PVE::LXC::Monitor;
+
+use strict;
+use warnings;
+
+use IO::Socket::UNIX;
+use Socket qw(SOCK_STREAM);
+use POSIX qw(NAME_MAX);
+
+use constant {
+    STATE_STOPPED => 0,
+    STATE_STARTING => 1,
+    STATE_RUNNING => 2,
+    STATE_STOPPING => 3,
+    STATE_ABORTING => 4,
+    STATE_FREEZING => 5,
+    STATE_FROZEN => 6,
+    STATE_THAWED => 7,
+    MAX_STATE => 8,
+};
+
+my $LXC_MSG_SIZE = length(pack('I! Z'.(NAME_MAX+1).' x![I] I', 0, "", 0));
+# Unpack an lxc_msg struct.
+my sub _unpack_lxc_msg($) {
+    my ($packet) = @_;
+
+    # struct lxc_msg {
+    #     lxc_msg_type_t type;
+    #     char name[NAME_MAX+1];
+    #     int value;
+    # };
+
+    my ($type, $name, $value) = unpack('I!Z'.(NAME_MAX+1).'I!', $packet);
+
+    if ($type == 0) {
+	$type = 'STATE';
+    } elsif ($type == 1) {
+	$type = 'PRIORITY';
+    } elsif ($type == 2) {
+	$type = 'EXITCODE';
+    } else {
+	warn "unsupported lxc message type $type received\n";
+	$type = undef;
+    }
+
+    return ($type, $name, $value);
+}
+
+# Opens the monitor socket
+#
+# Dies on errors
+sub get_monitor_socket {
+    my $socket = IO::Socket::UNIX->new(
+	Type => SOCK_STREAM(),
+	# assumes that lxcpath is '/var/lib/lxc', the hex part is a hash of the lxcpath
+	Peer => "\0lxc/ad055575fe28ddd5//var/lib/lxc",
+    );
+    if (!defined($socket)) {
+	die "failed to connect to monitor socket: $!\n";
+    }
+
+    return $socket;
+}
+
+# Read an lxc message from a socket.
+#
+# Returns undef on EOF
+# Otherwise returns a (type, vmid, value) tuple.
+#
+# The returned 'type' currently can be 'STATE', 'PRIORITY' or 'EXITSTATUS'.
+sub read_lxc_message($) {
+    my ($socket) = @_;
+
+    my $msg;
+    my $got = recv($socket, $msg, $LXC_MSG_SIZE, 0)
+	// die "failed to read from state socket: $!\n";
+
+    if (length($msg) == 0) {
+	return undef;
+    }
+
+    die "short read on state socket ($LXC_MSG_SIZE != ".length($msg).")\n"
+	if length($msg) != $LXC_MSG_SIZE;
+
+    my ($type, $name, $value) = _unpack_lxc_msg($msg);
+
+    return ($type, $name, $value);
+}
+
+1;
-- 
2.20.1






More information about the pve-devel mailing list