Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Hybrid TTY+socket mode for SSH and sudo #148
Per #139, now that large messages don't trigger bad buffering behaviour, a new problem emerges: the UNIX TTY layer is ancient and not really built for what we're doing to it, and so it has tiny fixed size (1-4KB) buffers which force large file transfers to loop thousands of times in slow Python code.
We can't get away from using TTY layer to capture sudo and SSH password prompts (etc), but that does not mean sudo or SSH's actual stdin/stdout needs to be connected to that controlling TTY.
Instead, tty_create_child() would change so that it returns an fd for the TTY (like today), in addition to a socketpair. In the forked child, the usual juju is triggered to cause the child's controlling TTY to become the slave end, /but then/ the SSH or sudo command is executed after redirecting stdin/stdout to the socketpair, whose other end is returned in the parent process alongside the TTY master fd.
This lets us have our cake and eat it: handle getpass-style apps like SSH and sudo that require a TTY for interactive password input, but gives us a socket with a configurable send buffer for the actual throughput-heavy IO.
This will require pretty much rewriting the SSH and sudo bootstraps, as different strings will be appearing on different file descriptors, but it'll be more than worth it
The above should handle sudo perfectly.
With a command line like "ssh box python -c ....", we have:
The sshd-created pipe is likely another source of annoyance, but at least on Linux we have latitude in the form of F_SETPIPE_SZ, meanwhile the default pipe buffer size on modern Linuxes is already 64kb