[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