Re: For review: pid_namespaces(7) man page

Eric W. Biederman
2013-03-01T15:35:52Z

"Michael Kerrisk (man-pages)" <mtk.manpages@gmail.com> writes:

> Hi Rob,
>
> On Fri, Mar 1, 2013 at 5:01 AM, Rob Landley <rob@landley.net> wrote:
>> On 02/28/2013 05:24:07 AM, Michael Kerrisk (man-pages) wrote:
> [...]
>
>>> DESCRIPTION
>>> For an overview of namespaces, see namespaces(7).
>>>
>>> PID namespaces isolate the process ID number space, meaning
>>> that processes in different PID namespaces can have the same
>>> PID.
>>
>>
>> Um, perhaps "different processes"? Slightly repetitive, but trying to avoid
>> the potential misreading that "a processes can have the same PID in
>> different namespaces". (A single process can't be a member of more than one
>> namespace. This is not about selective visibility.)
>
> I'm not sure this clarifies things...
>
>>> PID namespaces allow containers to migrate to a new host
>>> while the processes inside the container maintain the same
>>> PIDs.
>>
>>
>> I thought suspend/resume a container was the simple case. Migration to a new
>> host is built on top of that. (On resume in a new container on the same
>> system, if other stuff is going on in the system so the available PIDs have
>> shifted.)
>
> I'll add some words here on suspend/resume.
>
>>> Likewise, a process in an ancestor namespace can—subject to the
>>> usual permission checks described in kill(2)—send signals to
>>> the "init" process of a child PID namespace only if the "init"
>>> process has established a handler for that signal. (Within the
>>> handler, the siginfo_t si_pid field described in sigaction(2)
>>> will be zero.) SIGKILL or SIGSTOP are treated exceptionally:
>>> these signals are forcibly delivered when sent from an ancestor
>>> PID namespace. Neither of these signals can be caught by the
>>> "init" process, and so will result in the usual actions associ‐
>>> ated with those signals (respectively, terminating and stopping
>>> the process).
>>
>>
>> If SIGKILL to init is propogated to all the children of init, is SIGSTOP
>> also propogated to all the children? (I.E. will SIGSTOP to container's init
>> suspend the whole container, and will SIGCONT resume the whole container? If
>> the latter, will it only resume processes that weren't previously stopped?
>> :)
>
> Covered by Eric.
>
>>> To put things another way: a process's PID namespace membership
>>> is determined when the process is created and cannot be changed
>>> thereafter. Among other things, this means that the parental
>>> relationship between processes mirrors the parental between PID
>>
>>
>> mirrors the relationship
>
> Thanks.
>
>>> namespaces: the parent of a process is either in the same
>>> namespace or resides in the immediate parent PID namespace.
>>>
>>> Every thread in a process must be in the same PID namespace.
>>> For this reason, the two following call sequences will fail:
>>>
>>> unshare(CLONE_NEWPID);
>>> clone(..., CLONE_VM, ...); /* Fails */
>>>
>>> setns(fd, CLONE_NEWPID);
>>> clone(..., CLONE_VM, ...); /* Fails */
>>
>>
>> They fail with -EUNDOCUMENTED
>
> Added EINVAL, as per Eric's reply. (Eric does that error also apply
> for the two new cases you added?).
>
>>> Because the above unshare(2) and setns(2) calls only change the
>>> PID namespace for created children, the clone(2) calls neces‐
>>> sarily put the new thread in a different PID namespace from the
>>> calling thread.
>>
>>
>> Um, no they don't. They fail. That's the point.
>
> (Good catch.)
>
>> They _would_ put the new
>> thread in a different PID namespace, which breaks the definition of threads.
>>
>> How about:
>>
>> The above unshare(2) and setns(2) calls change the PID namespace of
>> children created by subsequent clone(2) calls, which is incompatible
>> with CLONE_VM.
>
> I decided on:
>
> The point here is that unshare(2) and setns(2) change the PID
> namespace for created children but not for the calling process,
> while clone(2) CLONE_VM specifies the creation of a new thread
> in the same process.

Can we make that "for all new tasks created" instead of "created
children"

Othewise someone might expect CLONE_THREAD would work as you
CLONE_THREAD creates a thread and not a child...

Eric