[Libct] Regarding libct and cgroup subgroups w/ or w/o mount namespaces.
Monali Porob
Monali.Porob at huawei.com
Tue Jan 20 15:05:34 PST 2015
Hi Andrew ,
The attached patch seems to fix the issue I mentioned below .
Thanks so much .
Regards,
Monali
-----Original Message-----
From: Andrew Vagin [mailto:avagin at parallels.com]
Sent: Wednesday, December 24, 2014 7:54 AM
To: Monali Porob
Cc: libct at openvz.org
Subject: Re: Regarding libct and cgroup subgroups w/ or w/o mount namespaces.
On Wed, Dec 24, 2014 at 01:39:40AM +0000, Monali Porob wrote:
> Hi Andrew ,
>
>
>
> For container with a mount namespaces and bind mounted controllers
> into its file tree,. I was able to check spawn a callback to check
> creation of subgroups or spawn a program.
>
>
>
> However using the libct_container_enter_execv() to enter a program in
> container is returning failure (-1). Attached is the program with
> failing enter_exec() but working spawn code ..
I found a mistake. Could you try out the attached patch. Thanks.
>
> Wanted to check if I am wrongly programming the parameters for
> libct_container_enter_execv. Tried libct_container_enter_cb() and
> that fails too with -1.
>
> Hence thought of getting pointers to debug the issue further
>
>
>
> Qn 2 :
>
> how do we spawn a container process in one of the subgroups created
> under the container file tree which has all the cgroup controllers bind mounted.
>
>
>
> Qn3:
>
> Also ,
>
> For a container with cgroups and without any namespaces (not even
> mount) , I am looking to check if the following functionalities would
> be supported by libct .
>
> -Ability to create container with a default subgroup , configure
> default subgroup and start a container process in the default subgroup.
>
> - Ability to create and configure additional subgroups and then move
> process from default subgroup to other already configured subgroups.
>
>
>
> Regards,
>
> Monali
>
>
>
> /*
> * Test creation of container with cgroup controller with subgroups
> and mount namespaces */ #define _XOPEN_SOURCE #include <libct.h>
> #include <stdio.h> #include <sys/mman.h> #include <fcntl.h> #include
> <string.h> #include <stdlib.h> #include <unistd.h> #include <libct.h>
> #include <stdio.h> #include <unistd.h> #include <sys/mman.h> #include
> <string.h> #include <fcntl.h> #include <unistd.h> #include
> <sys/stat.h> #include <sys/types.h> #include "test.h"
>
> #define CPUS "0"
> #define STR_HELPER(x) #x
> #define STR(x) STR_HELPER(x)
>
> #define MEMLIMIT 134217728 //128 MB
> #define MEMLIMIT_STR STR(MEMLIMIT)
>
> #define LOWER_THAN_LIMIT 104857600 //100 MB #define
> LOWER_THAN_LIMIT_STR STR(LOWER_THAN_LIMIT)
>
> #define FS_ROOT "libct_test_root_ns"
> #define FS_PRIVATE "libct_test_private_ns"
> #define FS_CG "cg"
>
> // External directories that will be bind mounted in the container
> #define FS_EXT_BIN "/usr/bin"
> #define FS_EXT_LIB "/lib"
> #define FS_EXT_LIB64 "/lib64"
>
> #define FS_CT_BIN "bin"
> #define FS_CT_LIB "lib"
> #define FS_CT_LIB64 "lib64"
>
>
> #ifndef CLONE_NEWNS
> #define CLONE_NEWNS 0x00020000
> #endif
>
> // For testing Define STRESS_MEM_STR to either LOWER_THAN_LIMIT_STR or
> MEMLIMIT_STR #define STRESS_MEM_STR LOWER_THAN_LIMIT_STR //#define
> STRESS_MEM_STR MEMLIMIT_STR
>
> int is_memory_limit_correct(const char *expected_limit) {
> int ret = 0;
> FILE *f = NULL;
> char buf[1024] = {'\0'};
>
> f = fopen("/sys/fs/cgroup/memory/test1/memory.limit_in_bytes", "r");
> if (!f) {
> fprintf(stderr, "Unable to open memory limit file !\n");
> goto err;
> }
>
> if (fscanf(f, "%s", buf) != 1) {
> fprintf(stderr, "fscanf failed!\n");
> goto err;
> }
> printf(" /sys/fs/cgroup/memory/test1/memory.limit_in_bytes now contains %s \n",buf);
> ret = !strcmp(buf, expected_limit);
> err:
> fclose(f);
> return ret;
> }
>
> static int check_cgroup(void *a)
> {
> FILE *f = NULL;
> char buf[1024] = {'\0'};
> mkdir("/"FS_CG"/memory/x", 0600);
> f = fopen("/"FS_CG"/memory/x/memory.limit_in_bytes", "r");
> if (!f) {
> fprintf(stderr, "Unable to open memory limit file !\n");
> goto err;
> }
>
> if (fscanf(f, "%s", buf) != 1) {
> fprintf(stderr, "fscanf failed!\n");
> goto err;
> }
> printf(" /"FS_CG"/memory/x/memory.limit_in_bytes now contains %s \n",buf);
> if (access("/"FS_CT_BIN"/stress", F_OK) == 0)
> printf (" Stress program is accessible in the CT \n");
> else
> printf (" Stress program is NOT available !! \n");
>
> // rmdir("/"FS_CG"/memory/x");
>
> err:
> fclose(f);
> return 0;
> }
>
> int main(int argc, char **argv)
> {
> libct_session_t s;
> ct_handler_t ct;
> ct_process_desc_t p;
> ct_process_t pr;
> int ret = 0;
> int state = 0;
> int fs_err = 0;
>
> mkdir(FS_ROOT, 0600);
> mkdir(FS_ROOT "/" FS_CT_BIN, 0600);
> mkdir(FS_ROOT "/" FS_CT_LIB, 0600);
> mkdir(FS_ROOT "/" FS_CT_LIB64, 0600);
>
> mkdir(FS_PRIVATE, 0600);
> mkdir(FS_PRIVATE "/" FS_CG, 0600);
>
> s = libct_session_open_local();
> ct = libct_container_create(s, "test1");
> p = libct_process_desc_create(s);
>
> libct_container_set_nsmask(ct, CLONE_NEWNS);
>
> libct_controller_add(ct, CTL_MEMORY);
> ret = libct_controller_configure(ct, CTL_MEMORY, "memory.limit_in_bytes", MEMLIMIT_STR);
> printf("\n libct_controller_configure returned %d \n", ret);
>
> ret = libct_controller_configure(ct, CTL_MEMORY, "memory.memsw.limit_in_bytes", MEMLIMIT_STR);
> printf("\n libct_controller_configure returned %d \n", ret);
>
>
> libct_fs_set_root(ct, FS_ROOT);
> libct_fs_add_bind_mount(ct, FS_EXT_BIN, FS_CT_BIN, 0);
> libct_fs_add_bind_mount(ct, FS_EXT_LIB, FS_CT_LIB, 0);
> libct_fs_add_bind_mount(ct, FS_EXT_LIB64, FS_CT_LIB64, 0);
>
> libct_fs_set_private(ct, CT_FS_SUBDIR, FS_PRIVATE);
> libct_container_set_option(ct, LIBCT_OPT_CGROUP_SUBMOUNT, FS_CG); #if
> 0
> pr = libct_container_spawn_cb(ct, p, check_cgroup, NULL);
> if (libct_handle_is_err(pr))
> {
> printf("\n lbct_container_spawn_cb failed with value = %ld \n",libct_handle_to_err(pr));
> return fail("Unable to spawn stress program into CT");
> }
>
> #endif
> state = libct_container_state(ct);
> printf(" Before : state of the container is %d \n",state);
>
> char *stress_a[8];
> stress_a[0] = "/"FS_CT_BIN"/stress";
> stress_a[1] = "--vm";
> stress_a[2] = "1";
> stress_a[3] = "--vm-bytes";
> stress_a[4] = STRESS_MEM_STR;
> stress_a[5] = "--vm-hang";
> stress_a[6] = "0";
> stress_a[7]= NULL;
>
> printf ("Stress path is %s \n ",stress_a[0]);
> pr = libct_container_spawn_execv(ct,p, "/"FS_CT_BIN"/stress",stress_a);
> if (libct_handle_is_err(pr))
> {
> printf("\n libct_container_spawn_execv failed with value = %ld \n",libct_handle_to_err(pr));
> return fail("Unable to spawn stress program into CT");
> }
>
> // This is not working .
> pr = libct_container_enter_cb(ct, p, check_cgroup, NULL);
> if (libct_handle_is_err(pr))
> {
> printf("\n lbct_container_enter_cb failed with value = %ld \n",libct_handle_to_err(pr));
> return fail("Unable to enter callback into CT");
> }
>
> #if 0
> // This is not working either .
> //pr = libct_container_enter_execv(ct,p, "/"FS_CT_BIN"/stress",stress_a);
> stress_a[0] = "/usr/bin/stress";
> printf ("Stress path is %s \n ",stress_a[0]);
> pr = libct_container_enter_execv(ct,p, "/usr/bin/stress",stress_a);
> if (libct_handle_is_err(pr))
> {
> printf("\n libct_container_enter_execv failed with value = %ld \n",libct_handle_to_err(pr));
> return fail("Unable to enter stress program into CT");
> }
>
> #endif
> state = libct_container_state(ct);
> printf("\n After spawn_exec state of the container is %d
> \n",state);
>
> if (!is_memory_limit_correct(MEMLIMIT_STR))
> return fail("Memory settings dont match to the expected value");
>
> if (libct_container_wait(ct) < 0)
> goto err;
> libct_container_destroy(ct);
> libct_session_close(s);
>
> if (rmdir(FS_PRIVATE "/" FS_CG) < 0)
> fs_err |= 1;
> if (rmdir(FS_ROOT "/" FS_CT_BIN) < 0)
> fs_err |= 2;
> if (rmdir(FS_ROOT "/" FS_CT_LIB) < 0)
> fs_err |= 4;
> if (rmdir(FS_ROOT "/" FS_CT_LIB64) < 0)
> fs_err |= 8;
> if (rmdir(FS_ROOT) < 0)
> fs_err |= 3;
> if (rmdir(FS_PRIVATE) < 0)
> fs_err |= 16;
>
> if (fs_err) {
> printf("FS remove failed %x %d \n", fs_err,fs_err);
> return fail("FS broken");
>
> }
>
> return pass("Memory limited CT is OK");
> err:
> return fail("Something wrong");
> }
More information about the Libct
mailing list