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@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
43int flag_exit;
44int flag_allocated;
45unsigned long memsize;
46
47/*
48 * process_options: process user specified options
49 */
50void 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 specifed");
65		}
66	}
67
68	if (memsize <= 0)
69		errx(3, "invalid usage");
70}
71
72/*
73 * touch_memory: force physical memory allocation
74 */
75void 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
84void mem_map()
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 */
104char action()
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
120int 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