]>
Commit | Line | Data |
---|---|---|
0115f8fd DE |
1 | /* liblxcapi |
2 | * | |
3 | * Copyright © 2013 Oracle. | |
4 | * | |
5 | * Authors: | |
6 | * Dwight Engen <dwight.engen@oracle.com> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2, as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License along | |
18 | * with this program; if not, write to the Free Software Foundation, Inc., | |
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
20 | */ | |
21 | ||
e49c56d6 CB |
22 | #include "config.h" |
23 | ||
948955a2 | 24 | #include <lxc/lxccontainer.h> |
0115f8fd DE |
25 | |
26 | #include <errno.h> | |
27 | #include <unistd.h> | |
4012c891 | 28 | #include <stdio.h> |
95ee490b SG |
29 | #include <string.h> |
30 | #include <sys/stat.h> | |
0115f8fd DE |
31 | |
32 | #define TTYCNT 4 | |
33 | #define TTYCNT_STR "4" | |
34 | #define TSTNAME "lxcconsoletest" | |
35 | #define MAXCONSOLES 512 | |
36 | ||
37 | #define TSTERR(fmt, ...) do { \ | |
38 | fprintf(stderr, "%s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ | |
39 | } while (0) | |
40 | ||
41 | static void test_console_close_all(int ttyfd[MAXCONSOLES], | |
36a94ce8 | 42 | int ptxfd[MAXCONSOLES]) |
0115f8fd DE |
43 | { |
44 | int i; | |
45 | ||
46 | for (i = 0; i < MAXCONSOLES; i++) { | |
36a94ce8 CB |
47 | if (ptxfd[i] != -1) { |
48 | close(ptxfd[i]); | |
49 | ptxfd[i] = -1; | |
0115f8fd | 50 | } |
9ace5308 | 51 | |
0115f8fd DE |
52 | if (ttyfd[i] != -1) { |
53 | close(ttyfd[i]); | |
54 | ttyfd[i] = -1; | |
55 | } | |
56 | } | |
57 | } | |
58 | ||
59 | static int test_console_running_container(struct lxc_container *c) | |
60 | { | |
61 | int nrconsoles, i, ret = -1; | |
62 | int ttynum [MAXCONSOLES]; | |
63 | int ttyfd [MAXCONSOLES]; | |
36a94ce8 | 64 | int ptxfd[MAXCONSOLES]; |
0115f8fd DE |
65 | |
66 | for (i = 0; i < MAXCONSOLES; i++) | |
36a94ce8 | 67 | ttynum[i] = ttyfd[i] = ptxfd[i] = -1; |
0115f8fd DE |
68 | |
69 | ttynum[0] = 1; | |
9ace5308 | 70 | |
36a94ce8 | 71 | ret = c->console_getfd(c, &ttynum[0], &ptxfd[0]); |
0115f8fd DE |
72 | if (ret < 0) { |
73 | TSTERR("console allocate failed"); | |
74 | goto err1; | |
75 | } | |
9ace5308 | 76 | |
0115f8fd DE |
77 | ttyfd[0] = ret; |
78 | if (ttynum[0] != 1) { | |
79 | TSTERR("console allocate got bad ttynum %d", ttynum[0]); | |
80 | goto err2; | |
81 | } | |
82 | ||
83 | /* attempt to alloc same ttynum */ | |
36a94ce8 | 84 | ret = c->console_getfd(c, &ttynum[0], &ptxfd[1]); |
0115f8fd DE |
85 | if (ret != -1) { |
86 | TSTERR("console allocate should fail for allocated ttynum %d", ttynum[0]); | |
87 | goto err2; | |
88 | } | |
36a94ce8 | 89 | close(ptxfd[0]); ptxfd[0] = -1; |
0115f8fd DE |
90 | close(ttyfd[0]); ttyfd[0] = -1; |
91 | ||
92 | /* ensure we can allocate all consoles, we do this a few times to | |
93 | * show that the closes are freeing up the allocated slots | |
94 | */ | |
95 | for (i = 0; i < 10; i++) { | |
96 | for (nrconsoles = 0; nrconsoles < MAXCONSOLES; nrconsoles++) { | |
36a94ce8 | 97 | ret = c->console_getfd(c, &ttynum[nrconsoles], &ptxfd[nrconsoles]); |
0115f8fd DE |
98 | if (ret < 0) |
99 | break; | |
100 | ttyfd[nrconsoles] = ret; | |
101 | } | |
9ace5308 | 102 | |
0115f8fd DE |
103 | if (nrconsoles != TTYCNT) { |
104 | TSTERR("didn't allocate all consoles %d != %d", nrconsoles, TTYCNT); | |
105 | goto err2; | |
106 | } | |
9ace5308 | 107 | |
36a94ce8 | 108 | test_console_close_all(ttyfd, ptxfd); |
0115f8fd | 109 | } |
9ace5308 | 110 | |
0115f8fd DE |
111 | ret = 0; |
112 | ||
113 | err2: | |
36a94ce8 | 114 | test_console_close_all(ttyfd, ptxfd); |
9ace5308 | 115 | |
0115f8fd DE |
116 | err1: |
117 | return ret; | |
118 | } | |
119 | ||
120 | /* test_container: test console function | |
121 | * | |
122 | * @lxcpath : the lxcpath in which to create the container | |
123 | * @group : name of the container group or NULL for default "lxc" | |
124 | * @name : name of the container | |
125 | * @template : template to use when creating the container | |
126 | */ | |
127 | static int test_console(const char *lxcpath, | |
128 | const char *group, const char *name, | |
129 | const char *template) | |
130 | { | |
131 | int ret; | |
132 | struct lxc_container *c = NULL; | |
133 | ||
134 | if (lxcpath) { | |
135 | ret = mkdir(lxcpath, 0755); | |
136 | if (ret < 0 && errno != EEXIST) { | |
137 | TSTERR("failed to mkdir %s %s", lxcpath, strerror(errno)); | |
138 | goto out1; | |
139 | } | |
140 | } | |
141 | ret = -1; | |
142 | ||
143 | if ((c = lxc_container_new(name, lxcpath)) == NULL) { | |
144 | TSTERR("instantiating container %s", name); | |
145 | goto out1; | |
146 | } | |
9ace5308 | 147 | |
0115f8fd DE |
148 | if (c->is_defined(c)) { |
149 | c->stop(c); | |
150 | c->destroy(c); | |
151 | c = lxc_container_new(name, lxcpath); | |
152 | } | |
9ace5308 | 153 | |
dc23c1c8 | 154 | if (!c->createl(c, template, NULL, NULL, 0, NULL)) { |
0115f8fd DE |
155 | TSTERR("creating container %s", name); |
156 | goto out2; | |
157 | } | |
9ace5308 | 158 | |
0115f8fd | 159 | c->load_config(c, NULL); |
fe1c5887 | 160 | c->set_config_item(c, "lxc.tty.max", TTYCNT_STR); |
9d28c4f9 | 161 | c->set_config_item(c, "lxc.pty.max", "1024"); |
0115f8fd | 162 | c->save_config(c, NULL); |
540f932a | 163 | c->want_daemonize(c, true); |
9ace5308 | 164 | |
0115f8fd DE |
165 | if (!c->startl(c, 0, NULL)) { |
166 | TSTERR("starting container %s", name); | |
167 | goto out3; | |
168 | } | |
169 | ||
170 | ret = test_console_running_container(c); | |
171 | ||
172 | c->stop(c); | |
9ace5308 | 173 | |
0115f8fd DE |
174 | out3: |
175 | c->destroy(c); | |
9ace5308 | 176 | |
0115f8fd DE |
177 | out2: |
178 | lxc_container_put(c); | |
9ace5308 | 179 | |
0115f8fd DE |
180 | out1: |
181 | return ret; | |
182 | } | |
183 | ||
184 | int main(int argc, char *argv[]) | |
185 | { | |
186 | int ret; | |
9ace5308 | 187 | |
0115f8fd DE |
188 | ret = test_console(NULL, NULL, TSTNAME, "busybox"); |
189 | if (ret < 0) | |
190 | goto err1; | |
191 | ||
192 | ret = test_console("/var/lib/lxctest2", NULL, TSTNAME, "busybox"); | |
193 | if (ret < 0) | |
194 | goto err1; | |
9ace5308 | 195 | |
0115f8fd | 196 | printf("All tests passed\n"); |
9ace5308 | 197 | |
0115f8fd DE |
198 | err1: |
199 | return ret; | |
200 | } |