scripts/run: Redirect QEMU stdin to /dev/null to prevent SIGTTIN - #108
scripts/run: Redirect QEMU stdin to /dev/null to prevent SIGTTIN#108CristianAndrei1423 wants to merge 1 commit into
Conversation
|
Ah nice will incorporate this |
|
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. |
There was a problem hiding this comment.
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/nullacross 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.
AndreiRV1
left a comment
There was a problem hiding this comment.
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?
|
Sure, to reproduce the hang:
./.scripts/build/qemu.x86_64
./.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.
ps -o pid,stat,cmd -C qemu-system-x86_64Redirecting 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
left a comment
There was a problem hiding this comment.
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?andwhy?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>
13ac701 to
8e04fb7
Compare
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.