Commit 36ea44bb by Dwight Engen Committed by Stéphane Graber

fix fd leak in test-concurrent

Opening a debug log for every thread at every iteration of test-concurrent causes it to quickly run out of fd's because this fd is leaked. Fix this by adding a new api: lxc_log_close(). As Caglar noted, the log handling is in general a bit "interesting" because a logfile can be opened through the per-container api c->set_config_item("lxc.logfile") but lxc_log_fd is now per-thread data. It just so happens in test-concurrent that there is a 1:1 mapping of threads to logfiles. Split out getting debug logs from quiet since I think they are useful separately. If debug is specified, get a log of any mode, not just during start. Signed-off-by: 's avatarDwight Engen <dwight.engen@oracle.com> Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com>
parent c9bd1357
...@@ -368,6 +368,16 @@ extern int lxc_log_init(const char *name, const char *file, ...@@ -368,6 +368,16 @@ extern int lxc_log_init(const char *name, const char *file,
return ret; return ret;
} }
extern void lxc_log_close(void)
{
if (lxc_log_fd == -1)
return;
close(lxc_log_fd);
lxc_log_fd = -1;
free(log_fname);
log_fname = NULL;
}
/* /*
* This is called when we read a lxc.loglevel entry in a lxc.conf file. This * This is called when we read a lxc.loglevel entry in a lxc.conf file. This
* happens after processing command line arguments, which override the .conf * happens after processing command line arguments, which override the .conf
......
...@@ -865,6 +865,11 @@ int list_active_containers(const char *lxcpath, char ***names, struct lxc_contai ...@@ -865,6 +865,11 @@ int list_active_containers(const char *lxcpath, char ***names, struct lxc_contai
*/ */
int list_all_containers(const char *lxcpath, char ***names, struct lxc_container ***cret); int list_all_containers(const char *lxcpath, char ***names, struct lxc_container ***cret);
/*!
* \brief Close log file.
*/
void lxc_log_close(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
static int nthreads = 5; static int nthreads = 5;
static int iterations = 1; static int iterations = 1;
static int debug = 0;
static int quiet = 0; static int quiet = 0;
static int delay = 0; static int delay = 0;
static const char *template = "busybox"; static const char *template = "busybox";
...@@ -40,6 +41,7 @@ static const struct option options[] = { ...@@ -40,6 +41,7 @@ static const struct option options[] = {
{ "delay", required_argument, NULL, 'd' }, { "delay", required_argument, NULL, 'd' },
{ "modes", required_argument, NULL, 'm' }, { "modes", required_argument, NULL, 'm' },
{ "quiet", no_argument, NULL, 'q' }, { "quiet", no_argument, NULL, 'q' },
{ "debug", no_argument, NULL, 'D' },
{ "help", no_argument, NULL, '?' }, { "help", no_argument, NULL, '?' },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
}; };
...@@ -54,6 +56,7 @@ static void usage(void) { ...@@ -54,6 +56,7 @@ static void usage(void) {
" -d, --delay=N Delay in seconds between start and stop\n" " -d, --delay=N Delay in seconds between start and stop\n"
" -m, --modes=<mode,mode,...> Modes to run (create, start, stop, destroy)\n" " -m, --modes=<mode,mode,...> Modes to run (create, start, stop, destroy)\n"
" -q, --quiet Don't produce any output\n" " -q, --quiet Don't produce any output\n"
" -D, --debug Create a debug log\n"
" -?, --help Give this help list\n" " -?, --help Give this help list\n"
"\n" "\n"
"Mandatory or optional arguments to long options are also mandatory or optional\n" "Mandatory or optional arguments to long options are also mandatory or optional\n"
...@@ -81,6 +84,11 @@ static void do_function(void *arguments) ...@@ -81,6 +84,11 @@ static void do_function(void *arguments)
return; return;
} }
if (debug) {
c->set_config_item(c, "lxc.loglevel", "DEBUG");
c->set_config_item(c, "lxc.logfile", name);
}
if (strcmp(args->mode, "create") == 0) { if (strcmp(args->mode, "create") == 0) {
if (!c->is_defined(c)) { if (!c->is_defined(c)) {
if (!c->create(c, template, NULL, NULL, 1, NULL)) { if (!c->create(c, template, NULL, NULL, 1, NULL)) {
...@@ -91,10 +99,6 @@ static void do_function(void *arguments) ...@@ -91,10 +99,6 @@ static void do_function(void *arguments)
} else if(strcmp(args->mode, "start") == 0) { } else if(strcmp(args->mode, "start") == 0) {
if (c->is_defined(c) && !c->is_running(c)) { if (c->is_defined(c) && !c->is_running(c)) {
c->want_daemonize(c, true); c->want_daemonize(c, true);
if (!quiet) {
c->set_config_item(c, "lxc.loglevel", "DEBUG");
c->set_config_item(c, "lxc.logfile", name);
}
if (!c->start(c, false, NULL)) { if (!c->start(c, false, NULL)) {
fprintf(stderr, "Starting the container (%s) failed...\n", name); fprintf(stderr, "Starting the container (%s) failed...\n", name);
goto out; goto out;
...@@ -127,6 +131,8 @@ static void do_function(void *arguments) ...@@ -127,6 +131,8 @@ static void do_function(void *arguments)
args->return_code = 0; args->return_code = 0;
out: out:
lxc_container_put(c); lxc_container_put(c);
if (debug)
lxc_log_close();
} }
static void *concurrent(void *arguments) static void *concurrent(void *arguments)
...@@ -148,7 +154,7 @@ int main(int argc, char *argv[]) { ...@@ -148,7 +154,7 @@ int main(int argc, char *argv[]) {
pthread_attr_init(&attr); pthread_attr_init(&attr);
while ((opt = getopt_long(argc, argv, "j:i:t:d:m:q", options, NULL)) != -1) { while ((opt = getopt_long(argc, argv, "j:i:t:d:m:qD", options, NULL)) != -1) {
switch(opt) { switch(opt) {
case 'j': case 'j':
nthreads = atoi(optarg); nthreads = atoi(optarg);
...@@ -165,6 +171,9 @@ int main(int argc, char *argv[]) { ...@@ -165,6 +171,9 @@ int main(int argc, char *argv[]) {
case 'q': case 'q':
quiet = 1; quiet = 1;
break; break;
case 'D':
debug = 1;
break;
case 'm': { case 'm': {
char *mode_tok, *tok, *saveptr = NULL; char *mode_tok, *tok, *saveptr = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment