File: ksmctl.c

package info (click to toggle)
ksmtuned 4.20150326
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 60 kB
  • sloc: sh: 101; ansic: 59; makefile: 12
file content (77 lines) | stat: -rw-r--r-- 1,724 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/* Start/stop KSM, for systemd.
 * Copyright (C) 2009, 2011 Red Hat, Inc.
 * Written by Paolo Bonzini <pbonzini@redhat.com>.
 * Based on the original sysvinit script by Dan Kenigsberg <danken@redhat.com>
 * This file is distributed under the GNU General Public License, version 2
 * or later.  */

#include <unistd.h>
#include <stdio.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#define KSM_MAX_KERNEL_PAGES_FILE "/sys/kernel/mm/ksm/max_kernel_pages"
#define KSM_RUN_FILE		  "/sys/kernel/mm/ksm/run"

char *program_name;

int usage(void)
{
	fprintf(stderr, "Usage: %s {start|stop}\n", program_name);
	return 1;
}

int write_value(uint64_t value, char *filename)
{
	FILE *fp;
	if (!(fp = fopen(filename, "w")) ||
	    fprintf(fp, "%llu\n", (unsigned long long) value) == EOF ||
	    fflush(fp) == EOF ||
	    fclose(fp) == EOF)
		return 1;

	return 0;
}

uint64_t ksm_max_kernel_pages()
{
	char *var = getenv("KSM_MAX_KERNEL_PAGES");
	char *endptr;
	uint64_t value;
	if (var && *var) {
		value = strtoll(var, &endptr, 0);
		if (value < LLONG_MAX && !*endptr)
			return value;
	}
	/* Unless KSM_MAX_KERNEL_PAGES is set, let KSM munch up to half of
	 * total memory.  */
	return sysconf(_SC_PHYS_PAGES) / 2;
}

int start(void)
{
	if (access(KSM_MAX_KERNEL_PAGES_FILE, R_OK) >= 0)
		write_value(ksm_max_kernel_pages(), KSM_MAX_KERNEL_PAGES_FILE);
	return write_value(1, KSM_RUN_FILE);
}

int stop(void)
{
	return write_value(0, KSM_RUN_FILE);
}

int main(int argc, char **argv)
{
	program_name = argv[0];
	if (argc < 2) {
		return usage();
	} else if (!strcmp(argv[1], "start")) {
		return start();
	} else if (!strcmp(argv[1], "stop")) {
		return stop();
	} else {
		return usage();
	}
}