]> TLD Linux GIT Repositories - packages/qemu.git/blob - ksmctl.c
- release 2
[packages/qemu.git] / ksmctl.c
1 /* Start/stop KSM, for systemd.
2  * Copyright (C) 2009, 2011 Red Hat, Inc.
3  * Written by Paolo Bonzini <pbonzini@redhat.com>.
4  * Based on the original sysvinit script by Dan Kenigsberg <danken@redhat.com>
5  * This file is distributed under the GNU General Public License, version 2
6  * or later.  */
7
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <limits.h>
11 #include <stdint.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #define KSM_MAX_KERNEL_PAGES_FILE "/sys/kernel/mm/ksm/max_kernel_pages"
16 #define KSM_RUN_FILE              "/sys/kernel/mm/ksm/run"
17
18 char *program_name;
19
20 int usage(void)
21 {
22         fprintf(stderr, "Usage: %s {start|stop}\n", program_name);
23         return 1;
24 }
25
26 int write_value(uint64_t value, char *filename)
27 {
28         FILE *fp;
29         if (!(fp = fopen(filename, "w")) ||
30             fprintf(fp, "%llu\n", (unsigned long long) value) == EOF ||
31             fflush(fp) == EOF ||
32             fclose(fp) == EOF)
33                 return 1;
34
35         return 0;
36 }
37
38 uint64_t ksm_max_kernel_pages()
39 {
40         char *var = getenv("KSM_MAX_KERNEL_PAGES");
41         char *endptr;
42         uint64_t value;
43         if (var && *var) {
44                 value = strtoll(var, &endptr, 0);
45                 if (value < LLONG_MAX && !*endptr)
46                         return value;
47         }
48         /* Unless KSM_MAX_KERNEL_PAGES is set, let KSM munch up to half of
49          * total memory.  */
50         return sysconf(_SC_PHYS_PAGES) / 2;
51 }
52
53 int start(void)
54 {
55         if (access(KSM_MAX_KERNEL_PAGES_FILE, R_OK) >= 0)
56                 write_value(ksm_max_kernel_pages(), KSM_MAX_KERNEL_PAGES_FILE);
57         return write_value(1, KSM_RUN_FILE);
58 }
59
60 int stop(void)
61 {
62         return write_value(0, KSM_RUN_FILE);
63 }
64
65 int main(int argc, char **argv)
66 {
67         program_name = argv[0];
68         if (argc < 2) {
69                 return usage();
70         } else if (!strcmp(argv[1], "start")) {
71                 return start();
72         } else if (!strcmp(argv[1], "stop")) {
73                 return stop();
74         } else {
75                 return usage();
76         }
77 }