Unikernels as highly isolated processes and an idea to implement limited fork/execve in OSv

27 views
Skip to first unread message

Waldek Kozaczuk

unread,
Nov 25, 2019, 5:44:29 PM11/25/19
to OSv Development
Sometimes it might be more useful to think of unikernels as highly isolated processes instead of microVMs with a specialised guest OS. See Nabla processes - https://acmsocc.github.io/2018/slides/socc18-slides-williams.pdf.

So given that I wonder if it would make sense/be feasible/applicable to implement limited fork/execve in OSv. It could work like this:
  1. fork() starts new thread T2 - acts as "stub/proxy" to a new remote microVM that would be lazily started when execve() is actually called
  2. tid of the new thread T2 would be returned to the caller in the thread T1; it would act as PID of the new process
  3. New thread T2 would start with same code as calling thread T1 but somehow (???) get 0 as the return value and continue from there (just like on normal Posix OS)
  4. T2 typically would call execve() right away
    • execve() would somehow communicate with host (how?) to start new child VM with passed in command line, argv
    • execve() would never return and instead wait unit the child VM terminates
    • T2 would also somehow listen for some other calls like kill() and pass it to the host that would shutdown child VM
There is obviously a plethora of various IPC mechanisms to communicate between processes (shared filesystem, shared memory, named semaphores, named semaphores, etc) so how much OSv would need to implement them to make such fork/execve useful, I do not know. I am also not sure if that would be applicable in any real-world scenarios. Maybe master-worker types of workloads (kind of what nginx model is).'

Do not be too harsh if you think this is really stupid idea ;-)

Waldek

Pekka Enberg

unread,
Nov 26, 2019, 7:05:47 AM11/26/19
to Waldek Kozaczuk, OSv Development
Hi Waldek,

You can certainly implement fork()/exec() for an unikernel, and it has been done before. See, for example, the following paper on Graphene:

  Tsai et al. Cooperation and Security Isolation of Library OSes for Multi-Process Applications. EuroSys 2014. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.589.1837&rep=rep1&type=pdf

However, please keep in mind that fork() is used for different kinds of things, which are not going to be easy to support efficiently using this kind of model. The way Redis uses fork() for snapshotting comes to mind, for example.

There is a way to support multi-process environment, though, and that's by implementing the posix_spawn() system call. I recommend reading the following paper for a case against fork() and why posix_spawn() makes more sense in the general case:

  Baumann et al. A fork() in the road. HotOS 2019. https://www.microsoft.com/en-us/research/uploads/prod/2019/04/fork-hotos19.pdf

- Pekka

Nadav Har'El

unread,
Nov 26, 2019, 10:06:29 AM11/26/19
to Waldek Kozaczuk, OSv Development
On Tue, Nov 26, 2019 at 12:44 AM Waldek Kozaczuk <jwkoz...@gmail.com> wrote:
Sometimes it might be more useful to think of unikernels as highly isolated processes instead of microVMs with a specialised guest OS. See Nabla processes - https://acmsocc.github.io/2018/slides/socc18-slides-williams.pdf.

So given that I wonder if it would make sense/be feasible/applicable to implement limited fork/execve in OSv. It could work like this:
  1. fork() starts new thread T2 - acts as "stub/proxy" to a new remote microVM that would be lazily started when execve() is actually called
  1. tid of the new thread T2 would be returned to the caller in the thread T1; it would act as PID of the new process
  2. New thread T2 would start with same code as calling thread T1 but somehow (???) get 0 as the return value and continue from there (just like on normal Posix OS)
  3. T2 typically would call execve() right away
    • execve() would somehow communicate with host (how?) to start new child VM with passed in command line, argv
    • execve() would never return and instead wait unit the child VM terminates
    • T2 would also somehow listen for some other calls like kill() and pass it to the host that would shutdown child VM
Something like this is doable (and I vaguely remember someone from the Mikelangelo project once thought about doing this), but I wonder which kind of applications this would be useful for. I would start with finding such an application before spending too much effort on this.
 
There is obviously a plethora of various IPC mechanisms to communicate between processes (shared filesystem, shared memory, named semaphores, named semaphores, etc) so how much OSv would need to implement them to make such fork/execve useful, I do not know. I am also not sure if that would be applicable in any real-world scenarios. Maybe master-worker types of workloads (kind of what nginx model is).'

Do not be too harsh if you think this is really stupid idea ;-)

Waldek

--
You received this message because you are subscribed to the Google Groups "OSv Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/8f1e8b08-1028-4075-8298-fe72823da3cf%40googlegroups.com.

zhiting zhu

unread,
Nov 26, 2019, 11:34:09 AM11/26/19
to Nadav Har'El, OSv Development, Waldek Kozaczuk
For example, there’re lots of program that uses subprocess in python or exec.cmd in golang. Those programs have to be ported to rewrite with the api bindings. 

Reply all
Reply to author
Forward
0 new messages