I’m trying to use cgroups to stop programs that actually USE too much memory, while letting them run if they just allocate and don’t actually use lots of memory. However, it doesn’t seem to work; any suggestions? On a Ubuntu machine, I set up my cgroup as follows[1]:
#Changing $USER to a system user running the process
sudo apt-get install cgroup-bin
sudo cgcreate -a $USER -g memory:$USER
echo 100M > /cgroup/memory/$USER/memory.limit_in_bytes
#Running the program using cgroups
cgexec -g memory:$USER program
I am using the following program (answering ‘no’ should work, and ‘yes’ should be stopped).
#include <stdlib.h>
#include <stdio.h>
#define SIZE (long int) 1*1024*1024*1024*sizeof(char)/*1 GB*/
int main(void)
{
char *str = (char*) malloc(SIZE);
char *ans = (char*) malloc(100);
printf("Write random values to memory? (yes/no): ");
scanf("%s", ans);
if (strcmp(ans,"yes") == 0) {
FILE *f = fopen("/dev/urandom","r");
fread(str,1,SIZE,f);
printf("Success!!\n");
fclose(f);
free(str);
}
else {
printf("Have a good day!\n");
}
return(0);
}
You test is returning success as it doesn't check for error. In fact, the fread call failed allocation when your binary hit the memory limit. You can see that by changing the code to check for error:
#include <stdlib.h>
#include <stdio.h>
#define SIZE (long int) 1*1024*1024*1024*sizeof(char)/*1 GB*/
int main(void)
{
char *str = (char*) malloc(SIZE);
char *ans = (char*) malloc(100);
printf("Write random values to memory? (yes/no): ");
scanf("%s", ans);
if (strcmp(ans,"yes") == 0) {
FILE *f = fopen("/dev/urandom","r");
int size = fread(str,1,SIZE,f);
if (size < SIZE) {
printf("incomplete read: %d, error %d\n", size, ferror(f));
} else {
printf("Success!!\n");
}
fclose(f);
free(str);
}
else {
printf("Have a good day!\n");
}
return(0);
}
Even cooler is to use a cgroup monitoring utility like cadvisor You can graphically see your binary hitting the limit. . Hope that helps :)