fix(console): switch conman from ser2net-telnet to direct serial access

The ser2net layer between conman and the serial devices was causing
stair-stepping in terminal output. conman's dev="host:port" uses telnet
protocol, but ser2net's accepter was raw TCP (no telnet mode). The telnet
NVT state machine in conman was stripping bare CR characters from device
output — particularly from Dell switches that use old-style \n\r (LF+CR)
line endings instead of standard \r\n. In telnet, a bare \r not followed
by \n or NUL is non-compliant and gets dropped, leaving bare \n that
causes stair-stepping in the raw-mode terminal.

Fix: conman now opens serial devices directly via the stable udev
symlinks (/dev/consoles/<name>) with seropts, eliminating the telnet
layer entirely. ser2net is stopped and disabled but remains installed
for emergency TCP access (documented workflow: stop conmand, start
ser2net, use telnet, then reverse).

Architecture change:
  Before: device → serial → ser2net (raw TCP) → conman (telnet NVT) → terminal
  After:  device → serial → conman (direct) → terminal

Verified: 7/7 serial devices held by conmand, 7/7 log files capturing,
all \r bytes preserved in terminal output (confirmed via PTY capture).

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
This commit is contained in:
2026-07-29 18:29:31 -05:00
parent 80693e4f8e
commit fa0c77fb58
6 changed files with 98 additions and 85 deletions
+13 -10
View File
@@ -143,14 +143,15 @@ fi
{
echo "%YAML 1.1"
echo "---"
echo "# ser2net configuration for pfv-tsys4 console ports"
echo "# ser2net configuration for pfv-tsys4 console ports (EMERGENCY USE ONLY)"
echo "# Generated by console/generate-config.sh on $(date)"
echo "#"
echo "# All ports bound to Tailscale IP ($TS_IP) for secure remote access."
echo "# Physical devices are accessed via stable udev symlinks in /dev/consoles/."
echo "# WARNING: ser2net is DISABLED by default. conman owns the serial"
echo "# devices directly. If you enable ser2net, STOP conmand first or the"
echo "# two will conflict (only one process can open a serial device at a time)."
echo "#"
echo "# To connect directly: telnet $TS_IP 2001"
echo "# To connect via conman: conman -f <name>"
echo "# Emergency workflow: systemctl stop conmand && systemctl start ser2net"
echo "# When done: systemctl stop ser2net && systemctl start conmand"
echo ""
echo "define: &banner \\r\\nPFV console port \\p device \\d [\\B]\\r\\n\\r\\n"
echo ""
@@ -215,14 +216,16 @@ fi
echo ""
echo "$MARKER_BEGIN"
echo "# Generated by console/generate-config.sh on $(date)"
echo "# Each console connects to a ser2net TCP port via telnet protocol."
echo "# ser2net owns the physical serial device; conman provides logging"
echo "# and multiplexing on top."
echo "# Each console connects directly to its serial device via the stable"
echo "# udev symlink in /dev/consoles/. conman owns the serial devices"
echo "# directly — no ser2net/telnet layer in the data path."
echo "# Access: conman -f <name>"
echo ""
for entry in "${ENTRIES[@]}"; do
IFS='|' read -r tcp_port name id_path baud comment <<< "$entry"
echo "CONSOLE name=\"${name}\" dev=\"${TS_IP}:${tcp_port}\" log=\"${name}.log\" logopts=\"timestamp\""
# Convert baud format: mapping.txt uses 9600n81, conman needs 9600,8n1
conman_seropts=$(echo "$baud" | sed -E 's/^([0-9]+)(.)(.)(.)$/\1,\3\2\4/')
echo "CONSOLE name=\"${name}\" dev=\"/dev/consoles/${name}\" seropts=\"${conman_seropts}\" log=\"${name}.log\" logopts=\"timestamp\""
done
echo "$MARKER_END"
} >> "$CONMAN_CONF"
@@ -244,7 +247,7 @@ echo " $CONMAN_CONF (CONSOLE entries appended between markers)"
echo ""
echo " Next steps:"
echo " 1. Reload udev: udevadm control --reload-rules && udevadm trigger"
echo " 2. Restart ser2net: systemctl restart ser2net"
echo " 2. Stop ser2net: systemctl stop ser2net && systemctl disable ser2net"
echo " 3. Start conman: systemctl enable --now conmand"
echo " 4. Or run: bash $(basename "$0" .sh | sed 's/generate-config/setup/') .sh"
echo "============================================"