Bug 214611

Summary: UM: stdout output ceases under certain conditions
Product: Platform Specific/Hardware Reporter: development
Component: UMLAssignee: Jeff Dike (jdike)
Status: CLOSED INVALID    
Severity: normal    
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 5.10.x - 5.14.x Subsystem:
Regression: No Bisected commit-id:
Attachments: Init script to reproduce the bug
Debian UML kernel config
UML config for 5.14.8

Description development 2021-10-03 01:27:04 UTC
Created attachment 299063 [details]
Init script to reproduce the bug

When a UML kernel is run with stdin being a file descriptor to a pipe, stdout works fine until reading from a ubd device. After which, output on stdout ceases even though the UML process continues running. If the UML process is run in such a manner without reading from a ubd device, stdout works as expected. If the UML process is run in the same way, except stdin is a pts device, stdout is unaffected as well. It seems odd that a udb device would be related to output on /dev/console.

This has been tested with the 5.10.46 official debian uml kernel (package name user-mode-linux) and with the 5.14.8 kernel from kernel.org built using the debian 5.10 config. Both were tested on host debian kernel 5.10.40-1. The kernel config files are attached.

To reproduce, run the following command after downloading the attached init script, creating first an empty ubd device.

> truncate -s 1G /$HOME/test.img
> linux.uml rootfstype=hostfs rootflags=/ rw mem=2048M init=$HOME/init.uml-bug
> ubd0=$HOME/test.img root=/dev/root umid=uml-test HOME=$HOME BUG=1 < <(cat
> /dev/null)

The last lines of output are:

> devtmpfs: mounted
> This architecture does not have kernel memory protection.
> Run /home/g10/init.uml-bug as init process
> + test -n 1
> + dd if=/dev/ubda of=/dev/null count=1
> Aborted

But you should see that execution continued after this point and a file $HOME/uml-bug.out was created to verify this.

Having stdin connected to a pts device does not trigger the bug

> linux.uml rootfstype=hostfs rootflags=/ rw mem=2048M init=$HOME/init.uml-bug
> ubd0=$HOME/test.img root=/dev/root umid=uml-test HOME=$HOME BUG=1

Not reading from the ubd device also does not trigger the bug.

> linux.uml rootfstype=hostfs rootflags=/ rw mem=2048M init=$HOME/init.uml-bug
> ubd0=$HOME/test.img root=/dev/root umid=uml-test HOME=$HOME < <(cat
> /dev/null)
Comment 1 development 2021-10-03 01:28:56 UTC
Created attachment 299065 [details]
Debian UML kernel config
Comment 2 development 2021-10-03 01:29:34 UTC
Created attachment 299067 [details]
UML config for 5.14.8
Comment 3 Johannes Berg 2021-10-04 12:51:30 UTC
(in case somebody stumbles across this, from my mailing list post)

This really has nothing to do with UBD or something. What's happening is
that you're using the command line badly.

What do you expect this:

  ... < <(cat /dev/null)

to do?

What happens is that the shell creates a pipe. This pipe is connected on
the one side to fd:1 in UML (stdin) and on the other to stdout of 'cat'.

Now this is all fine, but 'cat' will *quit immediately* since it cannot
read anything from /dev/null (it's write-only!).

Therefore, the fd:1 in UML will be invalidated pretty much immediately,
receiving EPOLLHUP.

This is detected by the epoll code, raising an interrupt into the line
level code, and the line code then closes the stdio console channel
entirely, including stdout.


If anything, the bug is that when you're not causing enough interrupts
by using ubd, somehow this situation doesn't get detected, and the
console remains open, so you still see the output... I think this might
be if closing the FD didn't generate a SIGIO?

In fact, if you generate SIGIO in *any* other way, including pressing
enter while the script is running even if stdin is redirected from your
dead cat [1], you still get the same behaviour of the channel getting
closed.