Home | History | Annotate | Download | only in control
      1 /*****************************************************************************/
      2 /*                                                                           */
      3 /*  Copyright (c) 2010 Mohamed Naufal Basheer                                */
      4 /*                                                                           */
      5 /*  This program is free software;  you can redistribute it and/or modify    */
      6 /*  it under the terms of the GNU General Public License as published by     */
      7 /*  the Free Software Foundation; either version 2 of the License, or        */
      8 /*  (at your option) any later version.                                      */
      9 /*                                                                           */
     10 /*  This program is distributed in the hope that it will be useful,          */
     11 /*  but WITHOUT ANY WARRANTY;  without even the implied warranty of          */
     12 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                */
     13 /*  the GNU General Public License for more details.                         */
     14 /*                                                                           */
     15 /*  You should have received a copy of the GNU General Public License        */
     16 /*  along with this program;  if not, write to the Free Software             */
     17 /*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA  */
     18 /*                                                                           */
     19 /*  File:    mem_process.c                                                   */
     20 /*                                                                           */
     21 /*  Purpose: act as a memory hog for the memcg_control tests                 */
     22 /*                                                                           */
     23 /*  Author:  Mohamed Naufal Basheer <naufal11 (at) gmail.com >                    */
     24 /*                                                                           */
     25 /*****************************************************************************/
     26 
     27 #include <sys/types.h>
     28 #include <sys/mman.h>
     29 #include <sys/stat.h>
     30 #include <err.h>
     31 #include <errno.h>
     32 #include <fcntl.h>
     33 #include <stdio.h>
     34 #include <stdlib.h>
     35 #include <unistd.h>
     36 
     37 /*
     38  * Named pipe to act as a communication channel between
     39  * shell script & this process
     40  */
     41 #define STATUS_PIPE "status_pipe"
     42 
     43 int flag_exit;
     44 int flag_allocated;
     45 unsigned long memsize;
     46 
     47 /*
     48  * process_options: process user specified options
     49  */
     50 void process_options(int argc, char **argv)
     51 {
     52 	int c;
     53 	char *end;
     54 
     55 	opterr = 0;
     56 	while ((c = getopt(argc, argv, "pm:")) != -1) {
     57 		switch (c) {
     58 		case 'm':
     59 			memsize = strtoul(optarg, &end, 10);
     60 			if (*end != '\0')
     61 				errx(2, "invalid -m usage");
     62 			break;
     63 		default:
     64 			errx(2, "invalid option specified");
     65 		}
     66 	}
     67 
     68 	if (memsize <= 0)
     69 		errx(3, "invalid usage");
     70 }
     71 
     72 /*
     73  * touch_memory: force physical memory allocation
     74  */
     75 void touch_memory(char *p)
     76 {
     77 	int i;
     78 	int pagesize = getpagesize();
     79 
     80 	for (i = 0; i < memsize; i += pagesize)
     81 		p[i] = 0xef;
     82 }
     83 
     84 void mem_map(void)
     85 {
     86 	static char *p;
     87 
     88 	if (flag_allocated) {
     89 		if (munmap(p, memsize) == -1)
     90 			err(5, "munmap failed");
     91 	} else {
     92 		p = mmap(NULL, memsize, PROT_READ | PROT_WRITE,
     93 			 MAP_SHARED | MAP_ANONYMOUS, 0, 0);
     94 		if (p == MAP_FAILED)
     95 			err(4, "mmap failed");
     96 		touch_memory(p);
     97 	}
     98 	flag_allocated = !flag_allocated;
     99 }
    100 
    101 /*
    102  * done: retrieve instructions from the named pipe
    103  */
    104 char action(void)
    105 {
    106 	char ch;
    107 	int fd;
    108 
    109 	if ((fd = open(STATUS_PIPE, O_RDONLY)) == -1)
    110 		err(6, "Error opening named pipe");
    111 
    112 	if (read(fd, &ch, 1) == -1)
    113 		err(7, "Error reading named pipe");
    114 
    115 	close(fd);
    116 
    117 	return ch;
    118 }
    119 
    120 int main(int argc, char **argv)
    121 {
    122 	int ret;
    123 	char ch;
    124 
    125 	process_options(argc, argv);
    126 
    127 	ret = mkfifo(STATUS_PIPE, 0666);
    128 
    129 	if (ret == -1 && errno != EEXIST)
    130 		errx(1, "Error creating named pipe");
    131 
    132 	do {
    133 		ch = action();
    134 
    135 		if (ch == 'm')
    136 			mem_map();
    137 	} while (ch != 'x');
    138 
    139 	remove(STATUS_PIPE);
    140 
    141 	return 0;
    142 }
    143