<br><br><div class="gmail_quote">On Wed, Apr 11, 2012 at 7:52 PM, Serge Hallyn <span dir="ltr"><<a href="mailto:serge.hallyn@canonical.com">serge.hallyn@canonical.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">Quoting Arun M (<a href="mailto:arunmahadevaiyer@gmail.com">arunmahadevaiyer@gmail.com</a>):<br>
> Hello,<br>
><br>
> I am observing that if two containers are spawned via lxc-execute and if<br>
> these happen to be in  the same process group, a process inside one<br>
> container can terminate the second container by sending a SIGTERM to the<br>
> process group.<br>
><br>
><br>
> Code snippet of the test program that was running inside the container (via<br>
> lxc-execute):-<br>
> --<br>
> void handle_term(int sig)<br>
> {<br>
>   signal(SIGTERM, SIG_DFL);<br>
>   kill(0, SIGTERM);<br>
> }<br>
><br>
> int main()<br>
> {<br>
>   signal(SIGTERM, handle_term);<br>
>   sleep(3600);<br>
> }<br>
> ----<br>
><br>
> I forked two copies of this via lxc-execute and made sure that they have<br>
> the same process group ID and sent a SIGTERM to the first lxc-execute.<br>
><br>
> The second container (where SIGTERM was not sent) apparently gets a SIGTERM<br>
> from PID 2 of the first container.<br>
><br>
> ---<br>
> write(3, "    lxc-execute 1334131101.756 INFO     lxc_start - received<br>
>  signal 15 from pid 2, uid 36886\n", 94) = 94<br>
> write(3, "    lxc-execute 1334131101.756 INFO     lxc_start - forwarded<br>
> signal 15 to pid 14875\n", 85) = 85<br>
> ---<br>
><br>
> Is this expected behavior ? Shouldn't two process in independent PID<br>
> namespaces get their own copy of process group IDs ?<br>
<br>
</div></div>Interesting case.  My first guess was that it is because lxc-execute doesn't<br>
do a setsid() or setpgrp() and that clone(CLONE_NEWPID) doesn't do that for<br>
you as I assumed.  But when I try:<br>
<br>
handlesignal() {<br>
        echo hi htere<br>
}<br>
trap handlesignal USR1<br>
cat > /root/killusr1.c << EOF<br>
#include <stdio.h><br>
#include <sys/types.h><br>
#include <signal.h><br>
<br>
int main()<br>
{<br>
                kill(0, SIGUSR1);<br>
}<br>
EOF<br>
gcc -o /root/killusr1 /root/killusr1.c<br>
lxc-unshare -s PID /root/killusr1<br>
<br>
the parent shell doesn't get the signal.<br>
<br>
So I'm not sure offhand what is going on.  I'll wait and see if someone else<br>
knows offhand, otherwise will look into it more.  Cause it's interesting.<br>
<br>
thanks,<br>
-serge<br>
</blockquote></div><br><div>I guess the unshare and shell does not belong to the same process group. I am able to reproduce with the following code.</div><div><br></div><div>cat > pgrp.c <<EOF</div><div><div>#include <stdio.h></div>
<div>#include <signal.h></div><div>#include <unistd.h></div><div>#include <alloca.h></div><div>#include <sched.h></div><div>#include <sys/types.h></div><div>#include <sys/wait.h></div><div>
<br></div><div><br></div><div>void handle_usr1()</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>printf("PID = %d, got usr1\n", getpid());</div><div>}</div><div><br></div><div>
int do_child(void *a)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>printf("Child pgrp = %d\n",getpgrp());</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>sleep(10);</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>kill(0, SIGUSR1);</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>return 0;</div><div>}</div><div><br></div><div>int main()</div><div>
{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>pid_t pid;</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>int status;</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>long stack_size = sysconf(_SC_PAGESIZE);</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>void *stack = alloca(stack_size);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">   </span>signal(SIGUSR1, handle_usr1);</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">     </span>if ( (pid = clone(do_child, stack + stack_size, CLONE_NEWPID, NULL)) == -1) {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>perror("clone");</div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>return -1;</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>}</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">   </span>printf("Parent pgrp = %d\n",getpgrp());</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">     </span>waitpid(pid, &status, __WCLONE);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>return 0;</div><div>
}</div></div><div>EOF</div><div><br></div><div><div>$ gcc pgrp.c -o pgrp</div><div>$ sudo ./pgrp </div><div>Parent pgrp = 21135</div><div>Child pgrp = 0</div><div>PID = 1, got usr1</div><div>PID = 21136, got usr1</div><div>
User defined signal 1</div></div><div><br></div><div>----</div><div><br></div><div>Though the child pgrp is 0 in child, outside the namespace both the parent and child seem to be having the same pgrp id and hence the signal is delivered to the parent as well.</div>
<div><br></div><div>Thanks,</div><div>Arun</div><div><br></div>