/* * Test creation of container with cgroup controller. Impose memory limits . */ #define _XOPEN_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #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) // 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 #define NONE 0 #define KILL 1 /* When a SIGUSR1 signal arrives, set this variable so that the processes in the test1 container are killed . */ volatile sig_atomic_t operation = NONE; 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; } void usr1_signal_handler (int sig) { operation = KILL; } int main(int argc, char **argv) { libct_session_t s; ct_handler_t ct; ct_process_desc_t p; int ret = 0; int state = 0; struct sigaction usr_action1; sigset_t block_mask1; /* Establish the signal handler for SIGUSR1. */ sigfillset (&block_mask1); usr_action1.sa_handler = usr1_signal_handler; usr_action1.sa_mask = block_mask1; usr_action1.sa_flags = 0; sigaction (SIGUSR1, &usr_action1, NULL); s = libct_session_open_local(); ct = libct_container_create(s, "test1"); p = libct_process_desc_create(s); 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); if (libct_container_set_option(ct, LIBCT_OPT_KILLABLE, NULL)) { tst_err("can't set killable"); } state = libct_container_state(ct); printf(" Before spawn_exec state of the container is %d \n",state); char *stress_a[8]; int ret_pid = 0; stress_a[0] = "/usr/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; ret_pid = libct_container_spawn_execv(ct,p, "/usr/bin/stress",stress_a); printf("\n libct_container_spawn_execv returned %d \n", ret_pid); if (ret_pid <= 0 ) return fail("Can't spawn stress program in container"); 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"); //Wait till SIGUSR1 arrives and then kill the container while(1) { if (operation == KILL) { printf("\n Killed the container \n"); libct_container_kill(ct); if (libct_container_wait(ct) < 0) goto err; state = libct_container_state(ct); // printf("state of the container is %d \n",state); libct_container_destroy(ct); libct_session_close(s); return pass("Memory limited and with service cgroup controller,CT is OK"); } state = libct_container_state(ct); // printf("state of the container is %d \n",state); } err: return fail("Something wrong"); }