]>
git.proxmox.com Git - mirror_lxc.git/blob - src/tests/concurrent.c
3 * Copyright © 2013 S.Çağlar Onur <caglar@10ur.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2, as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <lxc/lxccontainer.h>
30 static int nthreads
= 5;
31 static int iterations
= 1;
35 static const char *template = "busybox";
37 static const struct option options
[] = {
38 { "threads", required_argument
, NULL
, 'j' },
39 { "iterations", required_argument
, NULL
, 'i' },
40 { "template", required_argument
, NULL
, 't' },
41 { "delay", required_argument
, NULL
, 'd' },
42 { "modes", required_argument
, NULL
, 'm' },
43 { "quiet", no_argument
, NULL
, 'q' },
44 { "debug", no_argument
, NULL
, 'D' },
45 { "help", no_argument
, NULL
, '?' },
49 static void usage(void) {
50 fprintf(stderr
, "Usage: lxc-test-concurrent [OPTION]...\n\n"
52 " -j, --threads=N Threads to run concurrently\n"
53 " (default: 5, use 1 for no threading)\n"
54 " -i, --iterations=N Number times to run the test (default: 1)\n"
55 " -t, --template=t Template to use (default: busybox)\n"
56 " -d, --delay=N Delay in seconds between start and stop\n"
57 " -m, --modes=<mode,mode,...> Modes to run (create, start, stop, destroy)\n"
58 " -q, --quiet Don't produce any output\n"
59 " -D, --debug Create a debug log\n"
60 " -?, --help Give this help list\n"
62 "Mandatory or optional arguments to long options are also mandatory or optional\n"
63 "for any corresponding short options.\n\n");
72 static void do_function(void *arguments
)
74 char name
[NAME_MAX
+ 1];
75 struct thread_args
*args
= arguments
;
76 struct lxc_container
*c
;
78 sprintf(name
, "lxc-test-concurrent-%d", args
->thread_id
);
80 args
->return_code
= 1;
82 c
= lxc_container_new(name
, NULL
);
84 fprintf(stderr
, "Unable to instantiate container (%s)\n", name
);
89 c
->set_config_item(c
, "lxc.log.level", "DEBUG");
91 if (strcmp(args
->mode
, "create") == 0) {
92 if (!c
->is_defined(c
)) {
93 if (!c
->create(c
, template, NULL
, NULL
, 1, NULL
)) {
94 fprintf(stderr
, "Creating the container (%s) failed...\n", name
);
98 } else if(strcmp(args
->mode
, "start") == 0) {
99 if (c
->is_defined(c
) && !c
->is_running(c
)) {
100 c
->want_daemonize(c
, true);
102 if (!c
->start(c
, false, NULL
)) {
103 fprintf(stderr
, "Starting the container (%s) failed...\n", name
);
107 if (!c
->wait(c
, "RUNNING", 15)) {
108 fprintf(stderr
, "Waiting the container (%s) to start failed...\n", name
);
114 } else if(strcmp(args
->mode
, "stop") == 0) {
115 if (c
->is_defined(c
) && c
->is_running(c
)) {
117 fprintf(stderr
, "Stopping the container (%s) failed...\n", name
);
121 if (!c
->wait(c
, "STOPPED", 15)) {
122 fprintf(stderr
, "Waiting the container (%s) to stop failed...\n", name
);
126 } else if(strcmp(args
->mode
, "destroy") == 0) {
127 if (c
->is_defined(c
) && !c
->is_running(c
)) {
128 if (!c
->destroy(c
)) {
129 fprintf(stderr
, "Destroying the container (%s) failed...\n", name
);
135 args
->return_code
= 0;
138 lxc_container_put(c
);
144 static void *concurrent(void *arguments
)
146 do_function(arguments
);
152 int main(int argc
, char *argv
[]) {
156 struct thread_args
*args
;
158 char *modes_default
[] = {"create", "start", "stop", "destroy", NULL
};
159 char **modes
= modes_default
;
161 pthread_attr_init(&attr
);
163 while ((opt
= getopt_long(argc
, argv
, "j:i:t:d:m:qD", options
, NULL
)) != -1) {
166 nthreads
= atoi(optarg
);
169 iterations
= atoi(optarg
);
175 delay
= atoi(optarg
);
184 char *mode_tok
, *tok
, *saveptr
= NULL
;
190 for (i
= 0, mode_tok
= optarg
;
191 (tok
= strtok_r(mode_tok
, ",", &saveptr
));
192 i
++, mode_tok
= NULL
) {
193 modes
= realloc(modes
, sizeof(*modes
) * (i
+2));
211 threads
= malloc(sizeof(*threads
) * nthreads
);
212 args
= malloc(sizeof(*args
) * nthreads
);
213 if (threads
== NULL
|| args
== NULL
) {
214 fprintf(stderr
, "Unable malloc enough memory for %d threads\n", nthreads
);
218 for (iter
= 1; iter
<= iterations
; iter
++) {
221 fd
= open("/", O_RDONLY
);
223 fprintf(stderr
, "Failed to open /\n");
228 printf("\nIteration %d/%d maxfd:%d\n", iter
, iterations
, fd
);
232 for (i
= 0; modes
[i
];i
++) {
234 printf("Executing (%s) for %d containers...\n", modes
[i
], nthreads
);
236 for (j
= 0; j
< nthreads
; j
++) {
237 args
[j
].thread_id
= j
;
238 args
[j
].mode
= modes
[i
];
241 if (pthread_create(&threads
[j
], &attr
, concurrent
, (void *) &args
[j
]) != 0) {
242 perror("pthread_create() error");
246 do_function(&args
[j
]);
250 for (j
= 0; j
< nthreads
; j
++) {
252 if (pthread_join(threads
[j
], NULL
) != 0) {
253 perror("pthread_join() error");
258 if (args
[j
].return_code
) {
259 fprintf(stderr
, "thread returned error %d\n", args
[j
].return_code
);
268 pthread_attr_destroy(&attr
);