]>
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 | ||
948955a2 | 22 | #include <lxc/lxccontainer.h> |
0115f8fd DE |
23 | |
24 | #include <errno.h> | |
25 | #include <unistd.h> | |
4012c891 | 26 | #include <stdio.h> |
95ee490b SG |
27 | #include <string.h> |
28 | #include <sys/stat.h> | |
0115f8fd DE |
29 | |
30 | #define TTYCNT 4 | |
31 | #define TTYCNT_STR "4" | |
32 | #define TSTNAME "lxcconsoletest" | |
33 | #define MAXCONSOLES 512 | |
34 | ||
35 | #define TSTERR(fmt, ...) do { \ | |
36 | fprintf(stderr, "%s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ | |
37 | } while (0) | |
38 | ||
39 | static void test_console_close_all(int ttyfd[MAXCONSOLES], | |
36a94ce8 | 40 | int ptxfd[MAXCONSOLES]) |
0115f8fd DE |
41 | { |
42 | int i; | |
43 | ||
44 | for (i = 0; i < MAXCONSOLES; i++) { | |
36a94ce8 CB |
45 | if (ptxfd[i] != -1) { |
46 | close(ptxfd[i]); | |
47 | ptxfd[i] = -1; | |
0115f8fd | 48 | } |
9ace5308 | 49 | |
0115f8fd DE |
50 | if (ttyfd[i] != -1) { |
51 | close(ttyfd[i]); | |
52 | ttyfd[i] = -1; | |
53 | } | |
54 | } | |
55 | } | |
56 | ||
57 | static int test_console_running_container(struct lxc_container *c) | |
58 | { | |
59 | int nrconsoles, i, ret = -1; | |
60 | int ttynum [MAXCONSOLES]; | |
61 | int ttyfd [MAXCONSOLES]; | |
36a94ce8 | 62 | int ptxfd[MAXCONSOLES]; |
0115f8fd DE |
63 | |
64 | for (i = 0; i < MAXCONSOLES; i++) | |
36a94ce8 | 65 | ttynum[i] = ttyfd[i] = ptxfd[i] = -1; |
0115f8fd DE |
66 | |
67 | ttynum[0] = 1; | |
9ace5308 | 68 | |
36a94ce8 | 69 | ret = c->console_getfd(c, &ttynum[0], &ptxfd[0]); |
0115f8fd DE |
70 | if (ret < 0) { |
71 | TSTERR("console allocate failed"); | |
72 | goto err1; | |
73 | } | |
9ace5308 | 74 | |
0115f8fd DE |
75 | ttyfd[0] = ret; |
76 | if (ttynum[0] != 1) { | |
77 | TSTERR("console allocate got bad ttynum %d", ttynum[0]); | |
78 | goto err2; | |
79 | } | |
80 | ||
81 | /* attempt to alloc same ttynum */ | |
36a94ce8 | 82 | ret = c->console_getfd(c, &ttynum[0], &ptxfd[1]); |
0115f8fd DE |
83 | if (ret != -1) { |
84 | TSTERR("console allocate should fail for allocated ttynum %d", ttynum[0]); | |
85 | goto err2; | |
86 | } | |
36a94ce8 | 87 | close(ptxfd[0]); ptxfd[0] = -1; |
0115f8fd DE |
88 | close(ttyfd[0]); ttyfd[0] = -1; |
89 | ||
90 | /* ensure we can allocate all consoles, we do this a few times to | |
91 | * show that the closes are freeing up the allocated slots | |
92 | */ | |
93 | for (i = 0; i < 10; i++) { | |
94 | for (nrconsoles = 0; nrconsoles < MAXCONSOLES; nrconsoles++) { | |
36a94ce8 | 95 | ret = c->console_getfd(c, &ttynum[nrconsoles], &ptxfd[nrconsoles]); |
0115f8fd DE |
96 | if (ret < 0) |
97 | break; | |
98 | ttyfd[nrconsoles] = ret; | |
99 | } | |
9ace5308 | 100 | |
0115f8fd DE |
101 | if (nrconsoles != TTYCNT) { |
102 | TSTERR("didn't allocate all consoles %d != %d", nrconsoles, TTYCNT); | |
103 | goto err2; | |
104 | } | |
9ace5308 | 105 | |
36a94ce8 | 106 | test_console_close_all(ttyfd, ptxfd); |
0115f8fd | 107 | } |
9ace5308 | 108 | |
0115f8fd DE |
109 | ret = 0; |
110 | ||
111 | err2: | |
36a94ce8 | 112 | test_console_close_all(ttyfd, ptxfd); |
9ace5308 | 113 | |
0115f8fd DE |
114 | err1: |
115 | return ret; | |
116 | } | |
117 | ||
118 | /* test_container: test console function | |
119 | * | |
120 | * @lxcpath : the lxcpath in which to create the container | |
121 | * @group : name of the container group or NULL for default "lxc" | |
122 | * @name : name of the container | |
123 | * @template : template to use when creating the container | |
124 | */ | |
125 | static int test_console(const char *lxcpath, | |
126 | const char *group, const char *name, | |
127 | const char *template) | |
128 | { | |
129 | int ret; | |
130 | struct lxc_container *c = NULL; | |
131 | ||
132 | if (lxcpath) { | |
133 | ret = mkdir(lxcpath, 0755); | |
134 | if (ret < 0 && errno != EEXIST) { | |
135 | TSTERR("failed to mkdir %s %s", lxcpath, strerror(errno)); | |
136 | goto out1; | |
137 | } | |
138 | } | |
139 | ret = -1; | |
140 | ||
141 | if ((c = lxc_container_new(name, lxcpath)) == NULL) { | |
142 | TSTERR("instantiating container %s", name); | |
143 | goto out1; | |
144 | } | |
9ace5308 | 145 | |
0115f8fd DE |
146 | if (c->is_defined(c)) { |
147 | c->stop(c); | |
148 | c->destroy(c); | |
149 | c = lxc_container_new(name, lxcpath); | |
150 | } | |
9ace5308 | 151 | |
dc23c1c8 | 152 | if (!c->createl(c, template, NULL, NULL, 0, NULL)) { |
0115f8fd DE |
153 | TSTERR("creating container %s", name); |
154 | goto out2; | |
155 | } | |
9ace5308 | 156 | |
0115f8fd | 157 | c->load_config(c, NULL); |
fe1c5887 | 158 | c->set_config_item(c, "lxc.tty.max", TTYCNT_STR); |
9d28c4f9 | 159 | c->set_config_item(c, "lxc.pty.max", "1024"); |
0115f8fd | 160 | c->save_config(c, NULL); |
540f932a | 161 | c->want_daemonize(c, true); |
9ace5308 | 162 | |
0115f8fd DE |
163 | if (!c->startl(c, 0, NULL)) { |
164 | TSTERR("starting container %s", name); | |
165 | goto out3; | |
166 | } | |
167 | ||
168 | ret = test_console_running_container(c); | |
169 | ||
170 | c->stop(c); | |
9ace5308 | 171 | |
0115f8fd DE |
172 | out3: |
173 | c->destroy(c); | |
9ace5308 | 174 | |
0115f8fd DE |
175 | out2: |
176 | lxc_container_put(c); | |
9ace5308 | 177 | |
0115f8fd DE |
178 | out1: |
179 | return ret; | |
180 | } | |
181 | ||
182 | int main(int argc, char *argv[]) | |
183 | { | |
184 | int ret; | |
9ace5308 | 185 | |
0115f8fd DE |
186 | ret = test_console(NULL, NULL, TSTNAME, "busybox"); |
187 | if (ret < 0) | |
188 | goto err1; | |
189 | ||
190 | ret = test_console("/var/lib/lxctest2", NULL, TSTNAME, "busybox"); | |
191 | if (ret < 0) | |
192 | goto err1; | |
9ace5308 | 193 | |
0115f8fd | 194 | printf("All tests passed\n"); |
9ace5308 | 195 | |
0115f8fd DE |
196 | err1: |
197 | return ret; | |
198 | } |