]> git.proxmox.com Git - mirror_lxc.git/blob - src/tests/cgpath.c
meson: Remove non-existent tests
[mirror_lxc.git] / src / tests / cgpath.c
1 /* liblxcapi
2 *
3 * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
4 * Copyright © 2012 Canonical Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "config.h"
21
22 #include <lxc/lxccontainer.h>
23
24 #include <limits.h>
25 #include <unistd.h>
26 #include <signal.h>
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <sys/stat.h>
34
35 #include "cgroup.h"
36 #include "commands.h"
37 #include "lxc.h"
38 #include "lxctest.h"
39 #include "utils.h"
40
41 #if !HAVE_STRLCPY
42 #include "strlcpy.h"
43 #endif
44
45 #define MYNAME "lxctest1"
46
47 #define TSTERR(fmt, ...) do { \
48 fprintf(stderr, "%s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
49 } while (0)
50
51 /*
52 * test_running_container: test cgroup functions against a running container
53 *
54 * @name : name of the container
55 */
56 static int test_running_container(const char *lxcpath, const char *name)
57 {
58 __do_close int fd_log = -EBADF;
59 int ret = -1;
60 struct lxc_container *c = NULL;
61 struct lxc_log log = {};
62 char template[sizeof(P_tmpdir"/attach_XXXXXX")];
63 char *cgrelpath;
64 char relpath[PATH_MAX+1];
65 char value[NAME_MAX], value_save[NAME_MAX];
66 call_cleaner(cgroup_exit) struct cgroup_ops *cgroup_ops = NULL;
67
68 (void)strlcpy(template, P_tmpdir"/attach_XXXXXX", sizeof(template));
69
70 fd_log = lxc_make_tmpfile(template, false);
71 if (fd_log < 0) {
72 lxc_error("Failed to create temporary log file for container %s\n", name);
73 exit(EXIT_FAILURE);
74 }
75 log.name = name;
76 log.file = template;
77 log.level = "TRACE";
78 log.prefix = "cgpath";
79 log.quiet = false;
80 log.lxcpath = NULL;
81 if (lxc_log_init(&log))
82 goto err1;
83
84 sprintf(relpath, DEFAULT_PAYLOAD_CGROUP_PREFIX "%s", name);
85
86 if ((c = lxc_container_new(name, lxcpath)) == NULL) {
87 TSTERR("container %s couldn't instantiate", name);
88 goto err1;
89 }
90 if (!c->is_defined(c)) {
91 TSTERR("container %s does not exist", name);
92 goto err2;
93 }
94
95 cgrelpath = lxc_cmd_get_cgroup_path(c->name, c->config_path, "freezer");
96 if (!cgrelpath) {
97 TSTERR("lxc_cmd_get_cgroup_path returned NULL");
98 goto err2;
99 }
100 if (!strstr(cgrelpath, relpath)) {
101 TSTERR("lxc_cmd_get_cgroup_path %s not in %s", relpath, cgrelpath);
102 goto err3;
103 }
104
105 cgroup_ops = cgroup_init(c->lxc_conf);
106 if (!cgroup_ops)
107 goto err3;
108
109 /* test get/set value using memory.soft_limit_in_bytes file */
110 ret = cgroup_ops->get(cgroup_ops, "pids.max", value, sizeof(value),
111 c->name, c->config_path);
112 if (ret < 0) {
113 TSTERR("cgroup_get failed");
114 goto err3;
115 }
116 (void)strlcpy(value_save, value, NAME_MAX);
117
118 ret = cgroup_ops->set(cgroup_ops, "pids.max", "10000",
119 c->name, c->config_path);
120 if (ret < 0) {
121 TSTERR("cgroup_set failed %d %d", ret, errno);
122 goto err3;
123 }
124 ret = cgroup_ops->get(cgroup_ops, "pids.max", value,
125 sizeof(value), c->name, c->config_path);
126 if (ret < 0) {
127 TSTERR("cgroup_get failed");
128 goto err3;
129 }
130 if (strcmp(value, "10000\n")) {
131 TSTERR("cgroup_set_bypath failed to set value >%s<", value);
132 goto err3;
133 }
134
135 /* restore original value */
136 ret = cgroup_ops->set(cgroup_ops, "pids.max",
137 value_save, c->name, c->config_path);
138 if (ret < 0) {
139 TSTERR("cgroup_set failed");
140 goto err3;
141 }
142
143 ret = 0;
144
145 err3:
146 free(cgrelpath);
147 err2:
148 lxc_container_put(c);
149 err1:
150
151 if (ret != 0) {
152 char buf[4096];
153 ssize_t buflen;
154 while ((buflen = read(fd_log, buf, 1024)) > 0) {
155 buflen = write(STDERR_FILENO, buf, buflen);
156 if (buflen <= 0)
157 break;
158 }
159 }
160 (void)unlink(template);
161 return ret;
162 }
163
164 static int test_container(const char *lxcpath, const char *name,
165 const char *template)
166 {
167 int ret;
168 struct lxc_container *c = NULL;
169
170 if (lxcpath) {
171 ret = mkdir(lxcpath, 0755);
172 if (ret < 0 && errno != EEXIST) {
173 TSTERR("failed to mkdir %s %s", lxcpath, strerror(errno));
174 goto out1;
175 }
176 }
177 ret = -1;
178
179 if ((c = lxc_container_new(name, lxcpath)) == NULL) {
180 TSTERR("instantiating container %s", name);
181 goto out1;
182 }
183 if (c->is_defined(c)) {
184 c->stop(c);
185 c->destroy(c);
186 lxc_container_put(c);
187 c = lxc_container_new(name, lxcpath);
188 }
189 c->set_config_item(c, "lxc.net.0.type", "empty");
190 if (!c->createl(c, template, NULL, NULL, 0, NULL)) {
191 TSTERR("creating container %s", name);
192 goto out2;
193 }
194 c->load_config(c, NULL);
195 c->want_daemonize(c, true);
196 if (!c->startl(c, 0, NULL)) {
197 TSTERR("starting container %s", name);
198 goto out3;
199 }
200
201 ret = test_running_container(lxcpath, name);
202
203 c->stop(c);
204 out3:
205 c->destroy(c);
206 out2:
207 lxc_container_put(c);
208 out1:
209 return ret;
210 }
211
212 int main(int argc, char *argv[])
213 {
214 int ret = EXIT_FAILURE;
215
216 /* won't require privilege necessarily once users are classified by
217 * pam_cgroup */
218 if (geteuid() != 0) {
219 TSTERR("requires privilege");
220 exit(EXIT_SUCCESS);
221 }
222
223 #if TEST_ALREADY_RUNNING_CT
224
225 /*
226 * This is useful for running with valgrind to test for memory
227 * leaks. The container should already be running, we can't start
228 * the container ourselves because valgrind gets confused by lxc's
229 * internal calls to clone.
230 */
231 if (test_running_container(NULL, "bb01") < 0)
232 goto out;
233 printf("Running container cgroup tests...Passed\n");
234
235 #else
236
237 if (test_container(NULL, MYNAME, "busybox") < 0)
238 goto out;
239 printf("Container creation tests...Passed\n");
240
241 if (test_container("/var/lib/lxctest2", MYNAME, "busybox") < 0)
242 goto out;
243 printf("Container creation with LXCPATH tests...Passed\n");
244
245 #endif
246
247 ret = EXIT_SUCCESS;
248 out:
249 return ret;
250 }