tags:

views:

242

answers:

3

I'd like to use the namespacing features of the clone function. Reading the manpage, it seems like clone has lots of intricate details I need to worry about.

Is there an equivalent clone invocation to good ol' fork()?

I'm already familiar with fork, and believe that if I have a starting point in clone, I can add flags and options from there.

A: 

clone() is used to create a thread. The big difference between clone() and fork() is that clone() is meant to execute starting at a separate entry point - a function, whereas fork() just continues on down from the same point in the code from where was invoked. int (*fn)(void *) in the manpage definition is the function, which on exit returns an int, the exit status.

The closest call to clone is pthread_create() which is essentially a wrapper for clone(). This does not get you a way to get fork() behavior.

jim mcnamara
Good point. I'm not too concerned about the `fn` vs. `return` difference between `clone` and `fork`. My aim is understanding how to get the same subprocess characteristics (and what they are). In any case, `pthread_create` doesn't offer me the namespacing flags.
Shtééf
+1  A: 

I think that this will work, but I'm not entirely certain about some of the pointer arguments.

pid_t child = clone( child_f, child_stack, 
           /* int flags                */     SIGCHLD, 
           /* argument to child_f      */     NULL,
           /* pid_t *pid               */     NULL,
           /* struct usr_desc * tls    */     NULL,
           /* pid_t *ctid              */     NULL );

In the flags parameter the lower byte of it is used to specify which signal to send to notify the parent of the thread doing things like dying or stopping. I believe that all of the actual flags turn on switches which are different from fork. Looking at the kernel code suggests this is the case.

If you really want to get something close to fork you may want to call sys_clone which does not take function pointer and instead returns twice like fork.

nategoose
I went code-diving because I still didn't feel comfortable, but it looks like you're right. What I found is that `clone` is a very thin wrapper around `sys_clone`, mostly just doing what's necessary to call `fn` on the new stack. `sys_clone` actually returns like `fork`, but cannot be called directly, because it's signature differs per architecture. `fork` is actually rather fat: it executes callbacks, does misc cleanup, but basically uses only SIGCHLD. (I suppose there's nothing I can do to emulate the `fork`-extras.)
Shtééf
+1  A: 

You could fork a normal child process using fork(), then use unshare() to create a new namespace.

Namespaces are a bit weird, I can't see a lot of use-cases for them.

MarkR
It looks like `unshare` only supports a small subset of the `clone` flags. For example, I want to use `CLONE_NEWNET`, and it returns `EINVAL`.
Shtééf