Update qemu package to mitigate CVE-2015-3456
[packages/centos6/qemu.git] / ksmtuned
1 #!/bin/bash
2 #
3 # Copyright 2009 Red Hat, Inc. and/or its affiliates.
4 # Released under the GPL
5 #
6 # Author:      Dan Kenigsberg <danken@redhat.com>
7 #
8 # ksmtuned - a simple script that controls whether (and with what vigor) ksm
9 # should search for duplicated pages.
10 #
11 # starts ksm when memory commited to qemu processes exceeds a threshold, and
12 # make ksm work harder and harder untill memory load falls below that
13 # threshold.
14 #
15 # send SIGUSR1 to this process right after a new qemu process is started, or
16 # following its death, to retune ksm accordingly
17 #
18 # needs testing and ironing. contact danken@redhat.com if something breaks.
19
20 if [ -f /etc/ksmtuned.conf ]; then
21     . /etc/ksmtuned.conf
22 fi
23
24 debug() {
25     if [ -n "$DEBUG" ]; then
26         s="`/bin/date`: $*"
27         [ -n "$LOGFILE" ] && echo "$s" >> "$LOGFILE" || echo "$s"
28     fi
29 }
30
31
32 KSM_MONITOR_INTERVAL=${KSM_MONITOR_INTERVAL:-60}
33 KSM_NPAGES_BOOST=${KSM_NPAGES_BOOST:-300}
34 KSM_NPAGES_DECAY=${KSM_NPAGES_DECAY:--50}
35
36 KSM_NPAGES_MIN=${KSM_NPAGES_MIN:-64}
37 KSM_NPAGES_MAX=${KSM_NPAGES_MAX:-1250}
38 # millisecond sleep between ksm scans for 16Gb server. Smaller servers sleep
39 # more, bigger sleep less.
40 KSM_SLEEP_MSEC=${KSM_SLEEP_MSEC:-10}
41
42 KSM_THRES_COEF=${KSM_THRES_COEF:-20}
43 KSM_THRES_CONST=${KSM_THRES_CONST:-2048}
44
45 total=`awk '/^MemTotal:/ {print $2}' /proc/meminfo`
46 debug total $total
47
48 npages=0
49 sleep=$[KSM_SLEEP_MSEC * 16 * 1024 * 1024 / total]
50 [ $sleep -le 10 ] && sleep=10
51 debug sleep $sleep
52 thres=$[total * KSM_THRES_COEF / 100]
53 if [ $KSM_THRES_CONST -gt $thres ]; then
54     thres=$KSM_THRES_CONST
55 fi
56 debug thres $thres
57
58 KSMCTL () {
59     case x$1 in
60         xstop)
61             echo 0 > /sys/kernel/mm/ksm/run
62             ;;
63         xstart)
64             echo $2 > /sys/kernel/mm/ksm/pages_to_scan
65             echo $3 > /sys/kernel/mm/ksm/sleep_millisecs
66             echo 1 > /sys/kernel/mm/ksm/run
67             ;;
68     esac
69 }
70
71 committed_memory () {
72     # calculate how much memory is committed to running qemu processes
73     local pidlist
74     pidlist=$(pgrep -d ' ' -- '^qemu(-(kvm|system-.+)|:.{1,11})$')
75     if [ -n "$pidlist" ]; then
76         ps -p "$pidlist" -o rsz=
77     fi | awk '{ sum += $1 }; END { print 0+sum }'
78 }
79
80 free_memory () {
81     awk '/^(MemFree|Buffers|Cached):/ {free += $2}; END {print free}' \
82                 /proc/meminfo
83 }
84
85 increase_npages() {
86     local delta
87     delta=${1:-0}
88     npages=$[npages + delta]
89     if [ $npages -lt $KSM_NPAGES_MIN ]; then
90         npages=$KSM_NPAGES_MIN
91     elif [ $npages -gt $KSM_NPAGES_MAX ]; then
92         npages=$KSM_NPAGES_MAX
93     fi
94     echo $npages
95 }
96
97
98 adjust () {
99     local free committed
100     free=`free_memory`
101     committed=`committed_memory`
102     debug committed $committed free $free
103     if [ $[committed + thres] -lt $total -a $free -gt $thres ]; then
104         KSMCTL stop
105         debug "$[committed + thres] < $total and free > $thres, stop ksm"
106         return 1
107     fi
108     debug "$[committed + thres] > $total, start ksm"
109     if [ $free -lt $thres ]; then
110         npages=`increase_npages $KSM_NPAGES_BOOST`
111         debug "$free < $thres, boost"
112     else
113         npages=`increase_npages $KSM_NPAGES_DECAY`
114         debug "$free > $thres, decay"
115     fi
116     KSMCTL start $npages $sleep
117     debug "KSMCTL start $npages $sleep"
118     return 0
119 }
120
121 function nothing () {
122     :
123 }
124
125 loop () {
126     trap nothing SIGUSR1
127     while true
128     do
129         sleep $KSM_MONITOR_INTERVAL &
130         wait $!
131         adjust
132     done
133 }
134
135 PIDFILE=${PIDFILE-/var/run/ksmtune.pid}
136 if touch "$PIDFILE"; then
137   loop &
138   echo $! > "$PIDFILE"
139 fi