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
43 int flag_exit;
44 int flag_allocated;
45 unsigned long memsize;
46
47 /*
48 * process_options: process user specified options
49 */
process_options(int argc,char ** argv)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 */
touch_memory(char * p)75 void touch_memory(char *p)
76 {
77 int i;
78 int pagesize = getpagesize();
79
80 for (i = 0; i < (int)memsize; i += pagesize)
81 p[i] = 0xef;
82 }
83
mem_map(void)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 */
action(int fd)104 char action(int fd)
105 {
106 char ch;
107
108 if (read(fd, &ch, 1) == -1)
109 err(7, "Error reading named pipe");
110
111 return ch;
112 }
113
main(int argc,char ** argv)114 int main(int argc, char **argv)
115 {
116 int ret;
117 int fd;
118 char ch;
119
120 process_options(argc, argv);
121
122 ret = mkfifo(STATUS_PIPE, 0666);
123
124 if (ret == -1 && errno != EEXIST)
125 errx(1, "Error creating named pipe");
126
127 if ((fd = open(STATUS_PIPE, O_RDONLY)) == -1)
128 err(6, "Error opening named pipe");
129
130 do {
131 ch = action(fd);
132
133 if (ch == 'm')
134 mem_map();
135 } while (ch != 'x');
136
137 close(fd);
138
139 remove(STATUS_PIPE);
140
141 return 0;
142 }
143