<div dir="ltr">Hi all,<div><br></div><div>I am trying to use lxc_container->start() from within a process that happens to have started a TCP server, and even when my program exits, the server socket stays alive.  This can be tested by running this program (which starts a server and then starts a container) twice--the second time resulting in a bind() error:</div>
<div><br></div><div><div><font face="courier new, monospace">#include <sys/socket.h></font></div><div><font face="courier new, monospace">#include <netinet/in.h></font></div><div><font face="courier new, monospace">#include <stdio.h></font></div>
<div><font face="courier new, monospace">#include <errno.h></font></div><div><font face="courier new, monospace">#include <strings.h></font></div><div><font face="courier new, monospace">#include <stdlib.h></font></div>
<div><font face="courier new, monospace">#include <lxc/lxccontainer.h></font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">int main(int argc, char**argv)</font></div>
<div><font face="courier new, monospace">{</font></div><div><font face="courier new, monospace">  struct lxc_container *c;</font></div><div><font face="courier new, monospace">  int listenfd,connfd,n;</font></div><div><font face="courier new, monospace">  struct sockaddr_in servaddr;</font></div>
<div><font face="courier new, monospace">  int port;</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  // Start server</font></div><div><font face="courier new, monospace">  port = atoi(argv[2]);</font></div>
<div><font face="courier new, monospace">  printf("Listening on port %d ...\n", port);</font></div><div><font face="courier new, monospace">  listenfd=socket(AF_INET,SOCK_STREAM,0);</font></div><div><font face="courier new, monospace">  bzero(&servaddr,sizeof(servaddr));</font></div>
<div><font face="courier new, monospace">  servaddr.sin_family = AF_INET;</font></div><div><font face="courier new, monospace">  servaddr.sin_addr.s_addr=htonl(INADDR_ANY);</font></div><div><font face="courier new, monospace">  servaddr.sin_port=htons(port);</font></div>
<div><font face="courier new, monospace">  if (bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)))</font></div><div><font face="courier new, monospace">  {</font></div><div><font face="courier new, monospace">    perror("Error calling bind()");</font></div>
<div><font face="courier new, monospace">    exit(1);</font></div><div><font face="courier new, monospace">  }</font></div><div><font face="courier new, monospace">  listen(listenfd,1024);</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">  // Start</font></div><div><span style="font-family:'courier new',monospace">  printf("Starting container ...\n");</span><br></div><div><font face="courier new, monospace">  c = lxc_container_new(argv[1], NULL);</font></div>
<div><span style="font-family:'courier new',monospace">  c->want_daemonize(c, true);</span><br></div><div><font face="courier new, monospace">  c->want_close_all_fds(c, true);</font></div><div><font face="courier new, monospace">  c->start(c, 0, NULL);</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  return 0;</font></div><div><font face="courier new, monospace">}</font></div></div><div><br></div><div><b><font face="courier new, monospace">> gcc test.c -llxc -o test</font><br>
</b></div><div><font face="courier new, monospace"><b>> lxc-create -n blarghle -t ubuntu</b></font></div><div><b><span style="font-family:'courier new',monospace">> ./test blarghle 9050</span><br></b></div><div>
<div style="font-family:'courier new',monospace">Listening on port 9050 ...<br></div><div style="font-family:'courier new',monospace">Starting container ...</div><div style="font-family:'courier new',monospace">
<b>> ./test blarghle 9050</b></div><div style="font-family:'courier new',monospace">Listening on port 9050 ...</div><div style="font-family:'courier new',monospace">Error calling bind(): Address already in use</div>
<div style="font-family:'courier new',monospace"><br></div><div><font face="arial, helvetica, sans-serif">As you can see, even though ./test finished the first time, the second ./test cannot bind to the port because it is still in use.</font></div>
</div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">This appears to be because the lxc init process has a ghost "./test" as its parent:</font></div>
<div><font face="arial, helvetica, sans-serif"><br></font></div><div><b><font face="courier new, monospace">> ps -ef | grep 30276</font></b></div><div><font face="courier new, monospace">root     30276     1  0 18:37 ?        00:00:00 ./test blarghle 9050<br>
</font></div><div><font face="courier new, monospace">root     30285 30276  0 18:37 ?        00:00:00 /sbin/init<br></font></div><div><div><b><font face="courier new, monospace">> lsof | grep 9050</font></b></div><div>
<font face="courier new, monospace">test      30276              root    3u     IPv4             366649      0t0        TCP *:9050 (LISTEN)</font></div><div><br></div></div><div><font face="arial, helvetica, sans-serif">I am stymied on how to investigate further.  My best guess is it has to do with the <a href="https://github.com/lxc/lxc/blob/master/src/lxc/lxccontainer.c#L608-L621">double forking in lxccontainer.h</a>, though I don't really understand what that is for yet :)  Any thoughts?</font></div>
<div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Thanks!</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">--John</font></div>
<div><font face="arial, helvetica, sans-serif"><br></font></div></div>