Blame ksmctl.c

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