cgpath.c revision 4fb3cba5bc6b256b774e780f2bbf47b1dbcc0ce9
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* liblxcapi
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen *
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen * Copyright © 2012 Canonical Ltd.
ff5a3c57228ee8c6a97f0ddd2585498330415660Timo Sirainen *
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen * This program is free software; you can redistribute it and/or modify
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen * it under the terms of the GNU General Public License version 2, as
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger * published by the Free Software Foundation.
9805f5093a0e0845f028fb8fd52b0eec27d8f7abTimo Sirainen *
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen * This program is distributed in the hope that it will be useful,
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen * but WITHOUT ANY WARRANTY; without even the implied warranty of
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen * GNU General Public License for more details.
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen *
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen * You should have received a copy of the GNU General Public License along
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen * with this program; if not, write to the Free Software Foundation, Inc.,
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen#include <lxc/lxccontainer.h>
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen#include <limits.h>
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen#include <unistd.h>
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen#include <signal.h>
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen#include <stdio.h>
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen#include <sys/types.h>
b26b9ec937b0d067bff9d408101798e4f93cb919Timo Sirainen#include <sys/wait.h>
b26b9ec937b0d067bff9d408101798e4f93cb919Timo Sirainen#include <stdlib.h>
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen#include <errno.h>
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen#include <string.h>
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen#include <sys/stat.h>
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek#include "lxc/cgroup.h"
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek#include "lxc/lxc.h"
88ade75211d86266619d50aab44ccbdb7a151cbeTimo Sirainen#include "lxc/commands.h"
5e4d905f3b8e58839fe8aa44fc5ae1280031a114Timo Sirainen
5e4d905f3b8e58839fe8aa44fc5ae1280031a114Timo Sirainen#define MYNAME "lxctest1"
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
5e4d905f3b8e58839fe8aa44fc5ae1280031a114Timo Sirainen#define TSTERR(fmt, ...) do { \
5e4d905f3b8e58839fe8aa44fc5ae1280031a114Timo Sirainen fprintf(stderr, "%s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
ff5a3c57228ee8c6a97f0ddd2585498330415660Timo Sirainen} while (0)
5f1d689131a75c39f064cbd4202373e7edf78f18Josef 'Jeff' Sipek
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen/*
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen * test_running_container: test cgroup functions against a running container
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainen *
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen * @group : name of the container group or NULL for default "lxc"
6b96cd73c9b106f3fc78df263c0ec3e1ab6488b8Timo Sirainen * @name : name of the container
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen */
6b96cd73c9b106f3fc78df263c0ec3e1ab6488b8Timo Sirainenstatic int test_running_container(const char *lxcpath,
e60a349c641bb2f4723e4a395a25f55531682d2bTimo Sirainen const char *group, const char *name)
6b96cd73c9b106f3fc78df263c0ec3e1ab6488b8Timo Sirainen{
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen int ret = -1;
b26b9ec937b0d067bff9d408101798e4f93cb919Timo Sirainen struct lxc_container *c = NULL;
2d340205d897e23fbecb40c8e63a4ca49bd6739bTimo Sirainen char *cgrelpath;
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen char relpath[PATH_MAX+1];
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen char value[NAME_MAX], value_save[NAME_MAX];
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen sprintf(relpath, "%s/%s", group ? group : "lxc", name);
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen if ((c = lxc_container_new(name, lxcpath)) == NULL) {
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen TSTERR("container %s couldn't instantiate", name);
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen goto err1;
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen }
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen if (!c->is_defined(c)) {
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen TSTERR("container %s does not exist", name);
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen goto err2;
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen }
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen cgrelpath = lxc_cmd_get_cgroup_path(c->name, c->config_path, "freezer");
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen if (!cgrelpath) {
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen TSTERR("lxc_cmd_get_cgroup_path returned NULL");
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen goto err2;
6d3ebefb87dfddc6a9edabcec841b72c1cd7ae64Timo Sirainen }
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen if (!strstr(cgrelpath, relpath)) {
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen TSTERR("lxc_cmd_get_cgroup_path %s not in %s", relpath, cgrelpath);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen goto err3;
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen }
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen
9e7de2ced0b9ece9d7ae454d06e4f96cbe27668bTimo Sirainen /* test get/set value using memory.soft_limit_in_bytes file */
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen ret = lxc_cgroup_get("memory.soft_limit_in_bytes", value, sizeof(value),
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen c->name, c->config_path);
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen if (ret < 0) {
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen TSTERR("lxc_cgroup_get failed");
53c1549e64b1f655b4f84e307ef8b558f9cc8d74Timo Sirainen goto err3;
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen }
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen strcpy(value_save, value);
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen
b26b9ec937b0d067bff9d408101798e4f93cb919Timo Sirainen ret = lxc_cgroup_set("memory.soft_limit_in_bytes", "512M", c->name, c->config_path);
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen if (ret < 0) {
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen TSTERR("lxc_cgroup_set failed %d %d", ret, errno);
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen goto err3;
5e4d905f3b8e58839fe8aa44fc5ae1280031a114Timo Sirainen }
5e4d905f3b8e58839fe8aa44fc5ae1280031a114Timo Sirainen ret = lxc_cgroup_get("memory.soft_limit_in_bytes", value, sizeof(value),
5e4d905f3b8e58839fe8aa44fc5ae1280031a114Timo Sirainen c->name, c->config_path);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (ret < 0) {
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen TSTERR("lxc_cgroup_get failed");
5e4d905f3b8e58839fe8aa44fc5ae1280031a114Timo Sirainen goto err3;
5e4d905f3b8e58839fe8aa44fc5ae1280031a114Timo Sirainen }
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen if (strcmp(value, "536870912\n")) {
9691078006cfe7af5847116b519a0201c197a947Timo Sirainen TSTERR("lxc_cgroup_set_bypath failed to set value >%s<", value);
9691078006cfe7af5847116b519a0201c197a947Timo Sirainen goto err3;
9691078006cfe7af5847116b519a0201c197a947Timo Sirainen }
9691078006cfe7af5847116b519a0201c197a947Timo Sirainen
9691078006cfe7af5847116b519a0201c197a947Timo Sirainen /* restore original value */
9691078006cfe7af5847116b519a0201c197a947Timo Sirainen ret = lxc_cgroup_set("memory.soft_limit_in_bytes", value_save,
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen c->name, c->config_path);
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen if (ret < 0) {
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen TSTERR("lxc_cgroup_set failed");
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen goto err3;
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen }
76c6c1127ce9b7c079c8bdb8f2598b91432598d7Timo Sirainen
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen ret = 0;
d1bcee48225783610f0f6f639973677dd72b884aTimo Sirainen
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainenerr3:
41ba03fb730c1ede4c1d8267d4ea8a368fe6ed60Timo Sirainen free(cgrelpath);
5a7acd67806132cbc1ec9578df60d712d307e4beTimo Sirainenerr2:
41ba03fb730c1ede4c1d8267d4ea8a368fe6ed60Timo Sirainen lxc_container_put(c);
41ba03fb730c1ede4c1d8267d4ea8a368fe6ed60Timo Sirainenerr1:
41ba03fb730c1ede4c1d8267d4ea8a368fe6ed60Timo Sirainen return ret;
41ba03fb730c1ede4c1d8267d4ea8a368fe6ed60Timo Sirainen}
5fcc2aa187730d1de013d68faf01af11a1004630Timo Sirainen
5fcc2aa187730d1de013d68faf01af11a1004630Timo Sirainenstatic int test_container(const char *lxcpath,
5fcc2aa187730d1de013d68faf01af11a1004630Timo Sirainen const char *group, const char *name,
5fcc2aa187730d1de013d68faf01af11a1004630Timo Sirainen const char *template)
5fcc2aa187730d1de013d68faf01af11a1004630Timo Sirainen{
5fcc2aa187730d1de013d68faf01af11a1004630Timo Sirainen int ret;
5fcc2aa187730d1de013d68faf01af11a1004630Timo Sirainen struct lxc_container *c = NULL;
5fcc2aa187730d1de013d68faf01af11a1004630Timo Sirainen
5fcc2aa187730d1de013d68faf01af11a1004630Timo Sirainen if (lxcpath) {
43b4b4c1e9e468bfcb8b2434e26718279cbbc0d5Timo Sirainen ret = mkdir(lxcpath, 0755);
43b4b4c1e9e468bfcb8b2434e26718279cbbc0d5Timo Sirainen if (ret < 0 && errno != EEXIST) {
43b4b4c1e9e468bfcb8b2434e26718279cbbc0d5Timo Sirainen TSTERR("failed to mkdir %s %s", lxcpath, strerror(errno));
43b4b4c1e9e468bfcb8b2434e26718279cbbc0d5Timo Sirainen goto out1;
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen }
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen }
41ba03fb730c1ede4c1d8267d4ea8a368fe6ed60Timo Sirainen ret = -1;
41ba03fb730c1ede4c1d8267d4ea8a368fe6ed60Timo Sirainen
c7801f830c7d2e7d340065cdd5a5c795b1726223Timo Sirainen if ((c = lxc_container_new(name, lxcpath)) == NULL) {
14ee885f15104cdc0937773ea7bfbf84a2326fdbTimo Sirainen TSTERR("instantiating container %s", name);
14ee885f15104cdc0937773ea7bfbf84a2326fdbTimo Sirainen goto out1;
14ee885f15104cdc0937773ea7bfbf84a2326fdbTimo Sirainen }
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek if (c->is_defined(c)) {
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek c->stop(c);
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek c->destroy(c);
01c7913d4b30695b4a808e47d0402eacfd4873fcTimo Sirainen c = lxc_container_new(name, lxcpath);
14ee885f15104cdc0937773ea7bfbf84a2326fdbTimo Sirainen }
14ee885f15104cdc0937773ea7bfbf84a2326fdbTimo Sirainen c->set_config_item(c, "lxc.network.type", "empty");
c7801f830c7d2e7d340065cdd5a5c795b1726223Timo Sirainen if (!c->createl(c, template, NULL, NULL, 0, NULL)) {
14ee885f15104cdc0937773ea7bfbf84a2326fdbTimo Sirainen TSTERR("creating container %s", name);
14ee885f15104cdc0937773ea7bfbf84a2326fdbTimo Sirainen goto out2;
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainen }
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen c->load_config(c, NULL);
ee1dfe238d74e970f8b890f453ca118d51b1cc81Timo Sirainen c->want_daemonize(c, true);
ee1dfe238d74e970f8b890f453ca118d51b1cc81Timo Sirainen if (!c->startl(c, 0, NULL)) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen TSTERR("starting container %s", name);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen goto out3;
d7e9a0d0c025669388f1b04fa2980bbb2e6d2b7dTimo Sirainen }
d7e9a0d0c025669388f1b04fa2980bbb2e6d2b7dTimo Sirainen
c7801f830c7d2e7d340065cdd5a5c795b1726223Timo Sirainen ret = test_running_container(lxcpath, group, name);
ee1dfe238d74e970f8b890f453ca118d51b1cc81Timo Sirainen
ee1dfe238d74e970f8b890f453ca118d51b1cc81Timo Sirainen c->stop(c);
d7e9a0d0c025669388f1b04fa2980bbb2e6d2b7dTimo Sirainenout3:
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen c->destroy(c);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenout2:
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen lxc_container_put(c);
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainenout1:
2ded32b165ce2f510f063c7da04809891c0e8cc2Stephan Bosch return ret;
2ded32b165ce2f510f063c7da04809891c0e8cc2Stephan Bosch}
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainenint main()
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen{
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen int ret = EXIT_FAILURE;
2ded32b165ce2f510f063c7da04809891c0e8cc2Stephan Bosch
2ded32b165ce2f510f063c7da04809891c0e8cc2Stephan Bosch /* won't require privilege necessarily once users are classified by
9805f5093a0e0845f028fb8fd52b0eec27d8f7abTimo Sirainen * pam_cgroup */
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen if (geteuid() != 0) {
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek TSTERR("requires privilege");
9805f5093a0e0845f028fb8fd52b0eec27d8f7abTimo Sirainen exit(0);
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen }
2e705e574eb916181ce91f920d4d6f66bebce5baTimo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen #if TEST_ALREADY_RUNNING_CT
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen /*
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * This is useful for running with valgrind to test for memory
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * leaks. The container should already be running, we can't start
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * the container ourselves because valgrind gets confused by lxc's
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen * internal calls to clone.
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen */
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen if (test_running_container(NULL, NULL, "bb01") < 0)
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen goto out;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen printf("Running container cgroup tests...Passed\n");
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen #else
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen if (test_container(NULL, NULL, MYNAME, "busybox") < 0)
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen goto out;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen printf("Container creation tests...Passed\n");
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen if (test_container("/var/lib/lxctest2", NULL, MYNAME, "busybox") < 0)
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen goto out;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen printf("Container creation with LXCPATH tests...Passed\n");
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen #endif
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen ret = EXIT_SUCCESS;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainenout:
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen return ret;
5ef28f68edef46f69961b19b7c1dcd8ec5a955e8Timo Sirainen}
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen