diff --git a/ksm.init b/ksm.init
index 703286b..9b57587 100644
--- a/ksm.init
+++ b/ksm.init
@@ -76,11 +76,10 @@ case "$1" in
 	stop
 	start
 	;;
-  signal)
-	signal
-	;;
+  condrestart)
+        ;;
   *)
-	echo $"Usage: $prog {start|stop|restart|status|help}"
+	echo $"Usage: $prog {start|stop|restart|condrestart|status|help}"
 	RETVAL=3
 esac
 
diff --git a/ksmtuned b/ksmtuned
new file mode 100644
index 0000000..f72859f
--- /dev/null
+++ b/ksmtuned
@@ -0,0 +1,120 @@
+#!/bin/bash
+#
+# Copyright 2009 Red Hat, Inc. and/or its affiliates.
+# Released under the GPL
+#
+# Author:      Dan Kenigsberg <danken@redhat.com>
+#
+# ksmtuned - a simple script that controls whether (and with what vigor) ksm
+# should search for duplicated pages.
+#
+# starts ksm when memory commited to qemu processes exceeds a threshold, and
+# make ksm work harder and harder untill memory load falls below that
+# threshold.
+#
+# needs testing and ironing. contact danken@redhat.com if something breaks.
+
+if [ -f /etc/ksmtuned.conf ]; then
+    . /etc/ksmtuned.conf
+fi
+
+KSM_MONITOR_INTERVAL=${KSM_MONITOR_INTERVAL:-60}
+KSM_NPAGES_BOOST=${KSM_NPAGES_BOOST:-300}
+KSM_NPAGES_DECAY=${KSM_NPAGES_DECAY:--50}
+
+KSM_NPAGES_MIN=${KSM_NPAGES_MIN:-64}
+KSM_NPAGES_MAX=${KSM_NPAGES_MAX:-1250}
+# millisecond sleep between ksm scans for 16Gb server. Smaller servers sleep
+# more, bigger sleep less.
+KSM_SLEEP_MSEC=${KSM_SLEEP_MSEC:-10}
+
+KSM_THRES_COEF=${KSM_THRES_COEF:-20}
+KSM_THRES_CONST=${KSM_THRES_CONST:-2048}
+
+total=`awk '/^MemTotal:/ {print $2}' /proc/meminfo`
+[ -n "$DEBUG" ] && echo total $total
+
+npages=0
+sleep=$[KSM_SLEEP_MSEC * 16 * 1024 * 1024 / total]
+[ $sleep -le 10 ] && sleep=10
+[ -n "$DEBUG" ] && echo sleep $sleep
+thres=$[total * KSM_THRES_COEF / 100]
+if [ $KSM_THRES_CONST -gt $thres ]; then
+    thres=$KSM_THRES_CONST
+fi
+[ -n "$DEBUG" ] && echo thres $thres
+
+KSMCTL () {
+    case x$1 in
+        xstop)
+            echo 0 > /sys/kernel/mm/ksm/run
+            ;;
+        xstart)
+            echo $2 > /sys/kernel/mm/ksm/pages_to_scan
+            echo $3 > /sys/kernel/mm/ksm/sleep_millisecs
+            echo 1 > /sys/kernel/mm/ksm/run
+            ;;
+    esac
+}
+
+committed_memory () {
+    # calculate how much memory is committed to running qemu processes
+    local progname
+    progname=${1:-qemu}
+    ps -o vsz `pgrep $progname` | awk '{ sum += $1 }; END { print sum }'
+}
+
+free_memory () {
+    awk '/^(MemFree|Buffers|MemCached):/ {free += $2}; END {print free}' \
+                /proc/meminfo
+}
+
+increase_npages() {
+    local delta
+    delta=${1:-0}
+    npages=$[npages + delta]
+    if [ $npages -lt $KSM_NPAGES_MIN ]; then
+        npages=$KSM_NPAGES_MIN
+    elif [ $npages -gt $KSM_NPAGES_MAX ]; then
+        npages=$KSM_NPAGES_MAX
+    fi
+    echo $npages
+}
+
+
+adjust () {
+    local free committed
+    free=`free_memory`
+    committed=`committed_memory`
+    [ -n "$DEBUG" ] && echo committed $committed free $free
+    if [ $[committed + thres] -lt $total -a $free -gt $thres ]; then
+        KSMCTL stop
+        [ -n "$DEBUG" ] && echo "$[committed + thres] < $total and free > $thres, stop ksm"
+        return 1
+    fi
+    [ -n "$DEBUG" ] && echo "$[committed + thres] > $total, start ksm"
+    if [ $free -lt $thres ]; then
+        npages=`increase_npages $KSM_NPAGES_BOOST`
+        [ -n "$DEBUG" ] && echo "$free < $thres, boost"
+    else
+        npages=`increase_npages $KSM_NPAGES_DECAY`
+        [ -n "$DEBUG" ] && echo "$free > $thres, decay"
+    fi
+    KSMCTL start $npages $sleep
+    [ -n "$DEBUG" ] && echo "KSMCTL start $npages $sleep"
+    return 0
+}
+
+loop () {
+    while true
+    do
+        sleep $KSM_MONITOR_INTERVAL
+        adjust
+    done
+}
+
+PIDFILE=${PIDFILE-/var/run/ksmtune.pid}
+if touch "$PIDFILE"; then
+  loop &
+  echo $! > "$PIDFILE"
+fi
diff --git a/ksmtuned.conf b/ksmtuned.conf
new file mode 100644
index 0000000..87b9178
--- /dev/null
+++ b/ksmtuned.conf
@@ -0,0 +1,16 @@
+# Configuration file for ksmtuned.
+
+# How long ksmtuned should sleep between tuning adjustments
+# KSM_MONITOR_INTERVAL=60
+
+# Millisecond sleep between ksm scans for 16Gb server.
+# Smaller servers sleep more, bigger sleep less.
+# KSM_SLEEP_MSEC=10
+
+# KSM_NPAGES_BOOST=300
+# KSM_NPAGES_DECAY=-50
+# KSM_NPAGES_MIN=64
+# KSM_NPAGES_MAX=1250
+
+# KSM_THRES_COEF=20
+# KSM_THRES_CONST=2048
diff --git a/ksmtuned.init b/ksmtuned.init
new file mode 100644
index 0000000..205531a
--- /dev/null
+++ b/ksmtuned.init
@@ -0,0 +1,83 @@
+#!/bin/bash
+#
+# ksmtuned     Kernel Samepage Merging (KSM) Tuning Daemon
+#
+# Author:      Dan Kenigsberg <danken@redhat.com>
+#
+# Copyright 2009 Red Hat, Inc. and/or its affiliates.
+# Released under the GPL
+#
+# chkconfig: - 85 15
+# description: The KSM tuning daemon controls whether (and with what vigor) \
+#              ksm should ksm search duplicated pages.
+# processname: ksmtuned
+# config: /etc/ksmtuned.conf
+# pidfile: /var/run/ksmtuned.pid
+#
+### BEGIN INIT INFO
+# Provides: ksmtuned
+# Required-Start:
+# Required-Stop:
+# Should-Start:
+# Short-Description: tune the speed of ksm
+# Description: The Kernel Samepage Merging control Daemon is a simple script
+#   that controls whether (and with what vigor) should ksm search duplicated
+#   memory pages.
+#   needs testing and ironing. contact danken@redhat.com if something breaks.
+### END INIT INFO
+
+. /etc/rc.d/init.d/functions
+
+prog=ksmtuned
+ksmtuned=/usr/sbin/ksmtuned
+pidfile=${PIDFILE-/var/run/ksmtune.pid}
+RETVAL=0
+
+start() {
+    echo -n $"Starting $prog: "
+    daemon --pidfile=${pidfile} $ksmtuned
+    RETVAL=$?
+    echo
+    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
+}
+
+stop() {
+    echo -n $"Stopping $prog: "
+    killproc -p ${pidfile}
+    RETVAL=$?
+    echo
+    [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
+}
+
+restart() {
+    stop
+    start
+}
+
+condrestart() {
+    [ -e /var/lock/subsys/$prog ] && restart || :
+}
+
+case "$1" in
+  start)
+	start
+	;;
+  stop)
+	stop
+	;;
+  status)
+        status -p ${pidfile} $prog
+	RETVAL=$?
+	;;
+  restart)
+	restart
+	;;
+  condrestart)
+	condrestart
+	;;
+  *)
+	echo $"Usage: $prog {start|stop|restart|condrestart|status|help}"
+	RETVAL=3
+esac
+
+exit $RETVAL
diff --git a/qemu.spec b/qemu.spec
index 9c3ffc2..705a7c2 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -3,7 +3,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 0.10.92
-Release: 2%{?dist}
+Release: 3%{?dist}
 # Epoch because we pushed a qemu-1.0 package
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
@@ -19,9 +19,12 @@ Source2: kvm.modules
 # Creates /dev/kvm
 Source3: 80-kvm.rules
 
-# KSM control script
+# KSM control scripts
 Source4: ksm.init
 Source5: ksm.sysconfig
+Source6: ksmtuned.init
+Source7: ksmtuned
+Source8: ksmtuned.conf
 
 # Not upstream, why?
 Patch01: qemu-bios-bigger-roms.patch
@@ -100,6 +103,9 @@ This package provides the command line tool for manipulating disk images
 %package  common
 Summary: QEMU common files needed by all QEMU targets
 Group: Development/Tools
+Requires(post): /sbin/chkconfig
+Requires(preun): /sbin/service /sbin/chkconfig
+Requires(postun): /sbin/service
 %description common
 QEMU is a generic and open source processor emulator which achieves a good
 emulation speed by using dynamic translation.
@@ -300,9 +306,13 @@ make V=1 %{?_smp_mflags} $buildldflags
 %install
 rm -rf $RPM_BUILD_ROOT
 
-install -D -p -m 0755 %{SOURCE4} $RPM_BUILD_ROOT%{_sysconfdir}/rc.d/init.d/ksm
+install -D -p -m 0755 %{SOURCE4} $RPM_BUILD_ROOT%{_initddir}/ksm
 install -D -p -m 0644 %{SOURCE5} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/ksm
 
+install -D -p -m 0755 %{SOURCE6} $RPM_BUILD_ROOT%{_initddir}/rc.d/init.d/ksmtuned
+install -D -p -m 0755 %{SOURCE7} $RPM_BUILD_ROOT%{_sbindir}/ksmtuned
+install -D -p -m 0644 %{SOURCE8} $RPM_BUILD_ROOT%{_sysconfdir}/ksmtuned.conf
+
 %ifarch %{ix86} x86_64
 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/modules
 mkdir -p $RPM_BUILD_ROOT%{_bindir}/
@@ -324,7 +334,7 @@ make prefix="${RPM_BUILD_ROOT}%{_prefix}" \
      docdir="${RPM_BUILD_ROOT}%{_docdir}/%{name}-%{version}" \
      datadir="${RPM_BUILD_ROOT}%{_datadir}/%{name}" install
 chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man1/*
-install -D -p -m 0755 %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/rc.d/init.d/qemu
+install -D -p -m 0755 %{SOURCE1} $RPM_BUILD_ROOT%{_initddir}/qemu
 install -D -p -m 0644 -t ${RPM_BUILD_ROOT}%{qemudocdir} Changelog README TODO COPYING COPYING.LIB LICENSE
 
 install -D -p -m 0644 qemu.sasl $RPM_BUILD_ROOT%{_sysconfdir}/sasl2/qemu.conf
@@ -366,6 +376,30 @@ rm -rf $RPM_BUILD_ROOT
 sh %{_sysconfdir}/sysconfig/modules/kvm.modules
 %endif
 
+%post common
+getent group kvm >/dev/null || groupadd -g 36 -r kvm
+getent group qemu >/dev/null || groupadd -g 107 -r qemu
+getent passwd qemu >/dev/null || \
+  useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
+    -c "qemu user" qemu
+
+/sbin/chkconfig --add ksm
+/sbin/chkconfig --add ksmtuned
+
+%preun common
+if [ $1 -eq 0 ]; then
+    /sbin/service ksmtuned stop &>/dev/null || :
+    /sbin/chkconfig --del ksmtuned
+    /sbin/service ksm stop &>/dev/null || :
+    /sbin/chkconfig --del ksm
+fi
+
+%postun common
+if [ $1 -ge 1 ]; then
+    /sbin/service ksm condrestart &>/dev/null || :
+    /sbin/service ksmtuned condrestart &>/dev/null || :
+fi
+
 %post user
 /sbin/chkconfig --add qemu
 
@@ -380,13 +414,6 @@ if [ $1 -ge 1 ]; then
     /sbin/service qemu condrestart &>/dev/null || :
 fi
 
-%post common
-getent group kvm >/dev/null || groupadd -g 36 -r kvm
-getent group qemu >/dev/null || groupadd -g 107 -r qemu
-getent passwd qemu >/dev/null || \
-  useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
-    -c "qemu user" qemu
-
 %files 
 %defattr(-,root,root)
 
@@ -409,11 +436,14 @@ getent passwd qemu >/dev/null || \
 %{_mandir}/man8/qemu-nbd.8*
 %{_bindir}/qemu-nbd
 %config(noreplace) %{_sysconfdir}/sasl2/qemu.conf
-%{_sysconfdir}/rc.d/init.d/ksm
+%{_initddir}/ksm
 %config(noreplace) %{_sysconfdir}/sysconfig/ksm
+%{_initddir}/ksmtuned
+%{_sbindir}/ksmtuned
+%config(noreplace) %{_sysconfdir}/ksmtuned.conf
 %files user
 %defattr(-,root,root)
-%{_sysconfdir}/rc.d/init.d/qemu
+%{_initddir}/qemu
 %{_bindir}/qemu-alpha
 %{_bindir}/qemu-arm
 %{_bindir}/qemu-armeb
@@ -496,6 +526,10 @@ getent passwd qemu >/dev/null || \
 %{_mandir}/man1/qemu-img.1*
 
 %changelog
+* Wed Sep 16 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.92-3
+- Add ksmtuned, also from Dan Kenigsberg
+- Use %_initddir macro
+
 * Wed Sep 16 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.92-2
 - Add ksm control script from Dan Kenigsberg