28.08.2015 Views

The Design and Implementation of the Anykernel and Rump Kernels

1F3KDce

1F3KDce

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

178<br />

Supporting fork()<br />

Recall, <strong>the</strong> fork() system call creates a copy <strong>of</strong> <strong>the</strong> calling process which essentially<br />

differs only by <strong>the</strong> process ID number. After forking, <strong>the</strong> child process shares <strong>the</strong><br />

parent’s file descriptor table <strong>and</strong> <strong>the</strong>refore it shares <strong>the</strong> rumpclient socket. A shared<br />

connection cannot be used, since use <strong>of</strong> <strong>the</strong> same socket from multiple independent<br />

processes will result in corrupt transmissions. Ano<strong>the</strong>r connection must be initiated<br />

by <strong>the</strong> child. However, as stated earlier, a new connection is treated like an initial<br />

login <strong>and</strong> means that <strong>the</strong> child will not have access to <strong>the</strong> parent’s rump kernel<br />

state, including file descriptors. Applications such as web servers <strong>and</strong> shell input<br />

redirection depend on <strong>the</strong> behavior <strong>of</strong> file descriptors being correctly preserved over<br />

fork.<br />

We solve <strong>the</strong> issue by dividing forking into three phases. First, <strong>the</strong> forking process<br />

informs <strong>the</strong> rump kernel that it is about to fork. <strong>The</strong> rump kernel does a fork <strong>of</strong> <strong>the</strong><br />

rump process context, generates a cookie <strong>and</strong> sends that to <strong>the</strong> client as a response.<br />

Next, <strong>the</strong> client process calls <strong>the</strong> host’s fork routine. <strong>The</strong> parent returns immediately<br />

to <strong>the</strong> caller. <strong>The</strong> newly created child establishes its own connection to <strong>the</strong><br />

rump kernel server. It uses <strong>the</strong> cookie to perform a h<strong>and</strong>shake where it indicates<br />

it wants to attach to <strong>the</strong> rump kernel process <strong>the</strong> parent forked <strong>of</strong>f earlier. Only<br />

<strong>the</strong>n does <strong>the</strong> child return to <strong>the</strong> caller. Both host <strong>and</strong> rump process contexts retain<br />

expected semantics over a host process fork. <strong>The</strong> client side fork() implementation<br />

is illustrated in Figure 3.36. A hijacked fork call is a simple case <strong>of</strong> calling<br />

rumpclient_fork().<br />

Supporting execve()<br />

<strong>The</strong> requirements <strong>of</strong> exec are <strong>the</strong> “opposite” <strong>of</strong> fork.<br />

Instead <strong>of</strong> creating a new<br />

process, <strong>the</strong> same rump process context must be preserved over a host’s exec call.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!