Skip to content

scripts/run: Redirect QEMU stdin to /dev/null to prevent SIGTTIN - #108

Open
CristianAndrei1423 wants to merge 1 commit into
unikraft:mainfrom
CristianAndrei1423:main
Open

scripts/run: Redirect QEMU stdin to /dev/null to prevent SIGTTIN#108
CristianAndrei1423 wants to merge 1 commit into
unikraft:mainfrom
CristianAndrei1423:main

Conversation

@CristianAndrei1423

Copy link
Copy Markdown

Bug that is fixed : whenever the testing scripts boots up the QEMU Virtual Machine, it is put in background. Because of that, it is not allowed to read from the terminal, so the kernel sends SIGTTIN and suspends it, making the test fail automatically.

Fix : Just redirect stdin to /dev/null so that QEMU gets EOF instead. The fix was tested with wrapper.sh on nginx.

@vTusharr

vTusharr commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Ah nice will incorporate this

@CristianAndrei1423

Copy link
Copy Markdown
Author

One detail that i need to add is that QEMU vm's read from stdin only when given the -nographic flag. I specifically changed only the scripts that had this flag given.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the per-app QEMU run scripts to prevent backgrounded QEMU processes from being suspended by SIGTTIN when they attempt to read from the controlling terminal, by redirecting stdin to /dev/null.

Changes:

  • Redirect QEMU stdin to /dev/null across multiple .scripts/run/qemu.* scripts.
  • Add line continuations (\) where needed so the stdin redirection applies to the QEMU invocation.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
wamr/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
sqlite/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
sqlite/.scripts/run/qemu.arm64 Redirects QEMU stdin to /dev/null.
redis/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
redis/.scripts/run/qemu.arm64 Attempts to redirect QEMU stdin to /dev/null (currently not correctly attached to the QEMU command).
python3-hello/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
python3-hello/.scripts/run/qemu.arm64 Redirects QEMU stdin to /dev/null.
nginx/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
nginx/.scripts/run/qemu.arm64 Redirects QEMU stdin to /dev/null.
elfloader-net/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
elfloader-basic/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
cpp-http/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
cpp-http/.scripts/run/qemu.arm64 Redirects QEMU stdin to /dev/null.
cpp-hello/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
cpp-hello/.scripts/run/qemu.arm64 Redirects QEMU stdin to /dev/null.
click/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
click/.scripts/run/qemu.arm64 Redirects QEMU stdin to /dev/null.
c-http/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
c-http/.scripts/run/qemu.arm64 Redirects QEMU stdin to /dev/null.
c-hello/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
c-hello/.scripts/run/qemu.arm64 Redirects QEMU stdin to /dev/null.
c-fs/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
c-fs/.scripts/run/qemu.arm64 Redirects QEMU stdin to /dev/null.
bincompat-java-hello/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.
bincompat-c-hello/.scripts/run/qemu.x86_64 Redirects QEMU stdin to /dev/null.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread redis/.scripts/run/qemu.arm64 Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

@AndreiRV1 AndreiRV1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble reproducing the issue on my end. Could you share the exact command you used and which application failed when running under the wrapper script?

@CristianAndrei1423

Copy link
Copy Markdown
Author

Sure, to reproduce the hang:

  1. Go into a catalog-core app (e.g. c-hello) and build it:
./.scripts/build/qemu.x86_64
  1. Run it in the background. Because of the -nographic flag, QEMU wires the guest console to its stdin and tries to read from the controlling terminal:
./.scripts/run/qemu.x86_64 &

A process is only allowed to read the tty when it's in the terminal's foreground process group. Since we backgrounded it, QEMU is in a background process group when it attempts that read, so the kernel sends it SIGTTIN, which suspends the process.

  1. Check the process status: it's T, i.e. stopped by a job-control signal (in our case SIGTTIN), and it produces no output:
ps -o pid,stat,cmd -C qemu-system-x86_64

Redirecting stdin with < /dev/null fixes it: QEMU's stdin is then a file instead of the tty, so there's no tty read and no SIGTTIN, regardless of process group.

One note if you couldn't reproduce it: it won't trigger if you run the script in the foreground, through ./.scripts/test/all.sh, or over a non-interactive / no-tty shell, all of those remove one of SIGTTIN's preconditions.

In particular the test harness doesn't hit it because all.sh runs the app through .scripts/test/wrapper.sh, which (via common.sh's start_instance) launches QEMU with setsid --fork .That detaches it into a new session with no controlling terminal, so SIGTTIN can't fire there.

Hope this helps!

@AndreiRV1 AndreiRV1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the clarification! The changes look great overall, just a couple of small adjustments:

  • Please add some context in the commit body as to underline what? and why? changed.
  • Could you squash the second commit into the first one to keep the history clean?

The QEMU run scripts use -nographic, which wires the guest serial
console to QEMU's stdin. When a run script is started in the background
(as the test harness does), QEMU runs in a background process group and
its attempt to read the controlling terminal makes the kernel raise
SIGTTIN, which suspends the process. The guest never boots and the run
hangs with no output.

Redirect stdin from /dev/null in every qemu run script so QEMU reads an
immediate EOF instead of the terminal. SIGTTIN is no longer raised and
the guest boots regardless of the process group it runs in. The apps do
not consume serial input, so this has no other effect.

Signed-off-by: Cristian Andrei <cristian.andrei1423@gmail.com>
@razvand
razvand requested a review from AndreiRV1 August 22, 2026 10:34
@razvand razvand added the enhancement New feature or request label Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants