-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runc create hangs when passed a pipe for stdout or stderr #1721
Comments
What is your |
Unset, which, according to the docs, means |
As far as I can tell, If I try to do it as
|
(We really need to document this somewhere other than issues, or I should come up with a canned reply to questions about There are three main cases that can occur with pty handling:
So, if you're piping |
Very much would be appreciated. I struggled with isolating my problem for a while.
I couldn’t figure that out either. What gets passed? The path to a Unix domain socket, ok, but is that socket itself intended to become one of stdout or similar? How does that align with “pty will be set up by runc”?
This is exactly what I was trying to do. Why in this case does setting stdout or stderr to existing stdout/stderr or to an actual file work, but to a pipe or a buffer hang? |
It does, thank you. |
@cyphar re: documenting; should there be a “docs” or “examples” directory in this repo? |
#1018 implemented
I am not sure, and I will take a look at this when I get a chance. |
@thaJeztah Yeah we probably should have a |
@cyphar so it creates all three stdio descriptors, and then passes them via the socket? So I
Is that it? Why didn’t it just let me pass to it
Thanks. Much appreciated. I started to dig into the code myself, but not being familiar with it from the get go means it will take me a lot longer. I’m having a hard time reasoning about what could hang with a pipe or byte buffer that wouldn’t with a file or stdout (which is a file handle, but then again, so is a pipe). |
And if I ever actually fully get it, happy to open a PR for docs for this part. |
👍 for documentation about terminal behavior with runc. I also have a relevant question in a related ticket #1716 |
Now, you could manually do the above instead of using As for why we don't have
The main arguments that are against having specific flags for stdio (or extending
|
I kid you not, I had to reread this several times before I was sure I got it. :-) I still have to read #1018 in depth when I have a chance (off for a few days now), and I will. And if I didn’t say it yet, thank you for the great detail. Basically, it sounds like the summary is:
That fair? |
Damn, I was trying to make it simpler to understand. :/ Your summary is pretty much on the money aside from this point:
This isn't correct. There are many good reasons to use In addition, in non-detached mode, |
Read it not as a criticism of your writing, but a view into my brain’s addled state. :-)
Basically, you are saying, it almost always makes sense to do I understand it, but it feels like it goes against the grain on Unix style streams and pipes. I start processes, they inherit stdio no matter how far down, and I always can pipe into their stdin or out of their stdout/stderr. |
Yeah, I agree. But unfortunately when you're basically booting a separate operating system, the purity of pipes is less usable -- though of course note that if you don't run in detached mode this shouldn't be an issue (since |
So basically, the message is, "use I will put in a PR for docs later this week. |
@cyphar read through this a number of times. As far as I can tell, if you set However, this does not change what the container's process has, only allows you to "tap into it". The net effect appears to be that I (outside process) can feed to its stdin by writing to that fd, and I can read the combined stdout/stderr but reading from that fd. But I cannot, e.g., separate stderr from stdout (i.e. fds 1 and 2 are combined onto that passed fd). If I wanted to do that, I would need to run it foreground. Is that correct? I feel like it may be inherent to the nature of setting up a new pty, i.e. (as you put it) "basically booting a separate operating system" means you expect a terminal as a console, and that terminal doesn't really have separate stderr/stdout or pipes to/from stdio, just a console. If you want to do more "regular Unix-y stdio things" (yes, I really just wrote that.... :-) ), then you need to run foreground or Understanding correct? |
I created a PR for documenting it. In doing so, I realized that having a simple library to interact with the |
Abstracted out #1731 |
@deitch [I am currently on vacation, so sorry for the brief response.] I believe what you wrote is effectively correct, but I'll read through it again when I have some more time.
Effectively yes. When you open a new shell on your machine, you'll find that |
Another one who does OSS on vacation? I know I am in good company, but what is it with us? @jmahowald said to me about this, "don't complain. We are blessed that we enjoy what we do." I thank you. Looking forward to seeing those PRs (fixed if needed and then) merged in. Enjoy vacation! |
Alright, we now have documentation. Time to fix this issue. I'll take a look at this again later this week. |
@cyphar were you able to find something? I am currently looking into runc+criu tests (i.e. https://github.com/opencontainers/runc/blob/5b38ef7173cfd50e8fb6ded787876b8406f29408/tests/integration/checkpoint.bats#L51..L235) and it is likely I am hitting the issue described. I guess this is also the reason for commit 5369f9a by @filbranden |
No, I stared at the stall for a while and couldn't figure it out. My line of thinking was that there's something odd going on with how Go is copying the input, but this bug is so old I've forgotten where I got with debugging it. I can give it another shot though. |
On the other hand using pipes would be the safest option when using detached-passhtrough mode. The documentation even warns about passing regular files or ttys in that mode. And yet the safest one is the one that doesn't work according to this issue. 😞 Are there any more details under which constellations pipes cause hangs? Is it std in/out/err? Is it combining out/err? Does it depend on the O_NONBLOCK fcntl? |
We also ran into this with Go and
We worked around this by setting |
I found this by playing with various options in golang
cmd := exec.Command("runc")
and changingcmd.Stdout
, etc. to try and capture output from a container run. It works if I make stdoutos.Stdout
or an actualfile
, but anything else causes it to hang.For example:
cmd.Stdout = io.MultiWriter(os.Stdout)
cmd.Stdout = io.MultiWriter(file)
pipe := cmd.StdoutPipe()
- hangs when you doio.Copy(os.Stdout, pipe)
A sample with this is here
But it turns out I can recreate the problem simply:
The above hangs.
Is this because of some strange pty/tty handling? How would I work around it if I need to capture stdout from a
runc create
and possibly send it to other areas? E.g.runc create echo | tree /tmp/foo
The text was updated successfully, but these errors were encountered: