<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>