From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 131541FF0DF for ; Thu, 05 Nov 2026 15:51:09 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 2CBA2215EC; Thu, 05 Nov 2026 15:51:07 +0100 (CET) From: Filip Schauer To: pve-devel@lists.proxmox.com Subject: [RFC container v2 2/2] add container console scrollback buffer Date: Thu, 5 Nov 2026 15:49:44 +0100 Message-ID: <20261105144947.124148-3-f.schauer@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261105144947.124148-1-f.schauer@proxmox.com> References: <20261105144947.124148-1-f.schauer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1793890261616 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.282 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 7ZZC3FO34ON4KZ2KEFWJER2N3ODONEA2 X-Message-ID-Hash: 7ZZC3FO34ON4KZ2KEFWJER2N3ODONEA2 X-MailFrom: f.schauer@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Send a scrollback buffer to new clients connecting to a container console. This is achieved by replacing dtach and lxc-console with pve-lxc-console, which serves the console to all clients and replays a scrollback buffer when a client attaches. For containers with `cmode: console`, we additionally enable the LXC console ring buffer by setting `lxc.console.buffer.size` to 32KB. It records the console output since the container started, and pve-lxc-console reads its data from there. This way, users who open the console too late still see what the container printed earlier, even if no console was open at that time. The other console modes do not need a ring buffer to avoid losing data: with `cmode: tty` the kernel buffers the tty output until it is read, and with `cmode: shell` the shell is only started when the console is opened for the first time. This improves the user experience for containers and is especially useful for many application containers that print important diagnostic messages at startup, that would otherwise be easily missed by users opening the container console slightly too late. This change is backwards-compatible: pve-lxc-console speaks the dtach protocol on the same socket path, so it can still connect to a dtach master that is already running for a container. Upgrading also does not break consoles for already running containers with `cmode: console`. They were started without a console buffer, so if pve-lxc-console has to start a new master for them, it falls back to reading the console data directly. Signed-off-by: Filip Schauer --- debian/control | 1 + src/PVE/API2/LXC.pm | 36 +++--------------------------------- src/PVE/LXC.pm | 11 +++++++++++ 3 files changed, 15 insertions(+), 33 deletions(-) diff --git a/debian/control b/debian/control index 1d77c38..8a2a63f 100644 --- a/debian/control +++ b/debian/control @@ -36,6 +36,7 @@ Depends: binutils, pve-cluster (>= 4.0-8), pve-firewall (>= 6.0.1), pve-ha-manager (>= 5.0.3), + pve-lxc-console, pve-lxc-syscalld, proxmox-backup-client (>= 3.2.3-1), xz-utils, diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm index 63d30d1..713f4df 100644 --- a/src/PVE/API2/LXC.pm +++ b/src/PVE/API2/LXC.pm @@ -1019,17 +1019,7 @@ __PACKAGE__->register_method({ my $ticket = PVE::AccessControl::assemble_vnc_ticket($authuser, $authpath, $port); my $conf = PVE::LXC::Config->load_config($vmid, $node); - my $concmd = PVE::LXC::get_console_command($vmid, $conf, -1); - - my $shcmd = [ - '/usr/bin/dtach', - '-A', - "/var/run/dtach/vzctlconsole$vmid", - '-r', - 'winch', - '-z', - @$concmd, - ]; + my $shcmd = PVE::LXC::get_console_dtach_command($vmid, $conf); my $password; if ($param->{websocket}) { @@ -1150,17 +1140,7 @@ __PACKAGE__->register_method({ my $ticket = PVE::AccessControl::assemble_vnc_ticket($authuser, $authpath, $port); my $conf = PVE::LXC::Config->load_config($vmid, $node); - my $concmd = PVE::LXC::get_console_command($vmid, $conf, -1); - - my $shcmd = [ - '/usr/bin/dtach', - '-A', - "/var/run/dtach/vzctlconsole$vmid", - '-r', - 'winch', - '-z', - @$concmd, - ]; + my $shcmd = PVE::LXC::get_console_dtach_command($vmid, $conf); my $realcmd = sub { my $upid = shift; @@ -1292,17 +1272,7 @@ __PACKAGE__->register_method({ die "CT $vmid not running\n" if !PVE::LXC::check_running($vmid); - my $concmd = PVE::LXC::get_console_command($vmid, $conf); - - my $shcmd = [ - '/usr/bin/dtach', - '-A', - "/var/run/dtach/vzctlconsole$vmid", - '-r', - 'winch', - '-z', - @$concmd, - ]; + my $shcmd = PVE::LXC::get_console_dtach_command($vmid, $conf); my $title = "CT $vmid"; diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm index 78cc4cf..9cd0baf 100644 --- a/src/PVE/LXC.pm +++ b/src/PVE/LXC.pm @@ -871,6 +871,9 @@ sub update_lxc_config { } } + my $cmode = PVE::LXC::Config->get_cmode($conf); + $raw .= "lxc.console.buffer.size = 32KB\n" if ($cmode eq 'console'); + my $had_cpuset = 0; if (my $lxcconf = $conf->{lxc}) { foreach my $entry (@$lxcconf) { @@ -952,6 +955,14 @@ sub get_console_command { return $cmd; } +sub get_console_dtach_command { + my ($vmid, $conf) = @_; + + my $cmode = PVE::LXC::Config->get_cmode($conf); + + return ['pve-lxc-console', '-m', $cmode, $vmid]; +} + sub get_primary_ips { my ($conf) = @_; -- 2.47.3