/rump are hijacked to go to the rump server. So you can e.g. start
a hijacked shell and cd to /rump:
$ cd /rump
$ pwd
/rump
$ ls -l dev/null
crwxr-xr-x 1 root wheel 2, 2 Feb 17 12:35 dev/null
$ ls -l /dev/null
crw-rw-rw- 1 root wheel 2, 2 Dec 22 2009 /dev/null
$ chmod 0 /dev/null
chmod: /dev/null: Operation not permitted
$ chmod 0 dev/null
$ ls -l /rump/dev/null
c--------- 1 root wheel 2, 2 Feb 17 12:35 /rump/dev/null
(of course the rump server must have vfs loaded for that to work)
while for some cases attempting retry after server restart works
brilliantly (e.g. firefox), in other cases it's quite disasterous
(sshd doesn't like its file descriptors going missing and does not
attempt to reopen them, leading to a quite catastophic loop of
EBADF once the server does come back)
* rename RUMPHIJACK_RETRY to the slightly more sensible
RUMPHIJACK_RETRYCONNECT
rump tcp/ip stack:
* sshd likes to fork and then re-exec itself
==> trap execve() and augment the env with the current parameters
essential to a rump kernel (kernel communication fd, information
about dup2'd file descriptors)
* sshd likes to play lots of games with pipes, socketpairs and dup{,2}()
==> make sure we do not close essential rump client descriptors:
dup() them to a safe place, except for F_CLOSEM where we
simply leave them alone. also, partially solved by the above,
make sure the process's set of rump kernel descriptors persists
over exec()
* sshd likes to chdir() before exec
==> for unix-style rump_sp(7) sockets save the full path on the
initial exec and use it afterwards. thread the path through
the environment in execve()
expired it would assume that all input set descriptors had activity.
In case we get rv == 0 from the poll backend, zero out the fd sets
to signal that in fact no descriptors have activity.
Before this commit ssh was "jittery" when run through a rump tcp/ip
stack (interactive sessions kept blocking on stdin and you had to
"peddle" the connection). Now it works smoothly ... or at least
smoothly enough so that this commit could be done through a rump
tcp/ip stack:
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
root ssh 125 0 tcp localhost.65517 cvs.netbsd.org.22
libc resolver uses it. Error out in case of rump fd kevent (TODO).
Fixes one more problem pointed out by Alexander Nasonov.
Also, implement dup().
(TODO: implement it along the fcntl path too)
it. I still don't have any idea what the ssp stuff is supposed to
do and how it's supposed to even begin to work. If someone wants
to change this now, run tests/lib/librumphijack before commit so
that I can avoid another multihour debugging session!
with adding new calls and makes all existing fd-accepting hijacked
calls dual-kernel. It would be better to autogenerate the code
from syscalls.master, but this is easier for now.
Since fds[] does not go to both kernels, set revents to 0 when
splitting the vector. Now any stale revents passed by the caller
do not get counted as results for the kernel which did not "win"
the poll.
This fixes a situation where a firefox transfer would occasionally
stall. Now firefox works full speed with a rump networking stack.
stderr to be treated as a rump kernel fd as well. Makes e.g.
bozohttpd work better with stderr logging.
Also, add aborty stubs for kqueue.
(implementing kqueue is even trickier than implementing select/poll
since we need to keep state for two kqueue fd's)
now automatically picked based on the ABI of the target the library
is compiled for.
(the host libc symbolname to override still needs a little attention
based on the system version)
contact the X server. Since most of the useful cases these days
are local, add a toggle which forwards PF_LOCAL sockets to the host
and all other protocol families to the rump kernel.
This makes an unmodified firefox work with a rump TCP/IP stack.
I'm sure someone will find applications for being able to run
multiple web browser profiles on one OS with each browser having
a different IP address in the same subnet ...
would have been much easier if up to and including 5.0 we wouldn't
silently cap the nfds argument to poll(!!!).
Makes things like socket(1) work out-of-the-box, and pretty much
every other decidedly prehistoric select() user.
(netcat is a slight exception since it sets FD_SETSIZE, a.k.a.
interface-of-the-year, to 16)
to convince non-rumped applications to communicate with a rump
kernel instead of the host kernel. The precision of what goes
where is not exactly surgical, but for example when wanting to
debug a web server's TCP/IP stack interaction, it might be enough.
When all you have is a hand grenade, all problems look like a ....
hmm?
There's still plenty to figure out. For example, I'm not sure what
the user interface will be like. Now it just attempts to hijack
network communication. It also needs to sync with symbol renaming
in libc, and maybe autogenerate the non-schizophrenic wrappers
where the communication is heading to exactly one destination, lest
I'll be a mummmy by the time I finish writing them all. As a fun
example of a non-non-schizophrenic one, consider poll().
Work in progress, but I managed to get two non-rumped netcats
talking to each other or fetching the index from a non-rumped
thttpd. telnet works in one direction (i can read the data from
netcat, but anything i send back is not printed). bozohttpd uses
dup2() which i haven't bothered to address yet, etcetc.
(not hooking this up the build for now)