mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-04 19:28:29 +00:00
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: Dwight Engen <dwight.engen@oracle.com> Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
parent
d3de16bb56
commit
36eaa69415
@ -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
|
|||||||
*/
|
*/
|
||||||
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 @@
|
|||||||
|
|
||||||
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[] = {
|
|||||||
{ "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) {
|
|||||||
" -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)
|
|||||||
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)
|
|||||||
} 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)
|
|||||||
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[]) {
|
|||||||
|
|
||||||
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[]) {
|
|||||||
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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user