rumpkernel / rumprun

The Rumprun unikernel and toolchain for various platforms
Other
1.14k stars 128 forks source link

unikernel read from stdin returns EOF (qemu/x86_64) #64

Open jon-jacky opened 8 years ago

jon-jacky commented 8 years ago

I followed the Tutorial: Building Rumprun Unikernels. Starting from helloer.c, I successfully built and ran helloer-rumprun.bin on my host (Mac OS X 10.11.1). helloer.c uses printf to write to stdout (the qemu console display).

I wrote a similar program echoer.c which also uses fgets to read from stdin (see program below). It works as expected when compiled and run on my host: fgets reads input from the keyboard, unless I signal end-of-file by typing ^D (output below). But when I follow the same procedure I used to build and run helloer-rumprun.bin on qemu, in my echoer-rumprun.bin the first call to fgets returns EOF immediately, without reading from the keyboard (output below).

I would like my rumprun programs to read keyboard input from stdin. How can I achieve this?

I discovered this behavior while working with rumprun-packages/python. I successfully built and ran the hw.py/.c/.bin example, which uses Python print to write to stdout. But when I replaced hw.py (etc.) with my own echo.py/.c/.bin that also uses the Python input function to read from stdin, the call to input raises the Python EOFError.

In Python also, I would like to read keyboard input from stdin.

Jon Jacky

/* echoer.c - test reading from stdin in rump kernel */

#include <stdio.h>

int main()
{
  char string[80];
  char *result = "Anything but NULL";
  while (result != NULL) {
    printf (">> ");
    result = fgets(string,80,stdin); /* returns null pointer if EOF */
    if (result != NULL) printf ("%s", string);
  }
  printf("EOF\n");
  return 0;
}
# running echoer on host, Mac OS X 10.11.1.  It echoes until you type ^D to indicate EOF.

$ ./echoer
>> Hello
Hello
>> world
world
>> EOF
$
# running echoer-rumprun.bin unikernel in qemu on host, Mac OS X 10.11.1
# It returns EOF Immediately, then exits

$ rumprun qemu -i echoer-rumprun.bin
...
In qemu window:
...
=== calling "echoer-rumprun.bin" main() ===

>> EOF

=== main() of "echoer-rumprun.bin" returned 0 ===

=== ERROR: _exit(0) called ===
...
anttikantee commented 8 years ago

There's currently no support for keyboard input, and console stdin doesn't actually exist -- nor does stdout in the true sense, but we fake enough of it for things to appear to work. The reason is simple: those parts of rump kernels were solidified before the whole unikernel application of rump kernels existed. Proper stdin/stdout is one of those things that should get dealt with, but it's also tricky enough to require more than an afternoon's worth of time to fix.

You can fake keyboard input in a number of ways, e.g. over the network, though there's no "consumer grade" solution for that currently.

jon-jacky commented 8 years ago

Thanks - this is helpful to know. -- Jon

anttikantee commented 8 years ago

I don't think you should close the issue. The problem exists and should be fixed.

jon-jacky commented 8 years ago

I have reopened it. -- Jon

anttikantee commented 8 years ago

What do you need stdin for? If you can explain it on the mailing list, maybe someone can suggest a workaround that you can use already today.

jon-jacky commented 8 years ago

I would like to use stdin and stdout to interact with a command line program on the local console, in a simple standalone system where the unikernel runs on bare metal.

It is an experiment to see if the rump kernel can be used a simple standalone operating system that can be configured with the minimal support for some particular application. This would be similar to the way some real-time operating systems for embedded systems are used, but without real-time constraints, and with the possibility of supporting more kinds of programming languages and applications.

As I understand it, unikernels typically run "headless" (with no local console) as guest VMs on hosts in a cloud. In that case, you could interact with them via ssh or telnet to a port. But these are not standalone configurations - in addition to the unikernel you need another system with its own console to run the telnet or ssh client.

Jon

mato commented 8 years ago

+1 for standalone operation on bare metal being the major use case for stdin.

jibanes commented 8 years ago

+1

jibanes commented 8 years ago

need this for our app, bump.

anttikantee commented 8 years ago

Generally speaking, if you need a feature for your use case, it is your responsibility to arrange for that feature to be implemented. Spamming an issue report will not magically generate the time or money required to implement features for you.