|
|
ae23c9 |
/* Start/stop KSM, for systemd.
|
|
|
ae23c9 |
* Copyright (C) 2009, 2011 Red Hat, Inc.
|
|
|
ae23c9 |
* Written by Paolo Bonzini <pbonzini@redhat.com>.
|
|
|
ae23c9 |
* Based on the original sysvinit script by Dan Kenigsberg <danken@redhat.com>
|
|
|
ae23c9 |
* This file is distributed under the GNU General Public License, version 2
|
|
|
ae23c9 |
* or later. */
|
|
|
ae23c9 |
|
|
|
ae23c9 |
#include <unistd.h>
|
|
|
ae23c9 |
#include <stdio.h>
|
|
|
ae23c9 |
#include <limits.h>
|
|
|
ae23c9 |
#include <stdint.h>
|
|
|
ae23c9 |
#include <stdlib.h>
|
|
|
ae23c9 |
#include <string.h>
|
|
|
ae23c9 |
|
|
|
ae23c9 |
#define KSM_MAX_KERNEL_PAGES_FILE "/sys/kernel/mm/ksm/max_kernel_pages"
|
|
|
ae23c9 |
#define KSM_RUN_FILE "/sys/kernel/mm/ksm/run"
|
|
|
ae23c9 |
|
|
|
ae23c9 |
char *program_name;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
int usage(void)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
fprintf(stderr, "Usage: %s {start|stop}\n", program_name);
|
|
|
ae23c9 |
return 1;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
int write_value(uint64_t value, char *filename)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
FILE *fp;
|
|
|
ae23c9 |
if (!(fp = fopen(filename, "w")) ||
|
|
|
ae23c9 |
fprintf(fp, "%llu\n", (unsigned long long) value) == EOF ||
|
|
|
ae23c9 |
fflush(fp) == EOF ||
|
|
|
ae23c9 |
fclose(fp) == EOF)
|
|
|
ae23c9 |
return 1;
|
|
|
ae23c9 |
|
|
|
ae23c9 |
return 0;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
uint64_t ksm_max_kernel_pages()
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
char *var = getenv("KSM_MAX_KERNEL_PAGES");
|
|
|
ae23c9 |
char *endptr;
|
|
|
ae23c9 |
uint64_t value;
|
|
|
ae23c9 |
if (var && *var) {
|
|
|
ae23c9 |
value = strtoll(var, &endptr, 0);
|
|
|
ae23c9 |
if (value < LLONG_MAX && !*endptr)
|
|
|
ae23c9 |
return value;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
/* Unless KSM_MAX_KERNEL_PAGES is set, let KSM munch up to half of
|
|
|
ae23c9 |
* total memory. */
|
|
|
ae23c9 |
return sysconf(_SC_PHYS_PAGES) / 2;
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
int start(void)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
if (access(KSM_MAX_KERNEL_PAGES_FILE, R_OK) >= 0)
|
|
|
ae23c9 |
write_value(ksm_max_kernel_pages(), KSM_MAX_KERNEL_PAGES_FILE);
|
|
|
ae23c9 |
return write_value(1, KSM_RUN_FILE);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
int stop(void)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
return write_value(0, KSM_RUN_FILE);
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
|
|
|
ae23c9 |
int main(int argc, char **argv)
|
|
|
ae23c9 |
{
|
|
|
ae23c9 |
program_name = argv[0];
|
|
|
ae23c9 |
if (argc < 2) {
|
|
|
ae23c9 |
return usage();
|
|
|
ae23c9 |
} else if (!strcmp(argv[1], "start")) {
|
|
|
ae23c9 |
return start();
|
|
|
ae23c9 |
} else if (!strcmp(argv[1], "stop")) {
|
|
|
ae23c9 |
return stop();
|
|
|
ae23c9 |
} else {
|
|
|
ae23c9 |
return usage();
|
|
|
ae23c9 |
}
|
|
|
ae23c9 |
}
|