Unverified Commit eedf8b38 by 2xsec Committed by Christian Brauner

tests: cleanup concurrent.c

Signed-off-by: 's avatar2xsec <dh48.jeong@samsung.com>
parent bdad17c8
...@@ -35,223 +35,236 @@ static int delay = 0; ...@@ -35,223 +35,236 @@ static int delay = 0;
static const char *template = "busybox"; static const char *template = "busybox";
static const struct option options[] = { static const struct option options[] = {
{ "threads", required_argument, NULL, 'j' }, { "threads", required_argument, NULL, 'j' },
{ "iterations", required_argument, NULL, 'i' }, { "iterations", required_argument, NULL, 'i' },
{ "template", required_argument, NULL, 't' }, { "template", required_argument, NULL, 't' },
{ "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' }, { "debug", no_argument, NULL, 'D' },
{ "help", no_argument, NULL, '?' }, { "help", no_argument, NULL, '?' },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
}; };
static void usage(void) { static void usage(void) {
fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n" fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n"
"Common options :\n" "Common options :\n"
" -j, --threads=N Threads to run concurrently\n" " -j, --threads=N Threads to run concurrently\n"
" (default: 5, use 1 for no threading)\n" " (default: 5, use 1 for no threading)\n"
" -i, --iterations=N Number times to run the test (default: 1)\n" " -i, --iterations=N Number times to run the test (default: 1)\n"
" -t, --template=t Template to use (default: busybox)\n" " -t, --template=t Template to use (default: busybox)\n"
" -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" " -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"
"for any corresponding short options.\n\n"); "for any corresponding short options.\n\n");
} }
struct thread_args { struct thread_args {
int thread_id; int thread_id;
int return_code; int return_code;
const char *mode; const char *mode;
}; };
static void do_function(void *arguments) static void do_function(void *arguments)
{ {
char name[NAME_MAX+1]; char name[NAME_MAX + 1];
struct thread_args *args = arguments; struct thread_args *args = arguments;
struct lxc_container *c; struct lxc_container *c;
sprintf(name, "lxc-test-concurrent-%d", args->thread_id); sprintf(name, "lxc-test-concurrent-%d", args->thread_id);
args->return_code = 1; args->return_code = 1;
c = lxc_container_new(name, NULL);
if (!c) { c = lxc_container_new(name, NULL);
fprintf(stderr, "Unable to instantiate container (%s)\n", name); if (!c) {
return; fprintf(stderr, "Unable to instantiate container (%s)\n", name);
} return;
}
if (debug)
c->set_config_item(c, "lxc.log.level", "DEBUG"); if (debug)
c->set_config_item(c, "lxc.log.level", "DEBUG");
if (strcmp(args->mode, "create") == 0) {
if (!c->is_defined(c)) { if (strcmp(args->mode, "create") == 0) {
if (!c->create(c, template, NULL, NULL, 1, NULL)) { if (!c->is_defined(c)) {
fprintf(stderr, "Creating the container (%s) failed...\n", name); if (!c->create(c, template, NULL, NULL, 1, NULL)) {
goto out; fprintf(stderr, "Creating the container (%s) failed...\n", name);
} goto out;
} }
} else if(strcmp(args->mode, "start") == 0) { }
if (c->is_defined(c) && !c->is_running(c)) { } else if(strcmp(args->mode, "start") == 0) {
c->want_daemonize(c, true); if (c->is_defined(c) && !c->is_running(c)) {
if (!c->start(c, false, NULL)) { c->want_daemonize(c, true);
fprintf(stderr, "Starting the container (%s) failed...\n", name);
goto out; if (!c->start(c, false, NULL)) {
} fprintf(stderr, "Starting the container (%s) failed...\n", name);
if (!c->wait(c, "RUNNING", 15)) { goto out;
fprintf(stderr, "Waiting the container (%s) to start failed...\n", name); }
goto out;
} if (!c->wait(c, "RUNNING", 15)) {
sleep(delay); fprintf(stderr, "Waiting the container (%s) to start failed...\n", name);
} goto out;
} else if(strcmp(args->mode, "stop") == 0) { }
if (c->is_defined(c) && c->is_running(c)) {
if (!c->stop(c)) { sleep(delay);
fprintf(stderr, "Stopping the container (%s) failed...\n", name); }
goto out; } else if(strcmp(args->mode, "stop") == 0) {
} if (c->is_defined(c) && c->is_running(c)) {
if (!c->wait(c, "STOPPED", 15)) { if (!c->stop(c)) {
fprintf(stderr, "Waiting the container (%s) to stop failed...\n", name); fprintf(stderr, "Stopping the container (%s) failed...\n", name);
goto out; goto out;
} }
}
} else if(strcmp(args->mode, "destroy") == 0) { if (!c->wait(c, "STOPPED", 15)) {
if (c->is_defined(c) && !c->is_running(c)) { fprintf(stderr, "Waiting the container (%s) to stop failed...\n", name);
if (!c->destroy(c)) { goto out;
fprintf(stderr, "Destroying the container (%s) failed...\n", name); }
goto out; }
} } else if(strcmp(args->mode, "destroy") == 0) {
} if (c->is_defined(c) && !c->is_running(c)) {
} if (!c->destroy(c)) {
args->return_code = 0; fprintf(stderr, "Destroying the container (%s) failed...\n", name);
goto out;
}
}
}
args->return_code = 0;
out: out:
lxc_container_put(c); lxc_container_put(c);
if (debug)
lxc_log_close(); if (debug)
lxc_log_close();
} }
static void *concurrent(void *arguments) static void *concurrent(void *arguments)
{ {
do_function(arguments); do_function(arguments);
pthread_exit(NULL); pthread_exit(NULL);
return NULL; return NULL;
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int i, j, iter, opt; int i, j, iter, opt;
pthread_attr_t attr; pthread_attr_t attr;
pthread_t *threads; pthread_t *threads;
struct thread_args *args; struct thread_args *args;
char *modes_default[] = {"create", "start", "stop", "destroy", NULL}; char *modes_default[] = {"create", "start", "stop", "destroy", NULL};
char **modes = modes_default; char **modes = modes_default;
pthread_attr_init(&attr); pthread_attr_init(&attr);
while ((opt = getopt_long(argc, argv, "j:i:t:d:m:qD", 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);
break; break;
case 'i': case 'i':
iterations = atoi(optarg); iterations = atoi(optarg);
break; break;
case 't': case 't':
template = optarg; template = optarg;
break; break;
case 'd': case 'd':
delay = atoi(optarg); delay = atoi(optarg);
break; break;
case 'q': case 'q':
quiet = 1; quiet = 1;
break; break;
case 'D': case 'D':
debug = 1; debug = 1;
break; break;
case 'm': { case 'm': {
char *mode_tok, *tok, *saveptr = NULL; char *mode_tok, *tok, *saveptr = NULL;
if (!optarg) if (!optarg)
continue; continue;
modes = NULL; modes = NULL;
for (i = 0, mode_tok = optarg; for (i = 0, mode_tok = optarg;
(tok = strtok_r(mode_tok, ",", &saveptr)); (tok = strtok_r(mode_tok, ",", &saveptr));
i++, mode_tok = NULL) { i++, mode_tok = NULL) {
modes = realloc(modes, sizeof(*modes) * (i+2)); modes = realloc(modes, sizeof(*modes) * (i+2));
if (!modes) { if (!modes) {
perror("realloc"); perror("realloc");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
modes[i] = tok; modes[i] = tok;
} }
if (modes)
modes[i] = NULL; if (modes)
break; modes[i] = NULL;
} break;
default: /* '?' */ }
usage(); default: /* '?' */
exit(EXIT_FAILURE); usage();
} exit(EXIT_FAILURE);
} }
}
threads = malloc(sizeof(*threads) * nthreads);
args = malloc(sizeof(*args) * nthreads); threads = malloc(sizeof(*threads) * nthreads);
if (threads == NULL || args == NULL) { args = malloc(sizeof(*args) * nthreads);
fprintf(stderr, "Unable malloc enough memory for %d threads\n", nthreads); if (threads == NULL || args == NULL) {
exit(EXIT_FAILURE); fprintf(stderr, "Unable malloc enough memory for %d threads\n", nthreads);
} exit(EXIT_FAILURE);
}
for (iter = 1; iter <= iterations; iter++) {
int fd; for (iter = 1; iter <= iterations; iter++) {
fd = open("/", O_RDONLY); int fd;
if (fd < 0) {
fprintf(stderr, "Failed to open /\n"); fd = open("/", O_RDONLY);
continue; if (fd < 0) {
} fprintf(stderr, "Failed to open /\n");
continue;
if (!quiet) }
printf("\nIteration %d/%d maxfd:%d\n", iter, iterations, fd);
close(fd); if (!quiet)
printf("\nIteration %d/%d maxfd:%d\n", iter, iterations, fd);
for (i = 0; modes[i];i++) {
if (!quiet) close(fd);
printf("Executing (%s) for %d containers...\n", modes[i], nthreads);
for (j = 0; j < nthreads; j++) { for (i = 0; modes[i];i++) {
args[j].thread_id = j; if (!quiet)
args[j].mode = modes[i]; printf("Executing (%s) for %d containers...\n", modes[i], nthreads);
if (nthreads > 1) { for (j = 0; j < nthreads; j++) {
if (pthread_create(&threads[j], &attr, concurrent, (void *) &args[j]) != 0) { args[j].thread_id = j;
perror("pthread_create() error"); args[j].mode = modes[i];
exit(EXIT_FAILURE);
} if (nthreads > 1) {
} else { if (pthread_create(&threads[j], &attr, concurrent, (void *) &args[j]) != 0) {
do_function(&args[j]); perror("pthread_create() error");
} exit(EXIT_FAILURE);
} }
} else {
for (j = 0; j < nthreads; j++) { do_function(&args[j]);
if (nthreads > 1) { }
if (pthread_join(threads[j], NULL) != 0) { }
perror("pthread_join() error");
exit(EXIT_FAILURE); for (j = 0; j < nthreads; j++) {
} if (nthreads > 1) {
} if (pthread_join(threads[j], NULL) != 0) {
if (args[j].return_code) { perror("pthread_join() error");
fprintf(stderr, "thread returned error %d\n", args[j].return_code); exit(EXIT_FAILURE);
exit(EXIT_FAILURE); }
} }
}
} if (args[j].return_code) {
} fprintf(stderr, "thread returned error %d\n", args[j].return_code);
exit(EXIT_FAILURE);
free(args); }
free(threads); }
pthread_attr_destroy(&attr); }
exit(EXIT_SUCCESS); }
free(args);
free(threads);
pthread_attr_destroy(&attr);
exit(EXIT_SUCCESS);
} }
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