fix: vm-run console commands not returning output with cloud-hypervisor

Cloud-hypervisor's hybrid vsock (Unix socket + CONNECT protocol) doesn't
support half-close. When recv_pkt() gets a 0-byte read from shutdown(SHUT_WR),
it sends VSOCK_OP_SHUTDOWN with both RCV|SEND flags, tearing down the entire
connection and killing the response path.

Two fixes:
- Remove s.shutdown(SHUT_WR) from the vsock proxy
- Make guest command handler self-terminating: head -1 | bash. The pipe
  gives bash a clean EOF after one command line, so it no longer depends
  on vsock half-close to exit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Davíð Steinn Geirsson 2026-03-22 17:01:46 +00:00
parent faad5006c9
commit 22f632df88
2 changed files with 4 additions and 6 deletions

View file

@ -258,6 +258,9 @@ let
sys.stdout.buffer.flush()
# Bidirectional proxy: stdin → socket, socket → stdout
# Note: no s.shutdown(SHUT_WR) — cloud-hypervisor hybrid vsock doesn't
# support half-close; it tears down the entire connection, killing the
# response path. The guest command handler exits on its own after one command.
def forward_in():
try:
while True:
@ -267,11 +270,6 @@ let
s.sendall(data)
except Exception:
pass
finally:
try:
s.shutdown(socket.SHUT_WR)
except Exception:
pass
threading.Thread(target=forward_in, daemon=True).start()

View file

@ -43,7 +43,7 @@ in
''}";
ExecStart = pkgs.writeShellScript "vsock-cmd" ''
source /etc/set-environment
exec ${pkgs.bashInteractive}/bin/bash
${pkgs.coreutils}/bin/head -1 | ${pkgs.bashInteractive}/bin/bash
'';
ExecStopPost = "${pkgs.writeShellScript "touch-activity-stop" ''
touch /run/user/1000/vmsilo/last-activity