Skip to content

fix(qemu): propagate host TERM to the x86_64 nographic console - #2273

Merged
fslongjin merged 1 commit into
DragonOS-Community:masterfrom
fslongjin:fix/qemu-nographic-console-term
Sep 13, 2026
Merged

fslongjin merged 1 commit into
DragonOS-Community:masterfrom
fslongjin:fix/qemu-nographic-console-term

Conversation

@fslongjin

@fslongjin fslongjin commented Sep 13, 2026

Copy link
Copy Markdown
Member

Problem

The QEMU nographic console connects the host terminal to the guest /dev/hvc0 but forwards only the byte stream, never the terminal capability name. The kernel initializes PID 1 with TERM=linux (matching Linux 6.6.139 semantics), and BusyBox 1.35.0 init rewrites that to vt102 once VT_OPENQRY on hvc0 reports that the console is not a Linux virtual terminal — correct behavior for a non-VT console. The result is that terminfo-aware programs such as CodeBuddy and tput observe a "no color" capability even though the host terminal renders 256 colors.

Neither entry point passed TERM on the kernel command line:

Entry point Location
Make / Bash tools/run-qemu.sh
Nix start-* / yolo-* tools/qemu/default.nix

Fixing only one of them would produce entry-point dependent behavior, so the decision logic lives in a single sourced helper instead of being duplicated.

Changes

Add tools/qemu/console-term.sh, which resolves the console TERM for the x86_64 BusyBox/hvc0 session:

  • Automatic mode applies only to QEMU nographic stdio with both stdin and stdout attached to a TTY. Here QEMU transparently forwards bytes, so the host TERM describes the actual rendering endpoint and is propagated verbatim. An unset TERM, dumb or linux injects nothing, preserving the guest fallback.
  • DRAGONOS_QEMU_CONSOLE_TERM takes priority, covering Unix socket clients, automation and manually selected terminfo entries. Because BusyBox cannot preserve that value on hvc0, an explicit linux is rejected with an error rather than silently degraded.
  • Value validation: regardless of source, the candidate must be a 1-32 byte ASCII string matching [A-Za-z0-9][A-Za-z0-9._+-]* under LC_ALL=C. The value ends up in a space separated kernel command line, so whitespace, = and control characters cannot inject extra kernel parameters.
  • Conservative fallback: when nothing resolves, no TERM keyword is emitted and the existing x86_64 BusyBox vt102 fallback is preserved.

Both entry points wire in the helper and log the resolved value and its source.

Scope and invariants

  • x86_64 nographic only. RISC-V and LoongArch use different init paths and are left unchanged, since there is no behavioral evidence to justify touching them.
  • No kernel, TTY or application behavior is modified. VT_OPENQRY is not faked into succeeding, and 256 colors are not hardcoded in /etc/profile, /opt/env.sh or any application.
  • No capability is overstated: there is no terminal name mapping and no inference from COLORTERM. The host TERM is propagated exactly, so a missing guest terminfo entry remains a rootfs data concern rather than being masked by an incorrect mapping.

Verification

In an interactive x86_64 nographic session with host TERM=xterm-256color, the boot log reports Guest console TERM=xterm-256color (source=host), tput colors returns 256 after login, and CodeBuddy emits 256-color SGR sequences. With a non-TTY stdio or an unset TERM, no TERM keyword is emitted and behavior matches the pre-change baseline.

Testing

  • Interactive stdio automatic propagation
  • DRAGONOS_QEMU_CONSOLE_TERM explicit override and rejection of invalid values
  • Non-TTY stdio / unset TERM keeps the fallback
  • Unix socket transport without explicit configuration injects nothing

The QEMU nographic console connects the host terminal to the guest
/dev/hvc0 but forwards only the byte stream, never the terminal
capability name. The kernel initializes PID 1 with TERM=linux, matching
Linux 6.6.139 semantics, and BusyBox 1.35.0 init rewrites that value to
vt102 once VT_OPENQRY on hvc0 reports that the console is not a Linux
virtual terminal. That fallback is correct for a non-VT console, but it
leaves terminfo-aware programs such as CodeBuddy and tput with a "no
color" capability even though the host terminal renders 256 colors.

Both launchers created the same console without passing TERM on the
kernel command line: the Make/Bash entry point (tools/run-qemu.sh) and
the Nix entry points (tools/qemu/default.nix). Fixing only one of them
would produce entry-point dependent behavior, so the decision logic now
lives in a single sourced helper instead of being duplicated.

Add tools/qemu/console-term.sh, which resolves the console TERM for the
x86_64 BusyBox/hvc0 session:

- Automatic mode only applies to QEMU nographic stdio with both stdin
  and stdout attached to a TTY, where QEMU transparently forwards bytes
  and the host TERM describes the actual rendering endpoint. The host
  value is propagated verbatim; an unset TERM, dumb or linux leaves the
  guest fallback untouched.
- DRAGONOS_QEMU_CONSOLE_TERM takes priority when set, covering Unix
  socket clients, automation and manually selected terminfo entries.
  Because BusyBox cannot preserve it on hvc0, an explicit value of linux
  is rejected with an error rather than silently degraded.
- Regardless of source, the candidate must be a 1-32 byte ASCII string
  matching [A-Za-z0-9][A-Za-z0-9._+-]* under LC_ALL=C. The value ends up
  in a space separated kernel command line, so whitespace, '=' and
  control characters cannot inject extra kernel parameters.
- When nothing resolves, no TERM keyword is emitted and the existing
  x86_64 BusyBox vt102 fallback is preserved.

Wire the helper into both entry points and log the resolved value and
its source. The change is limited to x86_64 nographic; RISC-V and
LoongArch use different init paths and are left unchanged. No kernel,
TTY or application behavior is modified, and no capability is
overstated: the host TERM is propagated exactly, so a missing guest
terminfo entry remains a rootfs data concern rather than being masked by
an incorrect mapping.

Signed-off-by: longjin <longjin@dragonos.org>
@github-actions github-actions Bot added the Bug fix A bug is fixed in this pull request label Sep 13, 2026
@fslongjin

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-13T07:33:03.845973Z 28cee35 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@fslongjin
fslongjin merged commit f796724 into DragonOS-Community:master Sep 13, 2026
15 checks passed
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 28cee35640

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug fix A bug is fixed in this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant