]>
Commit | Line | Data |
---|---|---|
9fdf235e JR |
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 | } |