3 * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
4 * Copyright © 2012 Canonical Ltd.
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.
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.
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.
22 #include <lxc/lxccontainer.h>
28 #include <sys/types.h>
45 #define MYNAME "lxctest1"
47 #define TSTERR(fmt, ...) do { \
48 fprintf(stderr, "%s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
52 * test_running_container: test cgroup functions against a running container
54 * @name : name of the container
56 static int test_running_container(const char *lxcpath
, const char *name
)
58 __do_close
int fd_log
= -EBADF
;
60 struct lxc_container
*c
= NULL
;
61 struct lxc_log log
= {};
62 char template[sizeof(P_tmpdir
"/attach_XXXXXX")];
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
;
68 (void)strlcpy(template, P_tmpdir
"/attach_XXXXXX", sizeof(template));
70 fd_log
= lxc_make_tmpfile(template, false);
72 lxc_error("Failed to create temporary log file for container %s\n", name
);
78 log
.prefix
= "cgpath";
81 if (lxc_log_init(&log
))
84 sprintf(relpath
, DEFAULT_PAYLOAD_CGROUP_PREFIX
"%s", name
);
86 if ((c
= lxc_container_new(name
, lxcpath
)) == NULL
) {
87 TSTERR("container %s couldn't instantiate", name
);
90 if (!c
->is_defined(c
)) {
91 TSTERR("container %s does not exist", name
);
95 cgrelpath
= lxc_cmd_get_cgroup_path(c
->name
, c
->config_path
, "freezer");
97 TSTERR("lxc_cmd_get_cgroup_path returned NULL");
100 if (!strstr(cgrelpath
, relpath
)) {
101 TSTERR("lxc_cmd_get_cgroup_path %s not in %s", relpath
, cgrelpath
);
105 cgroup_ops
= cgroup_init(c
->lxc_conf
);
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
);
113 TSTERR("cgroup_get failed");
116 (void)strlcpy(value_save
, value
, NAME_MAX
);
118 ret
= cgroup_ops
->set(cgroup_ops
, "pids.max", "10000",
119 c
->name
, c
->config_path
);
121 TSTERR("cgroup_set failed %d %d", ret
, errno
);
124 ret
= cgroup_ops
->get(cgroup_ops
, "pids.max", value
,
125 sizeof(value
), c
->name
, c
->config_path
);
127 TSTERR("cgroup_get failed");
130 if (strcmp(value
, "10000\n")) {
131 TSTERR("cgroup_set_bypath failed to set value >%s<", value
);
135 /* restore original value */
136 ret
= cgroup_ops
->set(cgroup_ops
, "pids.max",
137 value_save
, c
->name
, c
->config_path
);
139 TSTERR("cgroup_set failed");
148 lxc_container_put(c
);
154 while ((buflen
= read(fd_log
, buf
, 1024)) > 0) {
155 buflen
= write(STDERR_FILENO
, buf
, buflen
);
160 (void)unlink(template);
164 static int test_container(const char *lxcpath
, const char *name
,
165 const char *template)
168 struct lxc_container
*c
= NULL
;
171 ret
= mkdir(lxcpath
, 0755);
172 if (ret
< 0 && errno
!= EEXIST
) {
173 TSTERR("failed to mkdir %s %s", lxcpath
, strerror(errno
));
179 if ((c
= lxc_container_new(name
, lxcpath
)) == NULL
) {
180 TSTERR("instantiating container %s", name
);
183 if (c
->is_defined(c
)) {
186 lxc_container_put(c
);
187 c
= lxc_container_new(name
, lxcpath
);
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
);
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
);
201 ret
= test_running_container(lxcpath
, name
);
207 lxc_container_put(c
);
212 int main(int argc
, char *argv
[])
214 int ret
= EXIT_FAILURE
;
216 /* won't require privilege necessarily once users are classified by
218 if (geteuid() != 0) {
219 TSTERR("requires privilege");
223 #if TEST_ALREADY_RUNNING_CT
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.
231 if (test_running_container(NULL
, "bb01") < 0)
233 printf("Running container cgroup tests...Passed\n");
237 if (test_container(NULL
, MYNAME
, "busybox") < 0)
239 printf("Container creation tests...Passed\n");
241 if (test_container("/var/lib/lxctest2", MYNAME
, "busybox") < 0)
243 printf("Container creation with LXCPATH tests...Passed\n");