From fbeb7a1a24cef6899b6a4f505e81d53c05d405b3 Mon Sep 17 00:00:00 2001 From: 2xsec Date: Tue, 3 Jul 2018 18:11:46 +0900 Subject: [PATCH] tests: cleanup concurrent.c Signed-off-by: 2xsec --- src/tests/concurrent.c | 413 +++++++++++++++++++++-------------------- 1 file changed, 213 insertions(+), 200 deletions(-) diff --git a/src/tests/concurrent.c b/src/tests/concurrent.c index c41e9f48fc..87d2ae9784 100644 --- a/src/tests/concurrent.c +++ b/src/tests/concurrent.c @@ -35,223 +35,236 @@ static int delay = 0; static const char *template = "busybox"; static const struct option options[] = { - { "threads", required_argument, NULL, 'j' }, - { "iterations", required_argument, NULL, 'i' }, - { "template", required_argument, NULL, 't' }, - { "delay", required_argument, NULL, 'd' }, - { "modes", required_argument, NULL, 'm' }, - { "quiet", no_argument, NULL, 'q' }, - { "debug", no_argument, NULL, 'D' }, - { "help", no_argument, NULL, '?' }, - { 0, 0, 0, 0 }, + { "threads", required_argument, NULL, 'j' }, + { "iterations", required_argument, NULL, 'i' }, + { "template", required_argument, NULL, 't' }, + { "delay", required_argument, NULL, 'd' }, + { "modes", required_argument, NULL, 'm' }, + { "quiet", no_argument, NULL, 'q' }, + { "debug", no_argument, NULL, 'D' }, + { "help", no_argument, NULL, '?' }, + { 0, 0, 0, 0 }, }; static void usage(void) { - fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n" - "Common options :\n" - " -j, --threads=N Threads to run concurrently\n" - " (default: 5, use 1 for no threading)\n" - " -i, --iterations=N Number times to run the test (default: 1)\n" - " -t, --template=t Template to use (default: busybox)\n" - " -d, --delay=N Delay in seconds between start and stop\n" - " -m, --modes= Modes to run (create, start, stop, destroy)\n" - " -q, --quiet Don't produce any output\n" - " -D, --debug Create a debug log\n" - " -?, --help Give this help list\n" - "\n" - "Mandatory or optional arguments to long options are also mandatory or optional\n" - "for any corresponding short options.\n\n"); + fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n" + "Common options :\n" + " -j, --threads=N Threads to run concurrently\n" + " (default: 5, use 1 for no threading)\n" + " -i, --iterations=N Number times to run the test (default: 1)\n" + " -t, --template=t Template to use (default: busybox)\n" + " -d, --delay=N Delay in seconds between start and stop\n" + " -m, --modes= Modes to run (create, start, stop, destroy)\n" + " -q, --quiet Don't produce any output\n" + " -D, --debug Create a debug log\n" + " -?, --help Give this help list\n" + "\n" + "Mandatory or optional arguments to long options are also mandatory or optional\n" + "for any corresponding short options.\n\n"); } struct thread_args { - int thread_id; - int return_code; - const char *mode; + int thread_id; + int return_code; + const char *mode; }; static void do_function(void *arguments) { - char name[NAME_MAX+1]; - struct thread_args *args = arguments; - struct lxc_container *c; - - sprintf(name, "lxc-test-concurrent-%d", args->thread_id); - - args->return_code = 1; - c = lxc_container_new(name, NULL); - if (!c) { - fprintf(stderr, "Unable to instantiate container (%s)\n", name); - return; - } - - if (debug) - c->set_config_item(c, "lxc.log.level", "DEBUG"); - - if (strcmp(args->mode, "create") == 0) { - if (!c->is_defined(c)) { - if (!c->create(c, template, NULL, NULL, 1, NULL)) { - 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)) { - c->want_daemonize(c, true); - if (!c->start(c, false, NULL)) { - fprintf(stderr, "Starting the container (%s) failed...\n", name); - goto out; - } - if (!c->wait(c, "RUNNING", 15)) { - fprintf(stderr, "Waiting the container (%s) to start failed...\n", name); - goto out; - } - sleep(delay); - } - } else if(strcmp(args->mode, "stop") == 0) { - if (c->is_defined(c) && c->is_running(c)) { - if (!c->stop(c)) { - fprintf(stderr, "Stopping the container (%s) failed...\n", name); - goto out; - } - if (!c->wait(c, "STOPPED", 15)) { - fprintf(stderr, "Waiting the container (%s) to stop 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)) { - fprintf(stderr, "Destroying the container (%s) failed...\n", name); - goto out; - } - } - } - args->return_code = 0; + char name[NAME_MAX + 1]; + struct thread_args *args = arguments; + struct lxc_container *c; + + sprintf(name, "lxc-test-concurrent-%d", args->thread_id); + + args->return_code = 1; + + c = lxc_container_new(name, NULL); + if (!c) { + fprintf(stderr, "Unable to instantiate container (%s)\n", name); + return; + } + + if (debug) + c->set_config_item(c, "lxc.log.level", "DEBUG"); + + if (strcmp(args->mode, "create") == 0) { + if (!c->is_defined(c)) { + if (!c->create(c, template, NULL, NULL, 1, NULL)) { + 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)) { + c->want_daemonize(c, true); + + if (!c->start(c, false, NULL)) { + fprintf(stderr, "Starting the container (%s) failed...\n", name); + goto out; + } + + if (!c->wait(c, "RUNNING", 15)) { + fprintf(stderr, "Waiting the container (%s) to start failed...\n", name); + goto out; + } + + sleep(delay); + } + } else if(strcmp(args->mode, "stop") == 0) { + if (c->is_defined(c) && c->is_running(c)) { + if (!c->stop(c)) { + fprintf(stderr, "Stopping the container (%s) failed...\n", name); + goto out; + } + + if (!c->wait(c, "STOPPED", 15)) { + fprintf(stderr, "Waiting the container (%s) to stop 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)) { + fprintf(stderr, "Destroying the container (%s) failed...\n", name); + goto out; + } + } + } + + args->return_code = 0; + out: - lxc_container_put(c); - if (debug) - lxc_log_close(); + lxc_container_put(c); + + if (debug) + lxc_log_close(); } static void *concurrent(void *arguments) { - do_function(arguments); - pthread_exit(NULL); + do_function(arguments); + pthread_exit(NULL); - return NULL; + return NULL; } int main(int argc, char *argv[]) { - int i, j, iter, opt; - pthread_attr_t attr; - pthread_t *threads; - struct thread_args *args; - - char *modes_default[] = {"create", "start", "stop", "destroy", NULL}; - char **modes = modes_default; - - pthread_attr_init(&attr); - - while ((opt = getopt_long(argc, argv, "j:i:t:d:m:qD", options, NULL)) != -1) { - switch(opt) { - case 'j': - nthreads = atoi(optarg); - break; - case 'i': - iterations = atoi(optarg); - break; - case 't': - template = optarg; - break; - case 'd': - delay = atoi(optarg); - break; - case 'q': - quiet = 1; - break; - case 'D': - debug = 1; - break; - case 'm': { - char *mode_tok, *tok, *saveptr = NULL; - - if (!optarg) - continue; - - modes = NULL; - for (i = 0, mode_tok = optarg; - (tok = strtok_r(mode_tok, ",", &saveptr)); - i++, mode_tok = NULL) { - modes = realloc(modes, sizeof(*modes) * (i+2)); - if (!modes) { - perror("realloc"); - exit(EXIT_FAILURE); - } - modes[i] = tok; - } - if (modes) - modes[i] = NULL; - break; - } - default: /* '?' */ - usage(); - exit(EXIT_FAILURE); - } - } - - threads = malloc(sizeof(*threads) * nthreads); - args = malloc(sizeof(*args) * nthreads); - if (threads == NULL || args == NULL) { - fprintf(stderr, "Unable malloc enough memory for %d threads\n", nthreads); - exit(EXIT_FAILURE); - } - - for (iter = 1; iter <= iterations; iter++) { - int fd; - fd = open("/", O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Failed to open /\n"); - continue; - } - - if (!quiet) - printf("\nIteration %d/%d maxfd:%d\n", iter, iterations, fd); - close(fd); - - for (i = 0; modes[i];i++) { - if (!quiet) - printf("Executing (%s) for %d containers...\n", modes[i], nthreads); - for (j = 0; j < nthreads; j++) { - args[j].thread_id = j; - args[j].mode = modes[i]; - - if (nthreads > 1) { - if (pthread_create(&threads[j], &attr, concurrent, (void *) &args[j]) != 0) { - perror("pthread_create() error"); - exit(EXIT_FAILURE); - } - } else { - do_function(&args[j]); - } - } - - for (j = 0; j < nthreads; j++) { - if (nthreads > 1) { - if (pthread_join(threads[j], NULL) != 0) { - perror("pthread_join() error"); - 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); + int i, j, iter, opt; + pthread_attr_t attr; + pthread_t *threads; + struct thread_args *args; + + char *modes_default[] = {"create", "start", "stop", "destroy", NULL}; + char **modes = modes_default; + + pthread_attr_init(&attr); + + while ((opt = getopt_long(argc, argv, "j:i:t:d:m:qD", options, NULL)) != -1) { + switch(opt) { + case 'j': + nthreads = atoi(optarg); + break; + case 'i': + iterations = atoi(optarg); + break; + case 't': + template = optarg; + break; + case 'd': + delay = atoi(optarg); + break; + case 'q': + quiet = 1; + break; + case 'D': + debug = 1; + break; + case 'm': { + char *mode_tok, *tok, *saveptr = NULL; + + if (!optarg) + continue; + + modes = NULL; + for (i = 0, mode_tok = optarg; + (tok = strtok_r(mode_tok, ",", &saveptr)); + i++, mode_tok = NULL) { + modes = realloc(modes, sizeof(*modes) * (i+2)); + if (!modes) { + perror("realloc"); + exit(EXIT_FAILURE); + } + modes[i] = tok; + } + + if (modes) + modes[i] = NULL; + break; + } + default: /* '?' */ + usage(); + exit(EXIT_FAILURE); + } + } + + threads = malloc(sizeof(*threads) * nthreads); + args = malloc(sizeof(*args) * nthreads); + if (threads == NULL || args == NULL) { + fprintf(stderr, "Unable malloc enough memory for %d threads\n", nthreads); + exit(EXIT_FAILURE); + } + + for (iter = 1; iter <= iterations; iter++) { + int fd; + + fd = open("/", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Failed to open /\n"); + continue; + } + + if (!quiet) + printf("\nIteration %d/%d maxfd:%d\n", iter, iterations, fd); + + close(fd); + + for (i = 0; modes[i];i++) { + if (!quiet) + printf("Executing (%s) for %d containers...\n", modes[i], nthreads); + + for (j = 0; j < nthreads; j++) { + args[j].thread_id = j; + args[j].mode = modes[i]; + + if (nthreads > 1) { + if (pthread_create(&threads[j], &attr, concurrent, (void *) &args[j]) != 0) { + perror("pthread_create() error"); + exit(EXIT_FAILURE); + } + } else { + do_function(&args[j]); + } + } + + for (j = 0; j < nthreads; j++) { + if (nthreads > 1) { + if (pthread_join(threads[j], NULL) != 0) { + perror("pthread_join() error"); + 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); }