2 * Copyright IBM Corp 2007
3 * Author: Hans-Joachim Picht <hans@linux.vnet.ibm.com>
5 * Linux for System z Hotplug Daemon
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include <sys/types.h>
33 #include <linux/param.h>
38 #include <sys/types.h>
39 #include <sys/ioctl.h>
45 * return page in and out as well as the page
46 * swap in and out rate based on /proc/vmstat
48 int get_vmstats(struct vm_info
*v
)
57 int pgpgout
; /* page out */
58 int pswpout
; /* page swap out */
59 int pswpin
; /* page swap in */
60 int pgpgin
; /* page in */
63 filp
= fopen("/proc/vmstat", "r");
65 fprintf(stderr
, "Can not open /proc/vmstat:");
66 fprintf(stderr
, "%s\n", strerror(errno
));
68 syslog(LOG_ERR
, "Can not open /proc/vmstat"
69 ":%s\n", strerror(errno
));
73 bytes_read
= fread(buffer
, 1, sizeof(buffer
), filp
);
75 * Bail if read failed or the buffer isn't big enough
77 if (bytes_read
== 0) {
78 fprintf(stderr
, "Reading /proc/vmstat failed:");
79 fprintf(stderr
, "%s\n", strerror(errno
));
81 syslog(LOG_ERR
, "Reading /proc/vmstat failed"
82 ":%s\n", strerror(errno
));
87 * NUL-terminate the text
89 buffer
[bytes_read
] = '\0';
90 match_pgpgout
= strstr(buffer
, "pgpgout");
91 match_pswpout
= strstr(buffer
, "pswpout");
92 match_pgpgin
= strstr(buffer
, "pgpgin");
93 match_pswpin
= strstr(buffer
, "pswpin");
94 if (match_pgpgout
== NULL
|| match_pswpout
== NULL
||
95 match_pgpgin
== NULL
|| match_pswpin
== NULL
) {
99 sscanf(match_pgpgout
, "pgpgout %d", &pgpgout
);
100 sscanf(match_pswpout
, "pswpout %d", &pswpout
);
101 sscanf(match_pgpgin
, "pgpgin %d", &pgpgin
);
102 sscanf(match_pswpin
, "pswpin %d", &pswpin
);
103 v
->pgpgout
= pgpgout
;
104 v
->pswpout
= pswpout
;
115 * The cmm_pages value defines the size of the balloon of blocked memory.
116 * Increasing the value is removing memory from Linux, which is an memunplug.
117 * Decreasing the value is adding memory back to Linux, which is memplug.
121 * increase number of pages permanently reserved
123 int memunplug(int size
)
125 int old_size
, new_size
;
128 old_size
= get_cmmpages_size();
130 * new value: previous value + size
132 new_size
= old_size
+ size
;
133 filp
= fopen("/proc/sys/vm/cmm_pages", "w");
135 fprintf(stderr
, "Can not open /proc/sys/vm/cmm_pages: %s\n",
138 syslog(LOG_ERR
, "Can not open /proc/sys/vm/cmm_pages"
139 ":%s\n", strerror(errno
));
142 fprintf(filp
, "%d\n", new_size
);
143 if (debug
&& foreground
== 1)
144 printf("changed number of pages permanently reserved "
145 "to %d \n", new_size
);
146 if (debug
&& foreground
== 0)
147 syslog(LOG_INFO
, "changed number of pages permanently"
148 " reserved to %d \n", new_size
);
154 * decrease number of pages permanently reserved
156 int memplug(int size
)
158 int old_size
, new_size
;
161 old_size
= get_cmmpages_size();
163 * new value: previous value - size
165 new_size
= old_size
- size
;
168 filp
= fopen("/proc/sys/vm/cmm_pages", "w");
170 fprintf(stderr
, "Can not open /proc/sys/vm/cmmpages: %s\n",
173 syslog(LOG_ERR
, "Can not open /proc/sys/vm/cmm_pages"
174 ":%s\n", strerror(errno
));
177 fprintf(filp
, "%d\n", new_size
);
178 if (debug
&& foreground
== 1)
179 printf("changed number of pages permanently reserved "
180 "to %d \n", new_size
);
181 if (debug
&& foreground
== 0)
182 syslog(LOG_INFO
, "changed number of pages permanently"
183 "reserved to %d \n", new_size
);
189 * override the value of cmm_pages
191 int set_cmm_pages(int size
)
195 filp
= fopen("/proc/sys/vm/cmm_pages", "w");
197 fprintf(stderr
, "Can not open /proc/sys/vm/cmmpages: %s\n",
200 syslog(LOG_ERR
, "Can not open /proc/sys/vm/cmm_pages"
201 ":%s\n", strerror(errno
));
204 fprintf(filp
, "%d\n", size
);
205 if (debug
&& foreground
== 1)
206 printf("changed number of pages permanently reserved "
208 if (debug
&& foreground
== 0)
209 syslog(LOG_INFO
, "changed number of pages permanently"
210 "reserved to %d \n", size
);
215 * read number of pages permanently reserved
217 int get_cmmpages_size()
223 filp
= fopen("/proc/sys/vm/cmm_pages", "r");
225 fprintf(stderr
, "Can not open /proc/sys/vm/cmm_pages: %s\n",
228 syslog(LOG_ERR
, "Can not open /proc/sys/vm/cmm_pages"
229 ":%s\n", strerror(errno
));
232 rc
= fscanf(filp
, "%d", &size
);
234 fprintf(stderr
, "Can not read /proc/sys/vm/cmm_pages: %s\n",
237 syslog(LOG_ERR
, "Can not read /proc/sys/vm/cmm_pages"
238 ":%s\n", strerror(errno
));
248 * reset cmm pagesize to value we found prior to daemon startup
254 filp
= fopen("/proc/sys/vm/cmm_pages", "w");
256 fprintf(stderr
, "Can not open /proc/sys/vm/cmm_pages: %s\n",
259 syslog(LOG_ERR
, "Can not open /proc/sys/vm/cmm_pages"
260 ":%s\n", strerror(errno
));
263 fprintf(filp
, "%d", cmm_pagesize_start
);
264 if (debug
&& foreground
== 1)
265 printf("changed number of pages permanently reserved"
266 " to %d \n", cmm_pagesize_start
);
267 if (debug
&& foreground
== 0)
268 syslog(LOG_INFO
, "changed number of pages permanently "
269 " reserved to %d \n",
279 * function to check if the cmm kernel module is loaded and the required
280 * files below /proc exit
282 int check_cmmfiles(void)
286 filp
= fopen("/proc/sys/vm/cmm_pages", "r");
295 * return amount of *free* memory as reported by
298 int get_free_memsize()
309 filp
= fopen("/proc/meminfo", "r");
311 fprintf(stderr
, "%s\n", strerror(errno
));
313 syslog(LOG_ERR
, "Can not open /proc/meminfo"
314 ":%s\n", strerror(errno
));
317 bytes_read
= fread(buffer
, 1, sizeof(buffer
), filp
);
319 * Bail if read failed or the buffer isn't big enough
321 if (bytes_read
== 0) {
322 fprintf(stderr
, "Reading /proc/meminfo failed:");
323 fprintf(stderr
, "%s\n", strerror(errno
));
325 syslog(LOG_ERR
, "Reading /proc/meminfo failed"
326 ":%s\n", strerror(errno
));
329 buffer
[bytes_read
] = '\0';
331 * Locate the line that starts with
334 match
= strstr(buffer
, "MemFree");
336 fprintf(stderr
, "No MemFree entry found in /proc/meminfo\n");
340 * Parse the line to extract
341 * the amount of memory
343 rc
= sscanf(match
, "MemFree : %d", &size
);