Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using cgroups to control memory usage on Linux

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); 
}

[1] https://askubuntu.com/questions/94619/how-to-set-cpu-limit-for-given-process-permanently-cpulimit-and-nice-dont-work

like image 365
Sam Hakim Avatar asked Dec 07 '25 03:12

Sam Hakim


1 Answers

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. cadvisor. Hope that helps :)

like image 81
Rohit Jnagal Avatar answered Dec 08 '25 22:12

Rohit Jnagal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!